| View previous topic :: View next topic |
| Author |
Message |
Sean
Joined: 12 Feb 2007 Posts: 1282
|
Posted: Tue Sep 04, 2007 10:48 am Post subject: "" . 0 evaluates to True? |
|
|
I have no idea why the following outputs 1.
| Code: | | MsgBox, % "" . 0 ? 1 : 0 |
OTOH, the following outputs correctly 0.
| Code: | | MsgBox, % "" . 0 <> 0 ? 1 : 0 |
Maybe, it's related with:
| Code: | MsgBox, % 0 . 0 ? 1 : 0 ; outputs 0
MsgBox, % "0" . 0 ? 1 : 0 ; outputs 1 |
|
|
| Back to top |
|
 |
engunneer
Joined: 30 Aug 2005 Posts: 6560 Location: Pacific Northwest, US
|
Posted: Tue Sep 04, 2007 4:56 pm Post subject: |
|
|
confirmed
| ?: wrote: |
This operator is a shorthand replacement for the if-else statement.
|
| Code: |
test := "" . 0 ? 1 : 0
;test2 := "" . 0 ? 1 : 0
if ("" . 0)
test2 := 1
else
test2 := 0
listvars
pause
|
_________________
Unless otherwise noted, all code is untested.
Common Answers: 1.(Loops, Viruses, etc.) 2. Search 3.RTFM |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2494 Location: Australia, Qld
|
Posted: Wed Sep 05, 2007 1:40 am Post subject: Re: "" . 0 evaluates to True? |
|
|
| Sean wrote: | I have no idea why the following outputs 1.
| Code: | | MsgBox, % "" . 0 ? 1 : 0 |
| I do. The result of "" . 0 is interpreted as a string, not a pure number. AHK assumes any string other than "" is true. | Code: | switch (right_is_number)
{
case PURE_INTEGER: // Probably the most common, e.g. both sides of "if (x>3 and x<6)" are the number 1/0.
// Force it to be purely 1 or 0 if it isn't already.
left_branch_is_true = (this_token.symbol == SYM_INTEGER ? this_token.value_int64
: ATOI64(right_contents)) != 0;
break;
case PURE_FLOAT: // Convert to float, not int, so that a number between 0.0001 and 0.9999 is is considered "true".
left_branch_is_true = (this_token.symbol == SYM_FLOAT ? this_token.value_double
: atof(right_contents)) != 0.0;
break;
default: // string.
// Since "if x" evaluates to false when x is blank, it seems best to also have blank
// strings resolve to false when used in more complex ways. In other words "if x or y"
// should be false if both x and y are blank. Logical-not also follows this convention.
left_branch_is_true = (*right_contents != '\0');
} | (script_expression.cpp, starts at line 2428 in v1.0.47.04)
At this point, right_contents is "0", and right_is_number is PURE_NOT_NUMERIC.
If you assign "" . 0 to a variable and pass the variable to ?:, it is correctly interpreted as PURE_INTEGER. |
|
| Back to top |
|
 |
Sean
Joined: 12 Feb 2007 Posts: 1282
|
Posted: Wed Sep 05, 2007 2:19 am Post subject: Re: "" . 0 evaluates to True? |
|
|
| lexikos wrote: | | Sean wrote: | I have no idea why the following outputs 1.
| Code: | | MsgBox, % "" . 0 ? 1 : 0 |
| I do. The result of "" . 0 is interpreted as a string, not a pure number. AHK assumes any string other than "" is true. |
As a matter of fact, I suspected that. See my last example:
| Code: | MsgBox, % 0 . 0 ? 1 : 0 ; outputs 0
MsgBox, % "0" . 0 ? 1 : 0 ; outputs 1 |
But, I'm not sure if it's a consistent behavior as both are output as 00.
And try also the example of engunneer. |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2494 Location: Australia, Qld
|
Posted: Wed Sep 05, 2007 4:53 am Post subject: Re: "" . 0 evaluates to True? |
|
|
I guess 0 . 0 is interpreted as PURE_INTEGER, even though it results in "00".
| Sean wrote: | | And try also the example of engunneer. |
Yes, I noticed if(..) works correctly. I believe the code I posted only applies to short-circuit-capable operators (ternary and AND/OR.) Try this: | Code: | if ("" . 0 and true)
msgbox true?! |
Also, it seems literal strings are differentiated from numbers in expressions intentionally: | Quote: | | // Marked explicitly as string vs. SYM_OPERAND to prevent it from being seen as a number, e.g. if (var == "12.0") would be false if var contains "12" with no trailing ".0". | Try this: | Code: | a := "0"
MsgBox % a . 0 ? "true" : "false" | I get "false," meaning the "" is what is causing the expression to be interpreted as a string rather than a number. I can understand why some might see this behaviour as necessary for the equality operator, and perhaps other operators for (some) consistency. |
|
| Back to top |
|
 |
corrupt
Joined: 29 Dec 2004 Posts: 2391
|
Posted: Wed Sep 05, 2007 5:21 am Post subject: |
|
|
Interesting... | Code: | a = 0
b := ""
If (b . a and true)
MsgBox hmm
if ("" . 0 and true)
msgbox true?! |
|
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10467
|
Posted: Fri Sep 14, 2007 5:12 pm Post subject: |
|
|
When a subexpression is required to become a boolean value, only a numeric zero or an empty string can be relied upon to evaluate to "false". Everything else evalutes to "true" with the one exception below.
Intermediate expression results are classified as strings vs. numbers when the author's intent is clear. The main example of this is a quoted literal string, which is clearly intended to be "true". By contrast, when the result is final vs. intermediate (such as an IF statement), this classification is lost, which causes an expression like ("" . 0) to be seen as false instead of true. The loss of classification is a side-effect of fact that the current implementation treats expressions as a separate world from commands (all if-statements are currently treated as commands).
Although changing it now would probably do more harm than good by breaking existing scripts, it will be revisited for AutoHotkey version 2.
Thanks for the analysis and examples. |
|
| Back to top |
|
 |
|