February 08, 2015
> There is no right or wrong when you compare floating point values for equality (and inequality) unless those values can be represented exactly in the machine. 1.0 is famously not representable exactly. (It is similar to how 1/3 cannot be represented in the decimal system.)

Here I tested one aspect of IEEE-754 floating point behavior (not ordinary floating point calculations for daily job). All integers can be represented exactly until some maximum value.

I believe that first section from http://dlang.org/float.html explains why behavior of my program should not be considered a bug in the compiler. But does it mean that due to these rules the results of the computation are not according to IEEE-754 for some specified floating point format (32 bit single precision in my examples)?

For example, according to IEEE-754 specification if we work with 32bit floating point numbers (floats in D) then the following pseudo code prints 'Works'.

F32 f = 16777216.0f;
F32 f2 = f + 0.1f;
if is_the_same_binary_presentation(f, f2)
  Print("Works");

As I understand D does not guarantee this. Please confirm if it's correct.
February 08, 2015
> nope, this is a bug in your code. compiler (by the specs) is free to
> perform intermediate calculations with any precision that is not lower
> than a highest used type (i.e. not lower that `float`'s one for `while`
> condition (`f + eps != f`). it may be even infinite precision, so your
> code may not exit the loop at all.

Thanks, it's clear now. I still have one question in the above post, I would appreciate if you check it too.

February 08, 2015
On Sun, 08 Feb 2015 09:05:30 +0000, Kenny wrote:

> Thanks, it's clear now. I still have one question in the above post, I would appreciate if you check it too.

i've seen that, but i don't know the answer, sorry. here we have to summon Walter to explain what his intentions was, how it should work and why.

February 08, 2015
> For example, according to IEEE-754 specification if we work with 32bit floating point numbers (floats in D) then the following pseudo code prints 'Works'.
>
> F32 f = 16777216.0f;
> F32 f2 = f + 0.1f;
> if is_the_same_binary_presentation(f, f2)
>   Print("Works");
>
> As I understand D does not guarantee this. Please confirm if it's correct.

One clarification:

In D the following should always print 'Works'
float f = 16777216.0f;
float f2 = f + 1.0f;
if (f == f2)
 writeln("Works");

I asked more about this case:
float f = 16777216.0f;
if (f == f + 1.0f)
 writeln("Works");

Although all operands are 32bit FP the result is not guaranteed to be equal to the result for FP32 computations as specified by IEEE-754.
February 08, 2015
On Sun, 08 Feb 2015 09:19:06 +0000, Kenny wrote:

> I asked more about this case:
> float f = 16777216.0f;
> if (f == f + 1.0f)
>   writeln("Works");
> 
> Although all operands are 32bit FP the result is not guaranteed to be equal to the result for FP32 computations as specified by IEEE-754.

i think you are mixing two things here. IEEE doesn't specify which internal representation compilers should use, it only specifies the results for chosen representation. so if D specs states that `float` calculations are always performing with `float` precision (and specs aren't), your sample should work.

but the specs says that compiler is free to promote such expression to any type it wants, it just should not loose precision. so the actual type of `f` in `f == f + 1.0f` can be freely promoted to `double`, `real` or even to some GMP representation.

February 08, 2015
On Sunday, 8 February 2015 at 09:19:08 UTC, Kenny wrote:
>> For example, according to IEEE-754 specification if we work with 32bit floating point numbers (floats in D) then the following pseudo code prints 'Works'.
>>
>> F32 f = 16777216.0f;
>> F32 f2 = f + 0.1f;
>> if is_the_same_binary_presentation(f, f2)
>>  Print("Works");
>>
>> As I understand D does not guarantee this. Please confirm if it's correct.
>
> One clarification:
>
> In D the following should always print 'Works'
> float f = 16777216.0f;
> float f2 = f + 1.0f;
> if (f == f2)
>  writeln("Works");
>
> I asked more about this case:
> float f = 16777216.0f;
> if (f == f + 1.0f)
>  writeln("Works");
>
> Although all operands are 32bit FP the result is not guaranteed to be equal to the result for FP32 computations as specified by IEEE-754.

«Algorithms should be written to work based on the minimum precision of the calculation. They should not degrade or fail if the actual precision is greater.»

http://dlang.org/float.html

:-/
February 08, 2015
Also note that denormal numbers is an issue, e.g. D assumes that they are always supported, I think. Which frequently is not the case...
February 08, 2015
> i think you are mixing two things here. IEEE doesn't specify which
> internal representation compilers should use, it only specifies the
> results for chosen representation. so if D specs states that `float`
> calculations are always performing with `float` precision (and specs
> aren't), your sample should work.
>
> but the specs says that compiler is free to promote such expression to
> any type it wants, it just should not loose precision. so the actual type
> of `f` in `f == f + 1.0f` can be freely promoted to `double`, `real` or
> even to some GMP representation.

It's clear now, thanks!. Also thanks to everyone for the answers, it was very helpful.

1 2
Next ›   Last »