0.85 asRational = (85/100) ?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

0.85 asRational = (85/100) ?

Jens Meisner
VW7.4:
0.85 asRational  = (848850/998647) >> true
0.85 asRational = (85/100) >> false

That´s ugly isn´t it ?
Is this bug fixed?

Cheers
Jens


Reply | Threaded
Open this post in threaded view
|

Re: 0.85 asRational = (85/100) ?

Andres Valloud-3
Jens Meisner wrote:
> VW7.4:
> 0.85 asRational  = (848850/998647) >> true
> 0.85 asRational = (85/100) >> false
>
> That´s ugly isn´t it ?
> Is this bug fixed?
>  

Actually, it's normal behavior for floating point numbers.  Since 0.85
cannot be expressed as someIntegerOf23Bits times a power of two, then no
single precision floating point number will represent it exactly.

Using double precision floating point numbers won't help, because 0.85
is not someIntegerOf53Bits times a power of two either.

For further information, I'd recommend The Art of Computer Programming
by Donald E. Knuth.

Thanks,
Andres.

Reply | Threaded
Open this post in threaded view
|

Re: 0.85 asRational = (85/100) ?

Andres Valloud-3
Andres Valloud wrote:
> Jens Meisner wrote:
>> VW7.4:
>> 0.85 asRational  = (848850/998647) >> true
>> 0.85 asRational = (85/100) >> false
>>
>> That´s ugly isn´t it ?
>> Is this bug fixed?
>>  

This kept bugging me.  0.85 asRational should not be expected to be
85/100.  However, what is left unexplained is how a rational
representation of a floating point number can have an odd denominator
(!!!).  It looks like asRational should be implemented more or less like
this:

    (aFloat mantissa: 23) * (2 raisedTo: aFloat exponent - 22)

I am not totally sure if this expression works for denormalized floats
as well at this very moment, but I will look into this further.

Thanks,
Andres.

Reply | Threaded
Open this post in threaded view
|

RE: 0.85 asRational = (85/100) ?

Steven Kelly
In reply to this post by Jens Meisner
Andres Valloud wrote:

> > Jens Meisner wrote:
> >> VW7.4:
> >> 0.85 asRational  = (848850/998647) >> true
> >> 0.85 asRational = (85/100) >> false
> >>
> >> That´s ugly isn´t it ?
> >> Is this bug fixed?
>
> This kept bugging me.  0.85 asRational should not be expected to be
> 85/100.  However, what is left unexplained is how a rational
> representation of a floating point number can have an odd denominator

I was just about to ask the same!

Jens might prefer to use 0.85s:
  0.85s asRational = (85/100) >> true
The comments in FixedPoint should be read to understand the details.

It might be useful to update the comments in LimitedPrecisionReal classes to reflect the most often asked questions.

Cheers,
Steve

Reply | Threaded
Open this post in threaded view
|

Re: 0.85 asRational = (85/100) ?

Reinout Heeck
In reply to this post by Andres Valloud-3
Andres Valloud wrote:
> However, what is left unexplained is how a rational
> representation of a floating point number can have an odd denominator
> (!!!).  It looks like asRational should be implemented more or less like
> this:
>
>    (aFloat mantissa: 23) * (2 raisedTo: aFloat exponent - 22)
>
> I am not totally sure if this expression works for denormalized floats
> as well at this very moment, but I will look into this further.



0.4 asRational "print it ->"(2/5)



R
-

Reply | Threaded
Open this post in threaded view
|

AW: 0.85 asRational = (85/100) ?

Jens Meisner
In reply to this post by Andres Valloud-3
Thank you Andres,

so the bug is fixed (the bug was to write down 0.85 and not to think about
it).

Thanks
Jens

-----Ursprüngliche Nachricht-----
Von: Andres Valloud [mailto:[hidden email]]
Gesendet am: Dienstag, 28. August 2007 09:48
An: [hidden email]
Betreff: Re: 0.85 asRational = (85/100) ?

Andres Valloud wrote:
> Jens Meisner wrote:
>> VW7.4:
>> 0.85 asRational  = (848850/998647) >> true
>> 0.85 asRational = (85/100) >> false
>>
>> That´s ugly isn´t it ?
>> Is this bug fixed?
>>

This kept bugging me.  0.85 asRational should not be expected to be
85/100.  However, what is left unexplained is how a rational
representation of a floating point number can have an odd denominator
(!!!).  It looks like asRational should be implemented more or less like
this:

    (aFloat mantissa: 23) * (2 raisedTo: aFloat exponent - 22)

I am not totally sure if this expression works for denormalized floats
as well at this very moment, but I will look into this further.

Thanks,
Andres.



Reply | Threaded
Open this post in threaded view
|

Re: 0.85 asRational = (85/100) ?

Andres Valloud-3
In reply to this post by Reinout Heeck
Reinout Heeck wrote:
> 0.4 asRational "print it ->"(2/5)  

Strictly speaking, that is not correct either.

Thanks,
Andres.

Reply | Threaded
Open this post in threaded view
|

Re: 0.85 asRational = (85/100) ?

Andres Valloud-3
Andres Valloud wrote:
> Reinout Heeck wrote:
>> 0.4 asRational "print it ->"(2/5)  
>
> Strictly speaking, that is not correct either.

It took me a while, but I found a nice example.

    4/10 / 3 / 5 / 7 / 11 => 2/5775

However,

    (0.4 / 1155.0) = (2.0 / 5775.0) => false

even though

    (0.4 / 1155.0) asRational => 2/5775

Thanks,
Andres.

Reply | Threaded
Open this post in threaded view
|

Re: 0.85 asRational = (85/100) ?

Reinout Heeck
In reply to this post by Andres Valloud-3
Andres Valloud wrote:
> Reinout Heeck wrote:
>> 0.4 asRational "print it ->"(2/5)  
>
> Strictly speaking, that is not correct either.
>



You lost me. What exactly do you consider incorrect here?


R
-

Reply | Threaded
Open this post in threaded view
|

Re: 0.85 asRational = (85/100) ?

Andres Valloud-3
Reinout Heeck wrote:
> Andres Valloud wrote:
>> Reinout Heeck wrote:
>>> 0.4 asRational "print it ->"(2/5)  
>>
>> Strictly speaking, that is not correct either.
>>
> You lost me. What exactly do you consider incorrect here?
>  

No floating point number can be equal to 2/5.

Andres.

Reply | Threaded
Open this post in threaded view
|

Re: 0.85 asRational = (85/100) ?

John Brant-2
Andres Valloud wrote:
>
> No floating point number can be equal to 2/5.

Smalltalk thinks it can:
 (2/5) = 0.4 ==> true

VW uses the standard algorithm for converting to fractions, but it keeps
going until the denominator has more digits than the float can
represent. If VW would stop when the float #= the fraction, then we
would get better looking fractions. For example, if we add:
        (Fraction numerator: num2 denominator: denom2) = self
                ifTrue: [^Fraction numerator: num2 denominator: denom2].
before the "limit < denom1" statement, we'll get a better looking fraction:
        0.85 asRational ==> (17/20)
        0.81 asRational ==> (81/100)


John Brant