|
|
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
"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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Le 17-11-08 à 15:56, Kenneth a écrit :
> 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!)
>
>
>
>
Want something even more compact?
Try this :
(!strcmp(IMG_TYPE,AA))|(!strcmp(IMG_TYPE,BB))|(!strcmp(IMG_TYPE,CC))
The "!" is the NOT operator. If the value is zero, it becomes a 1, if
it's <>0, it becomes a 0.
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Alain <kua### [at] videotronca> wrote:
>
> Want something even more compact?
Ah, yes indeed, that works as well-- and IS more compact. I'm familiar with
"not", but it would never have occured to me to use it in this context...until
now ;-)
Your example (and your other comments) have helped me to further understand the
nature of my original problem. Very much appreciated.
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
After re-reading the various comments, and experimenting with all sorts of
combinations of things, I have to admit that all of this stuff is still a bit
difficult to wrap my mind around-- mainly because there's a specific stumbling
block or two that's giving me a problem.
I've come up with some examples that probably go to the root cause of my
remaining misunderstanding.
My basic question is: When is the #switch() value considered an actual Boolean
true/false value, vs. a 'simple numerical' value?
Getting back to basics-- e.g., NOT using the strcmp() string-compare function to
complicate things-- consider the following:
#declare C = 27;
(A)
This works successfully...
#switch(1) // Boolean 'true'
#case(C = 27) // a Boolean comparison that's also 'true'
(B)
This ALSO works... two 'numerical values' that match
#switch(27)
#case(C)
(C)This does NOT work (it falls through to the #else clause)...
#switch(1000) // or 343 or -89 or any other non-zero value
#case(C = 27) // the Boolean comparison again
Regarding (A) and (B), it appears that #switch 'changes its operational mode'--
depending on the particular 'kind' of #case that it's presented with (Boolean
true/false vs. a simple number.) Currently, I'm not exactly sure when that might
happen, given the complexities of all of this inter-related stuff.
Regarding (C), I was under the impression from some earlier comments that
#switch could use ANY positive/negative value to mean 'true' or (1)-- but that
doesn't seem to be a correct interpretation. It seems that only #switch(1)
works.
If I could just get past *these* misunderstandings, my world would be a MUCH
happier place to be in ;-)
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
hi,
On 10/11/2017 21:15, Kenneth wrote:
> After re-reading the various comments, and experimenting with all sorts of
> combinations of things, I have to admit that all of this stuff is still a bit
> difficult to wrap my mind around-- mainly because there's a specific stumbling
> block or two that's giving me a problem.
> I've come up with some examples that probably go to the root cause of my
> remaining misunderstanding.
I'll try.
> My basic question is: When is the #switch() value considered an actual Boolean
> true/false value, vs. a 'simple numerical' value?
the documentation only refers to float values being compared/used.
> Getting back to basics-- e.g., NOT using the strcmp() string-compare function to
> complicate things-- consider the following:
> #declare C = 27;
> (A)
> This works successfully...
> #switch(1) // Boolean 'true'
> #case(C = 27) // a Boolean comparison that's also 'true'
yes, you say "switch when the value is one", and "truth" happens to be
represented as one, so, bingo.
> (B)
> This ALSO works... two 'numerical values' that match
> #switch(27)
> #case(C)
same thing, only now you say "switch when the value is 27".
> (C)This does NOT work (it falls through to the #else clause)...
> #switch(1000) // or 343 or -89 or any other non-zero value
> #case(C = 27) // the Boolean comparison again
how could it? 1000 is not the same as one.
> Regarding (A) and (B), it appears that #switch 'changes its operational mode'--
> depending on the particular 'kind' of #case that it's presented with (Boolean
> true/false vs. a simple number.) Currently, I'm not exactly sure when that might
> happen, given the complexities of all of this inter-related stuff.
again, the Boolean stuff just happens to apply in these "corner cases".
think coincidence.
> Regarding (C), I was under the impression from some earlier comments that
> #switch could use ANY positive/negative value to mean 'true' or (1)-- but that
> doesn't seem to be a correct interpretation. It seems that only #switch(1)
> works.
this isn't about truth, it as simple as "does value A match value B".
> If I could just get past *these* misunderstandings, my world would be a MUCH
> happier place to be in ;-)
I think that if you calculated the value you're interested in beforehand
and then used a variable (only), there'd be much less confusion, for
instance:
#local A = 1;
#switch (A)
#case (1)
#debug concat("one\n")
#break
#case (2)
#debug concat("two\n")
#break
#case (3)
#debug concat("three\n")
#break
#else
#debug concat("oops\n")
#end
now try it with other values for A, 2, etc. hth.
oh, and just to give you a "headache" :-) using the logical not
operator as suggested by Alain? try this (no further savings though):
(!(strcmp(IMG_TYP,AA)&strcmp(IMG_TYP,BB)&strcmp(IMG_TYP,CC)))
;-)
https://en.wikipedia.org/wiki/De_Morgan%27s_laws
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
|
|