digitalmars.D - double.init is nan ..?
- Etienne (5/5) Mar 14 2014 I'm trying to compare two doubles as part of a cache framework. To put
- bearophile (5/10) Mar 14 2014 Yes, it's a question for D.learn. And double.init is a NaN. NaN
- Adam D. Ruppe (8/9) Mar 14 2014 Yes, and the reason for this is NaN is similar to null - an
- Etienne (7/15) Mar 14 2014 The cache library stores serialized strings mostly, and returns an empty...
- Etienne (4/15) Mar 14 2014 Ok isNaN works on the deserialized values and simple comparisons works
- Adam D. Ruppe (21/22) Mar 14 2014 Interestingly:
- bearophile (6/8) Mar 14 2014 Keep in mind that there are many NaNs, and double.nan is not the
- Adam D. Ruppe (6/10) Mar 14 2014 Oh yeah, I forgot about that! (double.init is a signaling nan
- Etienne (2/13) Mar 14 2014 OK so I don't have to pack the structs to compare them! Thanks :)
- bearophile (6/8) Mar 14 2014 "is" between complex values should be seen as a special tool, to
- Adam D. Ruppe (7/10) Mar 14 2014 Perhaps, but when comparing between the init value it should
- luka8088 (3/5) Mar 15 2014 Note that you should not compare floating point types for equality!
I'm trying to compare two doubles as part of a cache framework. To put it simply, double.init == double.init ... is false? I don't understand. Maybe this belongs is D.learn, but I have no idea why or how this could possibly be normal behavior. Does anyone have a clue? Thanks!
Mar 14 2014
Etienne:I'm trying to compare two doubles as part of a cache framework. To put it simply, double.init == double.init ... is false? I don't understand. Maybe this belongs is D.learn, but I have no idea why or how this could possibly be normal behavior. Does anyone have a clue? Thanks!Yes, it's a question for D.learn. And double.init is a NaN. NaN comparisons return false. Bye, bearophile
Mar 14 2014
On Friday, 14 March 2014 at 16:06:17 UTC, bearophile wrote:And double.init is a NaN.Yes, and the reason for this is NaN is similar to null - an invalid state, so it can help you to catch uninitialized variables. You should explicitly initialize the variables normally and for the cache case, either keep a separate variable to tell if it is initialized (since NaN might be a valid cache state, like how an int may legitimately be 0) or compare using std.math.isNaN.
Mar 14 2014
On 2014-03-14 12:10 PM, Adam D. Ruppe wrote:On Friday, 14 March 2014 at 16:06:17 UTC, bearophile wrote:The cache library stores serialized strings mostly, and returns an empty value if there's a get on an empty key (like redis), so I was surprised to see get("key").unpack!double == double.init == false even when they key doesn't exist. So, I guess I'll have to modify msgpack-d to give doubles a 0.000 initialization value!And double.init is a NaN.Yes, and the reason for this is NaN is similar to null - an invalid state, so it can help you to catch uninitialized variables. You should explicitly initialize the variables normally and for the cache case, either keep a separate variable to tell if it is initialized (since NaN might be a valid cache state, like how an int may legitimately be 0) or compare using std.math.isNaN.
Mar 14 2014
On 2014-03-14 12:14 PM, Etienne wrote:On 2014-03-14 12:10 PM, Adam D. Ruppe wrote:Ok isNaN works on the deserialized values and simple comparisons works on the serialized values in the cache store. Struct.init is unreliable now in my books. Thanks!On Friday, 14 March 2014 at 16:06:17 UTC, bearophile wrote:And double.init is a NaN.Yes, and the reason for this is NaN is similar to null - an invalid state, so it can help you to catch uninitialized variables. You should explicitly initialize the variables normally and for the cache case, either keep a separate variable to tell if it is initialized (since NaN might be a valid cache state, like how an int may legitimately be 0) or compare using std.math.isNaN.
Mar 14 2014
On Friday, 14 March 2014 at 16:25:59 UTC, Etienne wrote:Struct.init is unreliable now in my books. Thanks!Interestingly: struct A{ int a; double b; } void main() { A a; assert(a is A.init); // passes assert(a == A.init); // fails double test; assert(test is double.nan); // fails } I struct == other_struct works basically by checking the equality operator on each member inside. So that is like saying assert(a.a == A.init.a && b.a ==B.init.b) which fails cuz of the nan rule. Whereas struct is other_struct works by just comparing the memory bytes, regardless of the types of the contents. If they match, it is considered a pass, which will always be the case for comparing against init.
Mar 14 2014
Adam D. Ruppe:double test; assert(test is double.nan); // failsKeep in mind that there are many NaNs, and double.nan is not the same as dounle init. So this passes: assert(test is double.init); Bye, bearophile
Mar 14 2014
On Friday, 14 March 2014 at 16:50:11 UTC, bearophile wrote:Keep in mind that there are many NaNs, and double.nan is not the same as dounle init.Oh yeah, I forgot about that! (double.init is a signaling nan while double.nan is not. There's a whole bunch of other nans possible in floating point too btw) You're right. Looks like "is" always just compares the raw bits, which is good stuff when comparing with init.So this passes: assert(test is double.init);
Mar 14 2014
On 2014-03-14 1:01 PM, Adam D. Ruppe wrote:On Friday, 14 March 2014 at 16:50:11 UTC, bearophile wrote:OK so I don't have to pack the structs to compare them! Thanks :)Keep in mind that there are many NaNs, and double.nan is not the same as dounle init.Oh yeah, I forgot about that! (double.init is a signaling nan while double.nan is not. There's a whole bunch of other nans possible in floating point too btw) You're right. Looks like "is" always just compares the raw bits, which is good stuff when comparing with init.So this passes: assert(test is double.init);
Mar 14 2014
Etienne:OK so I don't have to pack the structs to compare them! Thanks :)"is" between complex values should be seen as a special tool, to be used carefully. It's not a good idea to use it widely and carelessly. Bye, bearophie
Mar 14 2014
On Friday, 14 March 2014 at 17:54:23 UTC, bearophile wrote:"is" between complex values should be seen as a special tool, to be used carefully. It's not a good idea to use it widely and carelessly.Perhaps, but when comparing between the init value it should always work because they do the same thing: init is the bytes copied to the type when it is first declared is compares the two sets of bytes Since both are about a simple byte block it should be pretty well reliable.
Mar 14 2014
On 14.3.2014. 17:04, Etienne wrote:I'm trying to compare two doubles as part of a cache framework. To put it simply, double.init == double.init ... is false?Note that you should not compare floating point types for equality! http://www.parashift.com/c++-faq/floating-point-arith.html
Mar 15 2014