digitalmars.D.learn - Why do some T.init evaluate to true while others to false?
- ArturG (8/8) May 26 2016 for example:
- Basile B. (16/24) May 26 2016 It's a shortcut that works for certain type and that means:
- Basile B. (4/8) May 26 2016 I obviously meant:
- Basile B. (4/12) May 26 2016 I obviously meant:
- arturg (5/21) May 26 2016 yes i know about most of those shortcuts its just float.init and
- Basile B. (5/30) May 26 2016 float.init is not equal to 0.0f. In D FP points values are
- ArturG (3/7) May 26 2016 yes i guess i tested all/most types and know that float.init is
- Basile B. (9/18) May 26 2016 because nan is not 0 and that the shortcut for float is
- ArturG (2/10) May 26 2016 Ok sorry for the noise and thanks anyway.
- Basile B. (5/14) May 26 2016 Oh, I'm so sorry ! I totally missed the point of the Q.
- Basile B. (10/26) May 26 2016 void main(string[] args)
- ArturG (6/21) May 26 2016 im just playing with this template[1] is there anything else i
- Marc =?UTF-8?B?U2Now7x0eg==?= (5/10) May 27 2016 If you just want to check whether something is equal to its
- ArturG (3/14) May 27 2016 that still requiers a special case for floating points, arrays
- Adam D. Ruppe (2/5) May 27 2016 Have you tried? That should work in all cases.
- ArturG (5/11) May 27 2016 float f;
- Adam D. Ruppe (5/9) May 27 2016 You changed it to a value that isn't float.init, so of course it
- ArturG (5/14) May 27 2016 yes but i have to check for that when some one does
- Adam D. Ruppe (3/4) May 27 2016 Why? This is no different than if they set any of the other four
- ArturG (12/16) May 27 2016 What do you mean?
- Steven Schveighoffer (10/26) May 27 2016 conversion to bool is not universally (val !is val.init)
- ArturG (4/13) May 27 2016 but by default it works you just changed the default so its ok
- Steven Schveighoffer (5/20) May 27 2016 I didn't change the default. The default is to pick the first member and...
- ArturG (20/24) May 27 2016 by default i ment this
- Alex Parrill (8/18) May 30 2016 NaN in IEEE 754 floating-point numbers (the floating-point number
- ArturG (22/28) May 30 2016 does this count?
- Marc =?UTF-8?B?U2Now7x0eg==?= (5/18) May 31 2016 This one is a bug in DMD. It works correctly with LDC.
- ag0aep6g (2/10) May 26 2016 What does it matter?
for example: if(any floatingpoint.init) will be true if(any char.init) also true if("") also true while others are false e.g. string s; if(s) will be false all others are also false or did i miss any?
May 26 2016
On Thursday, 26 May 2016 at 14:03:16 UTC, ArturG wrote:for example: if(any floatingpoint.init) will be true if(any char.init) also true if("") also true while others are false e.g. string s; if(s) will be false all others are also false or did i miss any?It's a shortcut that works for certain type and that means: - pointers: if (ptr) <=> if (ptr != null) - pointers: if (!ptr) <=> if (ptr == null) - integral(*): if (i) <=> if (i > 0) - integral: if (!i) <=> if (i == 0) - classes: if (c) <=> if (c !is null) - classes: if (!c) <=> if (c is null) (*) integral: generally speaking so: byte, ubyte, short, ushort, int, uint, long, ulong, char, wchar, dchar and also, very special case, structs with an alias this to one of this integral type. for array this works and this tests the (.ptr) member but most of the people here (incl. me) would recommand rather to always do: "if (arr.length)" because in some cases "if (arr)" will yield "true" even if the length is equal to 0.
May 26 2016
On Thursday, 26 May 2016 at 15:11:50 UTC, Basile B. wrote:On Thursday, 26 May 2016 at 14:03:16 UTC, ArturG wrote:[...][...] - integral(*): if (i) <=> if (i > 0)I obviously meant: - integral(*): if (i) <=> if (i <> 0) and "<=>" stands for "equivalence"
May 26 2016
On Thursday, 26 May 2016 at 15:14:21 UTC, Basile B. wrote:On Thursday, 26 May 2016 at 15:11:50 UTC, Basile B. wrote:I obviously meant: integral(*): if (i) <=> if (i != 0), "<>" is the Pascal operator for C's "!=" ....On Thursday, 26 May 2016 at 14:03:16 UTC, ArturG wrote:[...][...] - integral(*): if (i) <=> if (i > 0)I obviously meant: - integral(*): if (i) <=> if (i <> 0) and "<=>" stands for "equivalence"
May 26 2016
On Thursday, 26 May 2016 at 15:15:57 UTC, Basile B. wrote:On Thursday, 26 May 2016 at 15:14:21 UTC, Basile B. wrote:yes i know about most of those shortcuts its just float.init and char.init that work different then the other when you do this if(someType) // will be true for float and char while someType is T.initOn Thursday, 26 May 2016 at 15:11:50 UTC, Basile B. wrote:I obviously meant: integral(*): if (i) <=> if (i != 0), "<>" is the Pascal operator for C's "!=" ....On Thursday, 26 May 2016 at 14:03:16 UTC, ArturG wrote:[...][...] - integral(*): if (i) <=> if (i > 0)I obviously meant: - integral(*): if (i) <=> if (i <> 0) and "<=>" stands for "equivalence"
May 26 2016
On Thursday, 26 May 2016 at 15:25:03 UTC, arturg wrote:On Thursday, 26 May 2016 at 15:15:57 UTC, Basile B. wrote:float.init is not equal to 0.0f. In D FP points values are initialized to nan (not a number). By the way for strings it works, it's like the array case I described in the first answer).On Thursday, 26 May 2016 at 15:14:21 UTC, Basile B. wrote:yes i know about most of those shortcuts its just float.init and char.init that work different then the other when you do this if(someType) // will be true for float and char while someType is T.initOn Thursday, 26 May 2016 at 15:11:50 UTC, Basile B. wrote:I obviously meant: integral(*): if (i) <=> if (i != 0), "<>" is the Pascal operator for C's "!=" ....On Thursday, 26 May 2016 at 14:03:16 UTC, ArturG wrote:[...][...] - integral(*): if (i) <=> if (i > 0)I obviously meant: - integral(*): if (i) <=> if (i <> 0) and "<=>" stands for "equivalence"
May 26 2016
On Thursday, 26 May 2016 at 15:29:52 UTC, Basile B. wrote:float.init is not equal to 0.0f. In D FP points values are initialized to nan (not a number). By the way for strings it works, it's like the array case I described in the first answer).yes i guess i tested all/most types and know that float.init is float.nan but why is nan true and not false?
May 26 2016
On Thursday, 26 May 2016 at 15:34:50 UTC, ArturG wrote:On Thursday, 26 May 2016 at 15:29:52 UTC, Basile B. wrote:because nan is not 0 and that the shortcut for float is if (fpValue) <=> if (fpValue != 0) if (!fpValue)<=> if (fpValue == 0) There's no relation between the initializer and the shortcut. It's not because for some values the shortcut matches to the initializer that it must always be the case...But I admit I don't know the exact rationale. Does anyone know ?float.init is not equal to 0.0f. In D FP points values are initialized to nan (not a number). By the way for strings it works, it's like the array case I described in the first answer).yes i guess i tested all/most types and know that float.init is float.nan but why is nan true and not false?
May 26 2016
On Thursday, 26 May 2016 at 15:38:55 UTC, Basile B. wrote:because nan is not 0 and that the shortcut for float is if (fpValue) <=> if (fpValue != 0) if (!fpValue)<=> if (fpValue == 0) There's no relation between the initializer and the shortcut. It's not because for some values the shortcut matches to the initializer that it must always be the case...But I admit I don't know the exact rationale. Does anyone know ?Ok sorry for the noise and thanks anyway.
May 26 2016
On Thursday, 26 May 2016 at 15:34:50 UTC, ArturG wrote:On Thursday, 26 May 2016 at 15:29:52 UTC, Basile B. wrote:Oh, I'm so sorry ! I totally missed the point of the Q. float.nan is not a "unique" value. Several values verify "nan" (Look at std.math.isNan). So I suppose it's simpler to test for nullity. Though with the sign there's also two possible 0...float.init is not equal to 0.0f. In D FP points values are initialized to nan (not a number). By the way for strings it works, it's like the array case I described in the first answer).yes i guess i tested all/most types and know that float.init is float.nan but why is nan true and not false?
May 26 2016
On Thursday, 26 May 2016 at 15:48:18 UTC, Basile B. wrote:On Thursday, 26 May 2016 at 15:34:50 UTC, ArturG wrote:void main(string[] args) { writeln(float.nan == float.init); // false import std.math: isNaN; writeln(isNaN(float.nan)); // true writeln(isNaN(float.init)); //true } So the shortcut in the compiler might be more simple, there is only a single test for "if(myFloat)"...On Thursday, 26 May 2016 at 15:29:52 UTC, Basile B. wrote:Oh, I'm so sorry ! I totally missed the point of the Q. float.nan is not a "unique" value. Several values verify "nan" (Look at std.math.isNan). So I suppose it's simpler to test for nullity. Though with the sign there's also two possible 0...float.init is not equal to 0.0f. In D FP points values are initialized to nan (not a number). By the way for strings it works, it's like the array case I described in the first answer).yes i guess i tested all/most types and know that float.init is float.nan but why is nan true and not false?
May 26 2016
On Thursday, 26 May 2016 at 15:51:39 UTC, Basile B. wrote:im just playing with this template[1] is there anything else i missed? (if you dont mind) it basically treats any T.init as false and skips the function/delegate and just returns type. [1] https://dpaste.dzfl.pl/d159d83e3167Oh, I'm so sorry ! I totally missed the point of the Q. float.nan is not a "unique" value. Several values verify "nan" (Look at std.math.isNan). So I suppose it's simpler to test for nullity. Though with the sign there's also two possible 0...void main(string[] args) { writeln(float.nan == float.init); // false import std.math: isNaN; writeln(isNaN(float.nan)); // true writeln(isNaN(float.init)); //true } So the shortcut in the compiler might be more simple, there is only a single test for "if(myFloat)"...
May 26 2016
On Thursday, 26 May 2016 at 16:45:22 UTC, ArturG wrote:im just playing with this template[1] is there anything else i missed? (if you dont mind) it basically treats any T.init as false and skips the function/delegate and just returns type. [1] https://dpaste.dzfl.pl/d159d83e3167If you just want to check whether something is equal to its type's .init value, use the `is` operator, which does a bitwise comparison: if(value is typeof(value).init) ...
May 27 2016
On Friday, 27 May 2016 at 09:25:55 UTC, Marc Schütz wrote:On Thursday, 26 May 2016 at 16:45:22 UTC, ArturG wrote:that still requiers a special case for floating points, arrays and optionally empty string literals.im just playing with this template[1] is there anything else i missed? (if you dont mind) it basically treats any T.init as false and skips the function/delegate and just returns type. [1] https://dpaste.dzfl.pl/d159d83e3167If you just want to check whether something is equal to its type's .init value, use the `is` operator, which does a bitwise comparison: if(value is typeof(value).init) ...
May 27 2016
On Friday, 27 May 2016 at 14:43:47 UTC, ArturG wrote:Have you tried? That should work in all cases.if(value is typeof(value).init) ...that still requiers a special case for floating points, arrays and optionally empty string literals.
May 27 2016
On Friday, 27 May 2016 at 14:48:59 UTC, Adam D. Ruppe wrote:On Friday, 27 May 2016 at 14:43:47 UTC, ArturG wrote:float f; if(f is float.init) "float init".writeln; f = float.nan; if(f is float.init) "float nan".writeln;Have you tried? That should work in all cases.if(value is typeof(value).init) ...that still requiers a special case for floating points, arrays and optionally empty string literals.
May 27 2016
On Friday, 27 May 2016 at 14:56:28 UTC, ArturG wrote:float f; if(f is float.init) "float init".writeln; f = float.nan; if(f is float.init) "float nan".writeln;You changed it to a value that isn't float.init, so of course it isn't going to match! float.nan and float.init are NOT the same thing. float.init is a kind of NAN, but not the same kind.
May 27 2016
On Friday, 27 May 2016 at 15:07:50 UTC, Adam D. Ruppe wrote:On Friday, 27 May 2016 at 14:56:28 UTC, ArturG wrote:yes but i have to check for that when some one does float.nan.checkThen!((f){ this fun should not run }); which should be the same as float.init.checkThen!((f){ this fun should not run });float f; if(f is float.init) "float init".writeln; f = float.nan; if(f is float.init) "float nan".writeln;You changed it to a value that isn't float.init, so of course it isn't going to match! float.nan and float.init are NOT the same thing. float.init is a kind of NAN, but not the same kind.
May 27 2016
On Friday, 27 May 2016 at 15:19:50 UTC, ArturG wrote:yes but i have to check for that when some one doesWhy? This is no different than if they set any of the other four billion possible values.
May 27 2016
On Friday, 27 May 2016 at 15:24:18 UTC, Adam D. Ruppe wrote:On Friday, 27 May 2016 at 15:19:50 UTC, ArturG wrote:What do you mean? operation on float.nan gives you a float.nan so why does the shortcut evaluate to true and not false wouldnt that make more sense? float f; if(f) "why does this print".writeln; // it should not same for char char c; if(c) "why does this print".writeln; // it should not it works for most other types is there any reason why it doesnt work or couldnt work with floating points and character types?yes but i have to check for that when some one doesWhy? This is no different than if they set any of the other four billion possible values.
May 27 2016
On 5/27/16 11:49 AM, ArturG wrote:On Friday, 27 May 2016 at 15:24:18 UTC, Adam D. Ruppe wrote:conversion to bool is not universally (val !is val.init) Why are you expecting it to be? Won't work for enums with first elements that are non-zero either: enum foo : int { bar = 1; } foo f; if(f) writeln("this will output too"); -SteveOn Friday, 27 May 2016 at 15:19:50 UTC, ArturG wrote:What do you mean? operation on float.nan gives you a float.nan so why does the shortcut evaluate to true and not false wouldnt that make more sense? float f; if(f) "why does this print".writeln; // it should not same for char char c; if(c) "why does this print".writeln; // it should not it works for most other types is there any reason why it doesnt work or couldnt work with floating points and character types?yes but i have to check for that when some one doesWhy? This is no different than if they set any of the other four billion possible values.
May 27 2016
On Friday, 27 May 2016 at 16:56:21 UTC, Steven Schveighoffer wrote:Why are you expecting it to be? Won't work for enums with first elements that are non-zero either: enum foo : int { bar = 1; } foo f; if(f) writeln("this will output too"); -Stevebut by default it works you just changed the default so its ok that it doesnt work.
May 27 2016
On 5/27/16 1:42 PM, ArturG wrote:On Friday, 27 May 2016 at 16:56:21 UTC, Steven Schveighoffer wrote:I didn't change the default. The default is to pick the first member and use that as the init value. I may not have even considered what foo.init might be when I was creating my enum. -SteveWhy are you expecting it to be? Won't work for enums with first elements that are non-zero either: enum foo : int { bar = 1; } foo f; if(f) writeln("this will output too");but by default it works you just changed the default so its ok that it doesnt work.
May 27 2016
On Friday, 27 May 2016 at 18:03:23 UTC, Steven Schveighoffer wrote:I didn't change the default. The default is to pick the first member and use that as the init value. I may not have even considered what foo.init might be when I was creating my enum. -Steveby default i ment this enum foo { bar } foo f; if(f) "dosnt print".writeln; but i understand what you mean which adds a problem to my checkThen template, as the return type of the template depends on the return type of the callable which right now returns the init value of the callable return type if the type you pass into the template evaluates to false. an example: class Foo { int x; } Foo foo(){ return null; } foo.checkThen!( f => f.x = 5; ).writeln; // writes f.x.init because i kinda need a common return type if foo wouldnt return null
May 27 2016
On Friday, 27 May 2016 at 15:49:16 UTC, ArturG wrote:On Friday, 27 May 2016 at 15:24:18 UTC, Adam D. Ruppe wrote:NaN in IEEE 754 floating-point numbers (the floating-point number system most languages and processors use) is defined as a number with all exponent bits set and a non-zero mantissa. The mantissa value is the "NaN payload", and can be any value. `is` does a binary comparison on floating-point numbers, so NaNs with different payloads will not be considered equal, as you have found out with `float.init !is float.nan`.On Friday, 27 May 2016 at 15:19:50 UTC, ArturG wrote:What do you mean? operation on float.nan gives you a float.nan so why does the shortcut evaluate to true and not false wouldnt that make more sense?yes but i have to check for that when some one doesWhy? This is no different than if they set any of the other four billion possible values.
May 30 2016
On Friday, 27 May 2016 at 14:48:59 UTC, Adam D. Ruppe wrote:On Friday, 27 May 2016 at 14:43:47 UTC, ArturG wrote:does this count? struct Foo { int x; float f; } void main() { Foo foo; if(foo is typeof(foo).init) "A: does'nt work".writeln; foo = Foo(); if(foo is typeof(foo).init) "B: works".writeln; } if you remove the float from the struct both cases work or if you define the float inside the struct like this: struct Foo { int x; // float f = float.init; // does'nt work float f = float.nan; }Have you tried? That should work in all cases.if(value is typeof(value).init) ...that still requiers a special case for floating points, arrays and optionally empty string literals.
May 30 2016
On Monday, 30 May 2016 at 19:06:53 UTC, ArturG wrote:does this count? struct Foo { int x; float f; } void main() { Foo foo; if(foo is typeof(foo).init) "A: does'nt work".writeln; foo = Foo(); if(foo is typeof(foo).init) "B: works".writeln; }This one is a bug in DMD. It works correctly with LDC. `Foo()` is supposed to be identical to `Foo.init`. File here: https://issues.dlang.org/show_bug.cgi?id=16105
May 31 2016
On 05/26/2016 04:03 PM, ArturG wrote:for example: if(any floatingpoint.init) will be true if(any char.init) also true if("") also true while others are false e.g. string s; if(s) will be false all others are also false or did i miss any?What does it matter?
May 26 2016
On Thursday, 26 May 2016 at 15:25:26 UTC, ag0aep6g wrote:On 05/26/2016 04:03 PM, ArturG wrote:You would have to create special cases for them.for example: if(any floatingpoint.init) will be true if(any char.init) also true if("") also true while others are false e.g. string s; if(s) will be false all others are also false or did i miss any?What does it matter?
May 26 2016
On 05/26/2016 05:28 PM, ArturG wrote:On Thursday, 26 May 2016 at 15:25:26 UTC, ag0aep6g wrote:[...]When? If you want to check if something is the .init value, compare against .init.What does it matter?You would have to create special cases for them.
May 26 2016