On 09/29/2012 06:48 PM, Andrej Mitrovic wrote:
> The second one uses fstp twice, then fld twice. I don't know, maybe
> this could be a bug. My ASM is weak but I see some difference here..
I saw similar differences but my asm is even weaker. :)
I am writing to confirm that I can reproduce the problem with -m32 on a 64-bit system. The code works as expected without -m32.
Ali

> The second one uses fstp twice, then fld twice. I don't know, maybe
> this could be a bug.
You're right the lack of one fst/fld in the first case is a bug. x87 floating point registers are 80 bit. This:
fstp dword [ebp-0CH]
Converts the value in ST0 to single precision float and stores it to memory (and pops ST0). When it is later loaded with fld, it is not the same as before storing since some precision is lost (because the D code compares floats and not reals, this is the correct behavior). In the first example, this storing and loading only happens for the first function call. For the second call the value is returned in ST0 and stays in x87 registers until it is compared with fucompp so it is not truncated as the result of the first function call was. That's why the compared values are not equal.

On Sunday, 30 September 2012 at 01:29:24 UTC, Ivan Agafonov wrote:
> // Tell me about this sutation, may be it is a bug?
>> [SNIP]
> // all of this fails!!!
> assert (a.length == a.length); // This is really shocking
> assert (a.length == a3.length);
> [SNIP]
This is just a fact of life regarding how floating point types work. Here is a well documented explanation. It pertains to C++, but applies.
http://www.parashift.com/c++-faq/floating-point-arith2.html
As a rule of thumb, NEVER use opEqual with floating point types aniways. You need to use some sort of comparison with leway for error, such as std.math.approxEqual.

On Sunday, 30 September 2012 at 17:07:19 UTC, monarch_dodra wrote:
> On Sunday, 30 September 2012 at 01:29:24 UTC, Ivan Agafonov wrote:
>> // Tell me about this sutation, may be it is a bug?
>>>> [SNIP]
>> // all of this fails!!!
>> assert (a.length == a.length); // This is really shocking
>> assert (a.length == a3.length);
>> [SNIP]
>> This is just a fact of life regarding how floating point types work. Here is a well documented explanation. It pertains to C++, but applies.
>> http://www.parashift.com/c++-faq/floating-point-arith2.html>> As a rule of thumb, NEVER use opEqual with floating point types aniways. You need to use some sort of comparison with leway for error, such as std.math.approxEqual.
Floating point types are trouble enough without these
optimization failures.
There are many unsolved problems, things like approxEqual are far
from answering them. Whatever the justifications they come up
with, "a.len == a.len" failure is IMO unacceptable, an opEqual
like this must not fail.
A suggestion: do what i do and have this in your config files.
alias real evil;

On Sunday, 30 September 2012 at 18:31:17 UTC, so wrote:
> On Sunday, 30 September 2012 at 17:07:19 UTC, monarch_dodra wrote:
>> On Sunday, 30 September 2012 at 01:29:24 UTC, Ivan Agafonov wrote:
>>> // Tell me about this sutation, may be it is a bug?
>>>>>> [SNIP]
>>> // all of this fails!!!
>>> assert (a.length == a.length); // This is really shocking
>>> assert (a.length == a3.length);
>>> [SNIP]
>>>> This is just a fact of life regarding how floating point types work. Here is a well documented explanation. It pertains to C++, but applies.
>>>> http://www.parashift.com/c++-faq/floating-point-arith2.html>>>> As a rule of thumb, NEVER use opEqual with floating point types aniways. You need to use some sort of comparison with leway for error, such as std.math.approxEqual.
>> Floating point types are trouble enough without these
> optimization failures.
> There are many unsolved problems, things like approxEqual are far
> from answering them. Whatever the justifications they come up
> with, "a.len == a.len" failure is IMO unacceptable, an opEqual
> like this must not fail.
>> A suggestion: do what i do and have this in your config files.
>> alias real evil;
I don't really agree with that. floating point operations are just inexact, regardless of optimizations. That's how they work, period.
Either you can work with inexact results, and you use them, or you can't, and don't. Banks don't use floating point types for exactly this reason. You have to know what you are getting into before you begin.
The real troubles really only start when you start using floating point type, but you expect exact results.