floating point verification using is?

Don nospam at nospam.com
Mon Dec 28 18:52:24 PST 2009


Steven Schveighoffer wrote:
> On Mon, 28 Dec 2009 06:51:30 -0500, Don <nospam at nospam.com> wrote:
> 
>> Stewart Gordon wrote:
>>> Steven Schveighoffer wrote:
>>> <snip>
>>>> Are you still working on this?  :)  I think this proves my point.  
>>>> The compiler does not provide an easy way to compare floats bitwise, 
>>>> so this means convoluted hard-to-write code.  When we have two 
>>>> operators that do equality -- and one of those means bitwise compare 
>>>> in all other contexts -- I think this is a no-brainer.
>>>  I entirely agree.
>>>  I've identified these cases in which float equality disagrees with 
>>> bitwise equality:
>>> - one is +0, one is -0
>>> - both are NaNs, identically signed
>>> - both are infinity, identically signed
>>>  In each case, is just does the same as ==.
>>>  Indeed, isIdentical is an ugly workaround for this, apparently 
>>> created instead of sanitising the definition of is to avoid the 
>>> minuscule amount of code breakage that the latter would effect.
>>
>> No, it was because I have write access to Phobos, but not to the 
>> compiler...
>>
>> But, this isn't as simple as people are assuming. There's a problem in 
>> the original request. We need to be clear about what T.init is. Is T.init
>> (a) the bit pattern which all variables of type T get default 
>> initialized to? Or is it
>> (b) an arbitrary valid value for type T?
>> In the case of floats, they are NOT "default initialized" -- they are 
>> marked as "not initialized". So there's a big question about whether 
>> semantic (a) T.init actually makes sense.
> 
> The answer is a.  Whether you like it or not, the runtime must 
> initialize it to something, even if the value means "uninitialized".  

The key question is: is it valid to read an uninitialized variable? I 
would hope the compiler would flag that as an error. The use of 
signalling NaNs was based on the assumption that you should *never* be 
reading uninitialized variables.

A consequence is that you should also NEVER read float.init!

> That value should always be consistent.  There has to be a way to verify 
> that the value was set properly.  Otherwise, how do you verify things
> like communication protocols or expectations for runtime functions?

I think that sending an uninitialized variable down a communication 
channel is always a bug.

> It has to be a bit pattern, because all other T.init values, including 
> those of aggregates which might contain floating points, are bit patterns.
> 
>> Consider this code:
>>
>> T x;
>> if (x==T.init) { writefln("x is uninitialized"); }
>>
>> Is this code valid? You are reading the value of an uninitialized 
>> variable.
> 
> Correct that to:
> 
> T x;
> if(x is T.init) {writefln("x is uninitialized"); }
> 
> Then I think it is valid.  I don't care if == is hijacked away from 
> bitwise comparison, in fact, it is necessary in many cases.  But there 
> should be a way to do bitwise comparison for verification, and 'is' fits 
> the bill perfectly.

That does preclude a compiler from ever giving you errors/warnings about 
using uninitialized variables. I think it's wrong.


More information about the Digitalmars-d-learn mailing list