float equality
Don
nospam at nospam.com
Mon Feb 21 06:27:18 PST 2011
spir wrote:
> On 02/21/2011 05:32 AM, Walter Bright wrote:
>> Kevin Bealer wrote:
>>> == Quote from Walter Bright (newshound2 at digitalmars.com)'s article
>>>> Kevin Bealer wrote:
>>>>> You could switch to this:
>>>>>
>>>>> struct {
>>>>> BigInt numerator;
>>>>> BigInt denominator;
>>>>> };
>>>>>
>>>>> Bingo -- no compromise.
>>>> It cannot represent irrational numbers accurately.
>>>
>>> True but I did mention this a few lines later.
>>
>> I guess I'm not seeing the point of representing numbers as ratios.
>> That works
>> only if you stick to arithmetic. As soon as you do logs, trig
>> functions, roots,
>> pi, etc., you're back to square one.
>
> "Naturally" non-representable numbers (irrationals), or results of
> "naturally" approximate operations (like trig), are not an issue because
> they are expected to yield inaccuracy.
You keep talking about "inaccuracy" and "approximation", when I think
you really mean "rounding".
Actually irrationals are a *big* issue. You might expect sin(PI) == 0,
but it isn't. This isn't a problem with sin(), it's a problem with the
limited resolution of PI. sin(3.141592654) != 0.
>
> This is different from numbers which are well definite in base ten, as
> well as results of operations which should yield well definite results.
> We think in base ten, thus for us 1.1 is exact. Two operations yielding
> 1.1 (including plain conversion to binary of the literal '1.1') may in
> fact yield unequal numbers at the binary level; this is a trap, and just
> wrong:
> assert (1.1 != 3.3 - 2.2); // pass
> Subsequent issue is (as I just discovered) that there is no remedy for
> that, since there is no way to know, in the general case, how many
> common magnitude bits are supposed to be shared by the numbers to be
> compared, when the results are supposed to be correct. (Is this worse if
> floating point format since the scale factor is variable?)
Decimal floating point formats exist, and have been implemented in
hardware in some cases. They don't suffer from the rounding-during-I/O
issue that you mention. Fortunately D supports the %a binary floating
point format, eg, 0x1.34p+46, which gives you what-you-see-is-what-you-get.
>
> This lets me think that, for common use, fixed point with a single
> /decimal/ scale factor (for instance 10^-6) may be a better solution.
> While the underlying integer type may well be binary --this is
> orthogonal-- we don't need using eg BCD. Using longs, this example would
> allow representing numbers up to +/- (2^63)/(10^-9), equivalent to
> having about 43 bits for the integral part (*), together with a
> precision of 6 decimal digits for the fractional part. Seems correct for
> common use cases, I guess.
>
>
> Denis
>
> (*) 10^6 ~ 2^20
> (2^63)/(10^-6) > 9_000_000_000_000
More information about the Digitalmars-d
mailing list