Very strange problem with comparing floating point numbers
Maxim Fomin
maxim at maxim-fomin.ru
Mon Oct 1 06:07:36 PDT 2012
2012/10/1 monarch_dodra <monarchdodra at gmail.com>:
> On Monday, 1 October 2012 at 11:36:43 UTC, Maxim Fomin wrote:
>>
>> On Sunday, 30 September 2012 at 17:07:19 UTC, monarch_dodra wrote:
>>>
>>> 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.
>>
>>
>> It is possible to compare exactly floating point types by binary
>> comparison, if it provides some benefits.
>>
>> import std.stdio;
>> import std.math;
>>
>> @property float getFloat()
>> {
>> return sqrt(1.1);
>> }
>>
>> void main()
>> {
>> writeln(getFloat is getFloat); // doesn't fail
>> }
>
>
> I think that what you are comparing here is the functions (the address), and
> not the results of the call. Try
> writeln(getFloat() is getFloat()); //*May* fail
>
http://dpaste.dzfl.pl/1f94c0b1
It works with -m32 too.
_Dmain:
0x0806d0e4 <+0>: push %ebp
0x0806d0e5 <+1>: mov %esp,%ebp
0x0806d0e7 <+3>: sub $0x10,%esp
0x0806d0ea <+6>: push %esi
0x0806d0eb <+7>: push %edi
0x0806d0ec <+8>: call 0x806d0d4 <_D4test8getFloatFNdZf>
0x0806d0f1 <+13>: fstps -0x10(%ebp)
0x0806d0f4 <+16>: lea -0x10(%ebp),%esi
0x0806d0f7 <+19>: call 0x806d0d4 <_D4test8getFloatFNdZf>
0x0806d0fc <+24>: fstps -0xc(%ebp)
0x0806d0ff <+27>: lea -0xc(%ebp),%edi
0x0806d102 <+30>: mov $0x4,%ecx
0x0806d107 <+35>: xor %eax,%eax
0x0806d109 <+37>: repz cmpsb %es:(%edi),%ds:(%esi)
0x0806d10b <+39>: je 0x806d112 <_Dmain+46>
0x0806d10d <+41>: sbb %eax,%eax
0x0806d10f <+43>: sbb $0xffffffff,%eax
0x0806d112 <+46>: neg %eax
0x0806d114 <+48>: sbb %eax,%eax
0x0806d116 <+50>: inc %eax
0x0806d117 <+51>: call 0x806d164 <_D3std5stdio14__T7writelnTbZ7writelnFbZv>
0x0806d11c <+56>: call 0x806d0d4 <_D4test8getFloatFNdZf>
0x0806d121 <+61>: fstps -0x8(%ebp)
0x0806d124 <+64>: lea -0x8(%ebp),%esi
0x0806d127 <+67>: call 0x806d0d4 <_D4test8getFloatFNdZf>
0x0806d12c <+72>: fstps -0x4(%ebp)
0x0806d12f <+75>: lea -0x4(%ebp),%edi
0x0806d132 <+78>: mov $0x4,%ecx
0x0806d137 <+83>: xor %eax,%eax
0x0806d139 <+85>: repz cmpsb %es:(%edi),%ds:(%esi)
0x0806d13b <+87>: je 0x806d142 <_Dmain+94>
0x0806d13d <+89>: sbb %eax,%eax
0x0806d13f <+91>: sbb $0xffffffff,%eax
0x0806d142 <+94>: neg %eax
0x0806d144 <+96>: sbb %eax,%eax
0x0806d146 <+98>: inc %eax
0x0806d147 <+99>: call 0x806d164 <_D3std5stdio14__T7writelnTbZ7writelnFbZv>
0x0806d14c <+104>: call 0x806d0d4 <_D4test8getFloatFNdZf>
0x0806d151 <+109>: sub $0x4,%esp
0x0806d154 <+112>: fstps (%esp)
0x0806d157 <+115>: call 0x806d588
<_D3std5stdio14__T7writelnTfZ7writelnFfZv>
0x0806d15c <+120>: xor %eax,%eax
0x0806d15e <+122>: pop %edi
0x0806d15f <+123>: pop %esi
0x0806d160 <+124>: leave
0x0806d161 <+125>: ret
> Also, "is" works like opEqual on built in types, AFAIK, it doesn't use any
> "binary" magic or anything like that.
I don't understand what you are trying to say. Is operator at runtime
compares two objects without calling opEquals functions (if applied on
user-defined types). For built-in and derived types it is similar to
== operator. Although, I am suprised that TDPL and spec doesn't
mention it (focused only on CT usage), there is a paragraph
(http://ddili.org/ders/d.en/null_is.html) from Turkish D book which
clearly shows such usage - so, I think this a valid D feature. Object
comparison at low-level (repz cmpsb) means binary comparison.
More information about the Digitalmars-d-learn
mailing list