POV-Ray : Newsgroups : povray.advanced-users : problem using ORs and strcmp() in #switch/#case Server Time
2 May 2024 07:46:33 EDT (-0400)
  problem using ORs and strcmp() in #switch/#case (Message 17 to 26 of 36)  
<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>
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

From: Alain
Subject: Re: problem using ORs and strcmp() in #switch/#case
Date: 8 Nov 2017 15:03:27
Message: <5a03630f@news.povray.org>
Le 17-11-07 à 14:32, Kenneth a écrit :
> I'm having  a subtle problem that I can't pin down, when trying to use
> logical-OR statements inside of #case directives. I'm using the strcmp()
> function to compare various strings, plus OR blocks separating those strcmp()
> comparisons inside of each #case. Posting my problematic scene code isn't
> practical here (it involves lots of image_maps), but I came up with a simplified
> test. I'm hoping to glean some insights into these interactions, from more
> astute newsgroup observers ;-)
> 
> There are four things involved: strings, #switch/#case, the strcmp() function,
> and OR.
> 
> Here's the test code, before I go into the details. Note that IMG_TYPE and AA
> exactly match. The problem is that #switch is falling through to the #else
> clause, when it should not do so (because  IMG_TYPE and AA *are* the same.)  If
> the #case clause is successful, you'll see a GREEN box; otherwise, a
> crosshatched box.  Comment-out the two OR lines for a successful test.
> --------------------
> #version 3.71; // or 3.7
> 
> global_settings{assumed_gamma 1.0 max_trace_level 5}
> default{finish{ambient 0 emission 1 diffuse 0}}
> 
> camera {
>    perspective
>    location  <.5, .5, -1.5>
>    look_at   <.5, .5, 0>
> }
> 
> #declare IMG_TYPE = "jpg"
> #local AA = "jpg"
> #local BB = "png"
> #local CC = "tiff"
> 
> box{0,<1,1,0>
> no_shadow
> pigment{
>      #switch(1000)
>      #case(
>      // INDIVIDUALLY, these all work the way they are supposed to-- but not
>      // all three at once. The OR's are causing some kind of problem, and
>      // the result always fall through to the #else clause.
>          (strcmp(IMG_TYPE,AA) + 1000)
>          | (strcmp(IMG_TYPE,BB) + 1000)
>          | (strcmp(IMG_TYPE,CC) + 1000)
>           )
>      srgb <0,1,0> // GREEN square
>      #debug "\nAt least ONE of the #case clauses is valid.\n\n\n\n"
>      #break
>      #else
>      // A cross-hatch warning image...
>      average
>      pigment_map{
>           [1 gradient x+y
>                frequency 6
>                color_map{
>                    [.25 srgb <1,0,0>]
>                    [.25 srgb 0]
>                          }
>           ]
>           [1 gradient x-y
>                frequency 6
>                color_map{
>                    [.25 srgb <1,0,0>]
>                    [.25 srgb 0]
>                         }
>           ]
>                  }
>       #debug "\nNO #case clause is valid.\n\n"
>       #end // of #switch
>          } // end of pigment
>      }
>   -----------------------
> 
> I assume that a #case clause can USE logical operators like ORs??
> 
> What DOES work is to *remove* all of the OR blocks--using just ONE
> strcmp() + 1000   in the #case (any one of the three). That results in correct
> #switch behavior (either a 'go' of 'no go'.) That's not what I want, of course,
> as I need all three in the #case statement. But is it possible that OR is not
> the correct logical operator to use? One *guess* I have is that  #case is
> 'reading' the   strcmp()-plus-OR blocks    left to right-- and finally comes to
> strcmp(IMG_TYPE,CC) + 1000,  the result of which does NOT 'match'
> #switch(1000)  ... possibly causing the fall-through to the #else clause(?)
> 
> My understanding of #switch is that ANY value can be used; it doesn't
> specifically need just TRUE/FALSE of 1/0, just so long as a particular #case
> result matches it.  But I don't really know its hidden operation. BTW,  I didn't
> use 'TRUE' in the #switch() because, when strcmp() finds two strings that
> *match*, its numerical output is zero-- which should  be a logical 'false' in a
> TRUE/FALSE clause, not 'true.' (AFAIU!)
> 
> Perhaps I shouldn't be using strcmp() at all. It *is* a rather complex beast--
> its numerical output depends on where the various strings fall into the 'ASCII
> collating sequence.' (I had to re-read the docs to try and understand this,
> along with running some experiments.) My use of  +1000  in the #switch clause
> (and in the #case arguments) was to try and avoid such problems, as 1000 is way
> outside of the ASCII numbering sequence. But no matter *what* numerical value I
> use-- while also using the ORs-- the #else clause is always invoked.
> 
> And in my real scene, I'm finding that the OR clauses *sometimes* need the added
> parentheses around  the various    strcmp() + 1000   statements -- but that
> seems to work inconsistently as well  :-/
> 
> 
> 
> 

The OR operator is a binary operator. It can only return a result of 
zero or one. Any input <> zero result in a true/on/1 result, and zero 
returns flase/off/0.
You check for a value of 1000 that can NEVER appen.

You can use your OR statement inside parantesis, THEN add 1000 or 
multiply by 1000.
You can have 3 #case() statements without ending #greak. That way, the 
first will fall through the next two, and the second falls through the last.
You can use "on" in your #switch statement.
You can replace your #switch by an #if statement.


Post a reply to this message

From: Alain
Subject: Re: problem using ORs and strcmp() in #switch/#case
Date: 8 Nov 2017 15:05:50
Message: <5a03639e$1@news.povray.org>
Le 17-11-07 à 16:36, Kenneth a écrit :
> "Bald Eagle" <cre### [at] netscapenet> wrote:
>> "Kenneth" <kdw### [at] gmailcom> wrote:
>>
>>> The problem seems to be with my use of ORs in the #case; they seem to be
>>> screwing up the results somehow. The *successful* (strcmp(IMG_TYPE,AA) + 1000))
>>> comparison value is being ignored or overridden, or something!
>>
>> Right - I think that you can't use case() like that.
>>
>> I think the Boolean comparison might yield a 0 or a 1, thus nothing
>> ever returns 1000.
> 
> Well, both of these seem to work correctly (when not using the troublesome ORs,
> that is)...
> #switch(0)
> #case(strcmp(IMG_TYPE,AA))
> 
> #switch(1000)
> #case((strcmp(IMG_TYPE,AA) + 1000)
> 
> -- which in itself is actually kind of surprising, as I assumed #switch(0) would
> be the equivalent of a 'false' statement Boolean-wise or in a TRUE/FALSE
> comparison. That's why I didn't use #switch(TRUE)-- also because, with *that*,
> the overal results--when USING the ORs--were screwy in a different way!
>>
>> Maybe you ought to do a regular
>> #if (comparison1 | comparison2 | comparison3)
>> #declare Trigger = 1000;
>> #end
>>
> 
> ..... or just separate the various comparisons into individual #cases. I was
> trying to avoid such stuff, simply because it didn't look... compact and elegant
>   ;-)
> 
> 
> 
> 
Your problem come from the OR that change your 1000's into 1's.


Post a reply to this message

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

> 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.)

Quite possibly.  The problem, however, is that 90% of the time I can't even
install the printer drivers I need for work, or run the windows OS
troubleshooter for a device - because there seemed to be a need to password lock
everything.

So installing something to the registry seems to be the actual hurdle.
Unless there's a way where I don't need to modify the registry...


Post a reply to this message

From: Alain
Subject: Re: problem using ORs and strcmp() in #switch/#case
Date: 8 Nov 2017 15:11:07
Message: <5a0364db@news.povray.org>
Le 17-11-07 à 22:59, Kenneth a écrit :
> "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
> 
> 
> 
> 
No, it's the expected result.

(strcmp(IMG_TYPE,BB) | strcmp(IMG_TYPE,CC) ) can ONLY return a zero or a 
one.

So, the cases of -10, -6, and 1000 can *never ever* appen.


Post a reply to this message

From: clipka
Subject: Re: problem using ORs and strcmp() in #switch/#case
Date: 8 Nov 2017 15:34:39
Message: <5a036a5f$1@news.povray.org>
Am 08.11.2017 um 21:04 schrieb Alain:

> The OR operator is a binary operator. It can only return a result of
> zero or one. Any input <> zero result in a true/on/1 result, and zero
> returns flase/off/0.
> You check for a value of 1000 that can NEVER appen.

Call it a "logical operator" or "boolean operator". The term "binary
operator" usually has a different meaning when talking about computer
languages, namely an operator that has two parameters (and typically
sits in between them), as opposed to a unary operator that has just one
operator (and typically sits left or right of it).

While the logical OR (`|`) is indeed a binary operator in the above
sense, so are most arithmetic operators (`+`, `-`, `*`, etc.)


Post a reply to this message

From: Kenneth
Subject: Re: problem using ORs and strcmp() in #switch/#case
Date: 8 Nov 2017 16:00:00
Message: <web.5a03677d1346e9e089df8d30@news.povray.org>
SO...
With all of this new-found knowledge, I actually came up with some code that
works consistently-- and that still uses my original OR statements(!)

#switch(1)
    #case(
     (strcmp(IMG_TYPE,AA)=0) // if strcmp(...) returns zero, then 0=0 is 'true',
// which matches #switch. Otherwise, 'false'.
     | (strcmp(IMG_TYPE,BB)=0) // ditto
     | (strcmp(IMG_TYPE,CC)=0) // ditto

This construct also works in my real scene code, I'm happy to say. (And with the
ORs in any order.) I prefer the ORs because the real scene has numerous #case
clauses, each with four or five strcmp()s.  It all simply looks more compact
this way, to my eyes.

It's all starting to make sense to me now (although I still need to digest some
of the comments.) I also see that there are, as usual, various ways to get
similar results.

THANKS for taking the time with the insights, examples, and discussion! (And if
I'm still not 'getting it', don't hesitate to say so!)


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.