POV-Ray : Newsgroups : povray.advanced-users : problem using ORs and strcmp() in #switch/#case Server Time
28 Mar 2024 21:43:42 EDT (-0400)
  problem using ORs and strcmp() in #switch/#case (Message 11 to 20 of 36)  
<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>
From: Kenneth
Subject: Re: problem using ORs and strcmp() in #switch/#case
Date: 7 Nov 2017 23:00:00
Message: <web.5a0281171346e9e089df8d30@news.povray.org>
"Bald Eagle" <cre### [at] netscapenet> wrote:
>
> I see where it's going wrong, and this will give you an idea of why:
>
>     #switch(true)
>
>     #case(1)
>      rgb <0, 0, 0.2>
>     #break
>
>     #case(
>        // no (strcmp(IMG_TYPE,AA), which is the only 'correct' match
>        (strcmp(IMG_TYPE,BB))
>        | (strcmp(IMG_TYPE,CC))
>      )
>
> #switch(true) is a very strange usage, and I'm sure clipka could give some
> source-code explanation of why it works the way it does.
> But basically, as I suspected, it just selects the FIRST #case() regardless of
> what it is.

But here's a very similar example (though without any ORs, which might make all
the difference), and it selects the 2nd #case (green)...

#switch(true)
#case(0)
     rgb <0, 0, 0.2> // BLUE
#break
#case(1)
    rgb <0,1,0> // GREEN
#break
....

This makes sense to me (well, at the moment, anyway!), as it looks like
#switch(true) is picking the #case with the appropriate 'true' result of (1)
>
> In fact, check out:
>
>     #switch(strcmp(IMG_TYPE,BB) | strcmp(IMG_TYPE,CC) )
>
>      #case(-10)
>      rgb <1, 1, 0>
>     #break
>
>      #case(-6)
>      rgb <1, 1, 1>
>     #break
>
>     #case(1)
>      rgb <0, 0, 0.2>
>     #break
>
>     #case(1000)
>
> It selects the blue pigment, which corresponds to 1.

*That's* a really unexpected result, IMO; neither of the #switch's strcmp()s
'match' IMG_TYPE (which would be AA), yet #case(1) is chosen as if #switch is
'true.' And looking at it in a different brain-twisting way (one that's
incorrect, no doubt), it seems that either #case(-6) or #case(-10) should be
chosen, but certainly not #case(1)

It all makes my brain hurt :-O


Post a reply to this message

From: Kenneth
Subject: Re: problem using ORs and strcmp() in #switch/#case
Date: 7 Nov 2017 23:45:00
Message: <web.5a028a351346e9e089df8d30@news.povray.org>
clipka <ano### [at] anonymousorg> wrote:


>
> Also, there's a much easier way to achieve a logical OR in any `#switch`
> construct: Just place multiple `#case` statements without a `#break` in
> between, like so:
>
>     #switch(0)
>       #case(strcmp(STRING,CONST1A))
>       #case(strcmp(STRING,CONST1B))
>         // go here if STRING = CONST1A or CONST1B
>       #break
>       #case(strcmp(STRING,CONST2A))
>       #case(strcmp(STRING,CONST2B))
>         // otherwise go here if STRING = CONST2A or CONST2B
>       #break
>
I didn't know that using #cases without #breaks was possible :-O  Thanks! That's
the construction I will probably use; it's nice and elegant. In fact, so
interesting that a note in the documentation about it would be justified ;-)

BTW, I almost never use #switch(true) in my scenes, usually just #switch(1) or
#switch(0)-- believing that they are the 'logical equivalents' of true/false,
not just the 'number values' 1 and 0. It has always worked for me, but is my
assumption valid, in light of all that's been said?

Another question, just to clarify something: Is there a difference between the
following two examples? (I don't actually code the latter way-- it may not even
be appropriate-- but I've seen various types of non-strcmp() constructions in
the newsgroups that look similar)...

#switch(0)
#case(strcmp(IMG_TYPE,AA))

and

#switch(0)
#case(strcmp(IMG_TYPE,AA)=0)

I ask because the latter doesn't work--no error message of any kind is created,
but it falls through to the #else clause, even though strcmp(IMG_TYPE,AA) is a
'match' between IMG_TYPE and AA.


Post a reply to this message

From: Bald Eagle
Subject: Re: problem using ORs and strcmp() in #switch/#case
Date: 8 Nov 2017 06:20:01
Message: <web.5a02e7b51346e9e05cafe28e0@news.povray.org>
"Kenneth" <kdw### [at] gmailcom> wrote:

> But here's a very similar example (though without any ORs, which might make all
> the difference), and it selects the 2nd #case (green)...
>
> #switch(true)
> #case(0)
>      rgb <0, 0, 0.2> // BLUE
> #break
> #case(1)
>     rgb <0,1,0> // GREEN
> #break
> ....
>
> This makes sense to me (well, at the moment, anyway!), as it looks like
> #switch(true) is picking the #case with the appropriate 'true' result of (1)

Right.  "true" "on" "yes" all evaluate to 1 in SDL.


> *That's* a really unexpected result, IMO; neither of the #switch's strcmp()s
> 'match' IMG_TYPE (which would be AA), yet #case(1) is chosen as if #switch is
> 'true.'

Yes, (now that I've gotten some sleep, and looked at the #debug output) I see
that's the case.   I probably won't have an opportunity to run any more tests
until tonight.


Post a reply to this message

From: Bald Eagle
Subject: Re: problem using ORs and strcmp() in #switch/#case
Date: 8 Nov 2017 06:30:00
Message: <web.5a02ea6a1346e9e05cafe28e0@news.povray.org>
"Kenneth" <kdw### [at] gmailcom> wrote:

> #switch(0)
> #case(strcmp(IMG_TYPE,AA))

This should work, as strcmp(IMG_TYPE,AA) _IS_ 0.


> #switch(0)
> #case(strcmp(IMG_TYPE,AA)=0)
>
> I ask because the latter doesn't work--no error message of any kind is created,
> but it falls through to the #else clause, even though strcmp(IMG_TYPE,AA) is a
> 'match' between IMG_TYPE and AA.

Which means that it evaluates to TRUE, or 1, which is NOT 0.

Stop thinking in terms of conditional Boolean word results, and think in 0 or 1.

#if (strcmp(IMG_TYPE,AA)=0)
would give a Boolean result of 1.


I think you're stuck thinking about #switch() and #case() as some sort of
semi-Boolean operator, when it's more of a "pick this value from the following
list" function.  Maybe if you think about the whole block like an array [n] and
the #case statements are picking a specific array item (sort of).

{pseudocode}
#if (Case = n)
      #local Return = Array [n]
#end

and

#if (Range > Low & Range < High)
      #local Return = Array [some appropriate n]
#end


Post a reply to this message

From: clipka
Subject: Re: problem using ORs and strcmp() in #switch/#case
Date: 8 Nov 2017 07:53:52
Message: <5a02fe60$1@news.povray.org>
Am 08.11.2017 um 05:40 schrieb Kenneth:

> I didn't know that using #cases without #breaks was possible :-O  Thanks! That's
> the construction I will probably use; it's nice and elegant. In fact, so
> interesting that a note in the documentation about it would be justified ;-)

It's hinted at very briefly in the v3.7 docs.

> BTW, I almost never use #switch(true) in my scenes, usually just #switch(1) or
> #switch(0)-- believing that they are the 'logical equivalents' of true/false,
> not just the 'number values' 1 and 0. It has always worked for me, but is my
> assumption valid, in light of all that's been said?

`#switch(0)` and `#switch(1)` are perfectly equivalent to
`#switch(false)` and `#switch(true)` respectively, but for code clarity
I would recommend the former when you're dealing with actual numbers
(such as the return value of `strcmp()`), and the latter when you're
dealing with logical expressions (such as the result of the `=` operator).


> Another question, just to clarify something: Is there a difference between the
> following two examples? (I don't actually code the latter way-- it may not even
> be appropriate-- but I've seen various types of non-strcmp() constructions in
> the newsgroups that look similar)...
> 
> #switch(0)
> #case(strcmp(IMG_TYPE,AA))
> 
> and
> 
> #switch(0)
> #case(strcmp(IMG_TYPE,AA)=0)

Yes, absolutely!
If IMG_TYPE is equal to AA, then `strcmp(IMG_TYPE,AA)` will yield 0.
Comparing that result with zero will yield true, i.e. some non-zero number.

So with IMG_TYPE=AA, the first case would resolve to:

    #switch(0)
    #case(0) // representing `zero difference`
      // (we'll enter here, because 0 = 0)

while the second case would resolve to:

    #switch(0)
    #case(1) // representing `true`
      // (we'll NOT enter here, because 0 <> 1)

> I ask because the latter doesn't work--no error message of any kind is created,
> but it falls through to the #else clause, even though strcmp(IMG_TYPE,AA) is a
> 'match' between IMG_TYPE and AA.

The latter case would generate an error or at least a warning in most
contemporary languages, as it is now considered good practice to clearly
distinguish between boolean an numeric values. Even in C, where use of
`int` for boolean values has a long-standing tradition, a dedicated
boolean type has been added by now.

However, POV-Ray's rusty SDL is particularly poor at distinguishing
between values representing entirely different things (another example
being colours vs. vectors), so it can't warn you that you might have a
problem there.


Post a reply to this message

From: clipka
Subject: Re: problem using ORs and strcmp() in #switch/#case
Date: 8 Nov 2017 07:58:22
Message: <5a02ff6e$1@news.povray.org>
Am 08.11.2017 um 12:28 schrieb Bald Eagle:

> I think you're stuck thinking about #switch() and #case() as some sort of
> semi-Boolean operator, when it's more of a "pick this value from the following
> list" function.  Maybe if you think about the whole block like an array [n] and
> the #case statements are picking a specific array item (sort of).

I would pick the analogy of a `#if...#elseif...#end` construct:

    #switch(VALUE)
      #case(COMPARE1)
        // branch 1
      #break
      #case(COMPARE2)
        // branch 2
      #break
      ...
      #default
        // branch Z
      #break
    #end

is fully equivalent (presuming all values are numeric) to:

    #if(VALUE=COMPARE1)
      // branch 1
    #elseif(VALUE=COMPARE2)
      // branch 2
    ...
    #else
      // branch Z
    #end


Post a reply to this message

From: clipka
Subject: Re: problem using ORs and strcmp() in #switch/#case
Date: 8 Nov 2017 08:16:08
Message: <5a030398$1@news.povray.org>
Am 08.11.2017 um 04:59 schrieb Kenneth:
> "Bald Eagle" <cre### [at] netscapenet> wrote:
>>
>> I see where it's going wrong, and this will give you an idea of why:
>>
>>     #switch(true)
>>
>>     #case(1)
>>      rgb <0, 0, 0.2>
>>     #break
>>
>>     #case(
>>        // no (strcmp(IMG_TYPE,AA), which is the only 'correct' match
>>        (strcmp(IMG_TYPE,BB))
>>        | (strcmp(IMG_TYPE,CC))
>>      )
>>
>> #switch(true) is a very strange usage, and I'm sure clipka could give some
>> source-code explanation of why it works the way it does.
>> But basically, as I suspected, it just selects the FIRST #case() regardless of
>> what it is.
> 
> But here's a very similar example (though without any ORs, which might make all
> the difference), and it selects the 2nd #case (green)...
> 
> #switch(true)
> #case(0)
>      rgb <0, 0, 0.2> // BLUE
> #break
> #case(1)
>     rgb <0,1,0> // GREEN
> #break
> .....
> 
> This makes sense to me (well, at the moment, anyway!), as it looks like
> #switch(true) is picking the #case with the appropriate 'true' result of (1)
>>
>> In fact, check out:
>>
>>     #switch(strcmp(IMG_TYPE,BB) | strcmp(IMG_TYPE,CC) )
>>
>>      #case(-10)
>>      rgb <1, 1, 0>
>>     #break
>>
>>      #case(-6)
>>      rgb <1, 1, 1>
>>     #break
>>
>>     #case(1)
>>      rgb <0, 0, 0.2>
>>     #break
>>
>>     #case(1000)
>>
>> It selects the blue pigment, which corresponds to 1.
> 
> *That's* a really unexpected result, IMO; neither of the #switch's strcmp()s
> 'match' IMG_TYPE (which would be AA), yet #case(1) is chosen as if #switch is
> 'true.' And looking at it in a different brain-twisting way (one that's
> incorrect, no doubt), it seems that either #case(-6) or #case(-10) should be
> chosen, but certainly not #case(1)
> 
> It all makes my brain hurt :-O

The `#switch` statement expression has no special treatment of logical
operators.

The logical-OR operator `A|B` returns `false` (0) if both A and B are
equivalent to `false` (0); otherwise, it returns or `true` (non-0, in
this case 1).

However, the `strcmp(A,B)` function does /not/ return a boolean value,
but a numerical one: Negative if A<B, positive if A>B, and zero if A=B.
It is therefore highly recommended to always and immediately compare the
`strcmp()` result with zero (unless you know exactly what you're doing),
which turns it into a reasonably easy-to-grasp logical expression.

For example, to examine whether A is "larger" than B, you would write
`strcmp(A,B)>0`.

Then again, with v3.7 you should really use `A>B`.


If you really want to use the `strcmp()` result directly as a boolean
value, you should ditch the idea of it as an equality test, and think of
it as a /non-equality/ test instead: The result will be non-zero (and
thus equivalent to `true`) if the two strings /differ/.


Post a reply to this message

From: Bald Eagle
Subject: Re: problem using ORs and strcmp() in #switch/#case
Date: 8 Nov 2017 10:10:00
Message: <web.5a031d721346e9e0c437ac910@news.povray.org>
"Kenneth" <kdw### [at] gmailcom> wrote:
> "Bald Eagle" <cre### [at] netscapenet> wrote:

> > In fact, check out:
> >
> >     #switch(strcmp(IMG_TYPE,BB) | strcmp(IMG_TYPE,CC) )
> >
> >      #case(-10)
> >      rgb <1, 1, 0>
> >     #break
> >
> >      #case(-6)
> >      rgb <1, 1, 1>
> >     #break
> >
> >     #case(1)
> >      rgb <0, 0, 0.2>
> >     #break
> >
> >     #case(1000)
> >
> > It selects the blue pigment, which corresponds to 1.
>
> *That's* a really unexpected result, IMO; neither of the #switch's strcmp()s
> 'match' IMG_TYPE (which would be AA), yet #case(1) is chosen as if #switch is
> 'true.' And looking at it in a different brain-twisting way (one that's
> incorrect, no doubt), it seems that either #case(-6) or #case(-10) should be
> chosen, but certainly not #case(1)

It seems to me that none of the individual cases should be chosen, as neither of
the Boolean expressions evaluate to 1, which means the logical OR should return
zero - so -10, -6, 1, and 1000 should ALL be skipped, and any extant #else
should selected instead.

No POV-Ray on _this_ computer, so I can't test anything for the next 8 hours.
(which is why I'd love a simple editor/parser-no-render combo, or a true
stand-alone POV-Ray ("USB") version)


Post a reply to this message

From: Kenneth
Subject: Re: problem using ORs and strcmp() in #switch/#case
Date: 8 Nov 2017 12:25:02
Message: <web.5a033a451346e9e089df8d30@news.povray.org>
Kenneth wrote...
> #switch(0)
> #case(strcmp(IMG_TYPE,AA)=0)
>
> I ask because the latter doesn't work--no error message of any kind is created,
> but it falls through to the #else clause, even though strcmp(IMG_TYPE,AA) is a
> 'match' between IMG_TYPE and AA.

Bald Eagle wrote...
> Which means that it evaluates to TRUE, or 1, which is NOT 0.

> Stop thinking in terms of conditional Boolean word results, and think in 0 or 1.

> #if (strcmp(IMG_TYPE,AA)=0)
> would give a Boolean result of 1.

And Clipka wrote...
> If IMG_TYPE is equal to AA, then `strcmp(IMG_TYPE,AA)` will yield 0.
> Comparing that result with zero will yield true, i.e. some non-zero number.

Ah! OK, this finally makes sense to me! Thanks to you both. (All of this stuff
reminds me of my college days, when I struggled mightily to grasp the
complexities of Boolean operations. Ugh. It made my brain hurt then too.)

Kenneth wrote...
> I didn't know that using #cases without #breaks was possible :-O  Thanks!
> ...a note in the documentation about it would be justified ;-)

Clipka...
> It's hinted at very briefly in the v3.7 docs.

Oops, you're right (as I see after re-reading the docs for the 137-th
time...ha...)

"If a clause evaluates true but no #break is specified, the parsing will fall
through to the next #case or #range and that clause conditional is evaluated."

So apparently it also works if a clause evaluates 'false' (the pseudo-OR
behavior.)


Post a reply to this message

From: Kenneth
Subject: Re: problem using ORs and strcmp() in #switch/#case
Date: 8 Nov 2017 12:45:01
Message: <web.5a0341fd1346e9e089df8d30@news.povray.org>
"Bald Eagle" <cre### [at] netscapenet> wrote:

>
> No POV-Ray on _this_ computer, so I can't test anything for the next 8 hours.
> (which is why I'd love a simple editor/parser-no-render combo, or a true
> stand-alone POV-Ray ("USB") version)

I seem to remember that someone in the newsgroups mentioned running POV-Ray from
a USB stick.(?) In modern computers, isn't it treated like 'just another hard
drive'? (Sorry, I've never tried running apps that way, so I don't know.)


Post a reply to this message

<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.