[squeak-dev] Float storage as Double?
Lawson English
lenglish5 at cox.net
Mon Apr 26 10:45:25 UTC 2010
Levente Uzonyi wrote:
> On Mon, 26 Apr 2010, Lawson English wrote:
>
>> Levente Uzonyi wrote:
>>> On Mon, 26 Apr 2010, Lawson English wrote:
>>>
>>>> I've been playing around with the Mandelbrot set and I noticed that
>>>> the implementation using Float looked somewhat vague. After
>>>> researching a while, it turns out (corrections welcome) that while
>>>> Float performs 64-bit FP calculations, only a limited number of
>>>> decimal places are stored for subsequent calculations. Is there a
>>>> way around this?
>>>
>>> That's not true, every Float stores 64 bits. Just because some
>>> digits are not shown in the printString, it doesn't mean they aren't
>>> there:
>>>
>>> 1.01 printString. "==> '1.01'"
>>> 1.01 printShowingDecimalPlaces: 60. "==>
>>> '1.010000000000000008881784197001252323389053344726562500000000'"
>>>
>>
>> I'm not sure what this means:
>>
>> 1.4142135623730950488016887242096980785696718753769480
>> printShowingDecimalPlaces: 60
>> '1.414213562373095145474621858738828450441360473632812500000000'
>
> It means that your number cannot be represented accurately as a Float.
> Details here:
> http://en.wikipedia.org/wiki/Floating_point#Representable_numbers.2C_conversion_and_rounding
>
>
>>
>>
>>>
>>>>
>>>> is there a faster way to truncate a ScaledDecimal than the above?
>>>
>>> Sure, don't convert it to strings. :) I think you shouldn't use
>>> ScaledDecimal at all, since it's just a combination of a fraction
>>> and scale. You only need the fraction. Use #truncateTo: to truncate
>>> a number.
>> Still confused, sorry.
>>
>> Even with 15 decimal places, a Float-based M set generator is going
>> to be inaccurate after a few levels of zoom. Fractions don't
>> truncate the way I need them to.
>
> How would you like them to truncate?
>
>
> Levente
>
a := (14142135623730950488016887242096980785696718753769480
/10000000000000000000000000000000000000000000000000000) asScaledDecimal.
a asFloat ==>1.414213562373095.
b:=a * a.
b asScaledDecimal ==> 1.999999999999999999999999999999999999999999999999999.
"b asFraction ==>
(124999999999999999999999999999999999999999999999999987064068383137630325081727067987961060813568112169
/62500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)
"
"The number is stored as a Fraction and all calculations are done on the
Fraction."
b := ScaledDecimal newFromNumber: b scale: 51.
"b ==> 1.999999999999999999999999999999999999999999999999999s51"
"b asFraction ==>
(124999999999999999999999999999999999999999999999999987064068383137630325081727067987961060813568112169
/62500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)"
b := ScaledDecimal readFrom: b asString.
"b ==> 1.999999999999999999999999999999999999999900000000000s51"
"b asFraction ==>
(19999999999999999999999999999999999999999
/10000000000000000000000000000000000000000)"
So for the M set generator, since I break out of the loop if things get
above 2, the calculations are accurate up to 51 decimals (in this case)
when I do the last operation above and I don't grow my fraction to
50,000 bytes or whatever.
Its slower than I would like, of course.
Lawson
More information about the Squeak-dev
mailing list
|