View mode: basic / threaded / horizontal-split · Log in · Help
April 14, 2012
Re: floats default to NaN... why?
Jerome BENOIT wrote:
> Why would a compiler set `real' to 0.0 rather then 1.0, Pi, 
> .... ?

Because 0.0 is the "lowest" (smallest, starting point, etc..) 
numerical value. Pi is the corner case and obviously has to be 
explicitly set.

If you want to take this further, chars could even be initialized 
to spaces or newlines or something similar. Pointers/references 
need to be defaulted to null because they absolutely must equal 
an explicit value before use. Value types don't share this 
limitation.

> The more convenient default set certainly depends on the 
> underlying mathematics,
> and a compiler  cannot (yet) understand the encoded mathematics.
> NaN is certainly the certainly the very choice as whatever the 
> involved mathematics,
> they will blow up sooner or later. And, from a practical point 
> of view, blowing up is easy to trace.

Zero is just as easy for the runtime/compiler to default to; and 
bugs can be introduce anywhere in the code, not just definition. 
We have good ways of catching these bugs in D with unittests 
already.
April 14, 2012
Re: floats default to NaN... why?
On Saturday, 14 April 2012 at 10:38:45 UTC, Silveri wrote:
> On Saturday, 14 April 2012 at 07:52:51 UTC, F i L wrote:
>> On Saturday, 14 April 2012 at 06:43:11 UTC, Manfred Nowak 
>> wrote:
>>> F i L wrote:
>>>
>>> 4) use hardware signalling to overcome some of the limitations
>>> impressed by 3).
>>
>> 4) I have no idea what you just said... :)
>
> On Saturday, 14 April 2012 at 07:58:44 UTC, F i L wrote:
>> That's interesting, but what effect does appending an invalid 
>> char to a valid one have? Does the resulting string end up 
>> being "NaS" (Not a String)? Cause if not, I'm not sure that's 
>> a fair comparison.
>
> The initialization values chosen are also determined by the 
> underlying hardware implementation of the type. Signalling NANs 
> (http://en.wikipedia.org/wiki/NaN#Signaling_NaN) can be used 
> with floats because they are implemented by the CPU, but in the 
> case of integers or strings their aren't really equivalent 
> values.

I'm sure the hardware can just as easily signal zeros.


> On Saturday, 14 April 2012 at 07:45:58 UTC, F i L wrote:
>> My original post was inspired by me showing my D code to 
>> another C# guy earlier, and coming up with poor explanations 
>> as to why floats where required to be defaulted in my math 
>> lib. His reaction what along the lines of my first post.
>
> I think the correct mindset when working in D is to think that 
> "all variables should be initialized" and if you get incorrect 
> calculations with zero values, division by zero errors or nan 
> errors the most likely mistake is often that this guideline was 
> not followed.

Like I said before, this is backwards thinking. At the end of the 
day, you _can_ use default values in D. Given that ints are 
defaulted to usable values, FP Values should be as well for the 
sake of consistency and convenience.

You can't force new D programmers to follow a 'guidline' no 
matter how loudly the documentation shouts it (which is barely 
does at this point), so said guideline is not a dependable 
practice all D will follow (unless it's statically enforced)... 
nor _should_ the learning curve be steepened by enforcing 
awareness of this idiosyncrasy.

The correct mindset from the compilers perspective should be: 
"people create variables to use them. What do they want if they 
didn't specify a value?"

therefor our mindset can be: "I defined a variable to use. Should 
be zero so I don't need to set it."
April 14, 2012
Re: floats default to NaN... why?
dennis luehring wrote:
> what does make float default to 0.0 better - does it just feel 
> better?

Not just. It's consistent with Int types, therefor easier for 
newbs to pick up since all numeric value types behave the same.

I even think char should default to a usable value as well. Most 
likely a space character. But that's another point.
April 14, 2012
Re: floats default to NaN... why?
On Saturday, 14 April 2012 at 12:48:01 UTC, Andrej Mitrovic wrote:
> On 4/14/12, bearophile <bearophileHUGS@lycos.com> wrote:
>> Having a variable not initialized is a common source of bugs.
>
> I'm going to argue that this was true for C/C++ but is much 
> less true
> for D. One benefit of having integrals initialized to 0 is that 
> you
> now have a defined default that you can rely on (just as you 
> can rely
> on pointers being null by default). Personally I find this to 
> be a big
> win in productivity. If the language/runtime does something 
> defined
> for me then I can focus on more important things.

Amen! This is exactly what I'm trying to get at. The compiler 
provides defaults as a convince feature (mostly) so that there's 
no garbage and so values are reliable. It's incredibly 
inconvenient at that point to have to remember to always 
explicitly init one specific type..

This feels very natural in C#.
April 14, 2012
Re: floats default to NaN... why?
On 4/14/12, F i L <witte2008@gmail.com> wrote:
> This is exactly what I'm trying to get at.

Anyway it's not all bad news since we can use a workaround:

struct Float {
   float payload = 0.0;
   alias payload this;
}

void main() {
   Float x;  // acts as a float, is initialized to 0.0
}

Not pretty, but it comes in handy.
April 14, 2012
Re: floats default to NaN... why?
On 14/04/12 16:47, F i L wrote:
> Jerome BENOIT wrote:
>> Why would a compiler set `real' to 0.0 rather then 1.0, Pi, .... ?
>
> Because 0.0 is the "lowest" (smallest, starting point, etc..)

quid -infinity ?

numerical value. Pi is the corner case and obviously has to be explicitly set.
>
> If you want to take this further, chars could even be initialized to spaces or newlines or something similar. Pointers/references need to be defaulted to null because they absolutely must equal an explicit value before use. Value types don't share this limitation.
>

CHAR set are bounded, `real' are not.


>> The more convenient default set certainly depends on the underlying mathematics,
>> and a compiler cannot (yet) understand the encoded mathematics.
>> NaN is certainly the certainly the very choice as whatever the involved mathematics,
>> they will blow up sooner or later. And, from a practical point of view, blowing up is easy to trace.
>
> Zero is just as easy for the runtime/compiler to default to;

Fortran age is over.
D compiler contains a lot of features that are not easy to set up by the compiler BUT meant for easing coding.


 and bugs can be introduce anywhere in the code, not just definition.

so the NaN approach discard one source of error.

 We have good ways of catching these bugs in D with unittests already.

Zero may give a value that sounds reasonable, NaN will give a NaN value ... which is not reasonable: this is NaN blow up and it can been seen right the way.

Note that the NaN approach is used in some numerical libraries as CLN.
April 14, 2012
Re: floats default to NaN... why?
On Saturday, 14 April 2012 at 15:44:46 UTC, Jerome BENOIT wrote:
>
>
> On 14/04/12 16:47, F i L wrote:
>> Jerome BENOIT wrote:
>>> Why would a compiler set `real' to 0.0 rather then 1.0, Pi, 
>>> .... ?
>>
>> Because 0.0 is the "lowest" (smallest, starting point, etc..)
>
> quid -infinity ?

The concept of zero is less meaningful than -infinity. Zero is 
the logical starting place because zero represents nothing 
(mathematically), which is inline with how pointers behave (only 
applicable to memory, not scale).


> numerical value. Pi is the corner case and obviously has to be 
> explicitly set.
>>
>> If you want to take this further, chars could even be 
>> initialized to spaces or newlines or something similar. 
>> Pointers/references need to be defaulted to null because they 
>> absolutely must equal an explicit value before use. Value 
>> types don't share this limitation.
>>
>
> CHAR set are bounded, `real' are not.

Good point, I'm not so convinced char should default to " ". I 
think there are arguments either way, I haven't given it much 
thought.


>>> The more convenient default set certainly depends on the 
>>> underlying mathematics,
>>> and a compiler cannot (yet) understand the encoded 
>>> mathematics.
>>> NaN is certainly the certainly the very choice as whatever 
>>> the involved mathematics,
>>> they will blow up sooner or later. And, from a practical 
>>> point of view, blowing up is easy to trace.
>>
>> Zero is just as easy for the runtime/compiler to default to;
>
> Fortran age is over.
> D compiler contains a lot of features that are not easy to set 
> up by the compiler BUT meant for easing coding.
>
>
>  and bugs can be introduce anywhere in the code, not just 
> definition.
>
> so the NaN approach discard one source of error.

Sure, the question then becomes "does catching bugs introduced by 
inaccurately defining a variable outweigh the price of 
inconsistency and learning curve." My opinion is No, expected 
behavior is more important. Especially when I'm not sure I've 
ever heard of someone in C# having bugs that would have been 
helped by defaulting to NaN. I mean really, how does:

    float x; // NaN
    ...
    x = incorrectValue;
    ...
    foo(x); // first time x is used

differ from:

    float x = incorrectValue;
    ...
    foo(x);

in any meaning full way? Except that in this one case:

    float x; // NaN
    ...
    foo(x); // uses x, resulting in NaNs
    ...
    x = foo(x); // sets after first time x is used

you'll get a "more meaningful" error message, which, assuming you 
didn't just write a ton of FP code, you'd be able to trace to 
it's source faster.

It just isn't enough to justify defaulting to NaN, IMO. I even 
think the process of hunting down bugs is more straight forward 
when defaulting to zero, because every numerical bug is pursued 
the same way, regardless of type. You don't have to remember that 
FP specifically causes this issues in only some cases.
April 14, 2012
Re: floats default to NaN... why?
On Saturday, 14 April 2012 at 15:35:13 UTC, Andrej Mitrovic wrote:
> On 4/14/12, F i L <witte2008@gmail.com> wrote:
>> This is exactly what I'm trying to get at.
>
> Anyway it's not all bad news since we can use a workaround:
>
> struct Float {
>     float payload = 0.0;
>     alias payload this;
> }
>
> void main() {
>     Float x;  // acts as a float, is initialized to 0.0
> }
>
> Not pretty, but it comes in handy.

Lol, that's kinda an interesting idea:

    struct var(T, T def) {
        T payload = def;
        alias payload this;
    }

    alias var!(float,  0.0f) Float;
    alias var!(double, 0.0)  Double;
    alias var!(real,   0.0)  Real;
    alias var!(char,   ' ')  Char;

    void main() {
        Float f;
        assert(f == 0.0f);
    }

a Hack though, since it doesn't work with 'auto'. I still think 
it should be the other way around, and this should be used to 
Default to NaN.
April 14, 2012
Re: floats default to NaN... why?
On 4/14/12, F i L <witte2008@gmail.com> wrote:
> a Hack though, since it doesn't work with 'auto'.

What do you mean?
April 14, 2012
Re: floats default to NaN... why?
On Saturday, 14 April 2012 at 17:30:19 UTC, Andrej Mitrovic wrote:
> On 4/14/12, F i L <witte2008@gmail.com> wrote:
>> a Hack though, since it doesn't work with 'auto'.
>
> What do you mean?

Only that:

    auto f = 1.0f; // is float not Float
1 2 3 4 5 6 7
Top | Discussion index | About this forum | D home