Re: BigNum -- Floating Point

From: Programmer Dude (Chris_at_Sonnack.com)
Date: 12/16/03


Date: Tue, 16 Dec 2003 14:37:46 -0600

Thad Smith wrote:

> The choice is partly determined by the expected use.

It's to be a native numeric type for a language.

> In general, I would use something like standard floating point:
> mantissa and exponent.

I confess, I hadn't considered that route. Interesting...

> You will need to decide what size to make the exponent and
> what base to use. A convenient base is 2^32, so that when
> you normalize numbers, you shift them by whole words.

In that the current implementation already uses 32-bit "digits",
this would be a decent fit.

> A 31 bit signed exponent would give you an amazing range of
> 2^(-(2^30)*32) to 2^((2^30)*32), which would let you place
> about 1e10 zeros, in decimal representation, before or after
> the mantissa.

Range is less important than precision. Precision must be as
high as (1) required OR (2) requested by the user (see previous
post about the DivPrecision setting). That means the user should
have the ability to write an algorithm that accurately generates
10,000 digits of pi if they want. The package *must* support that.

Which, when I think about it, is why I didn't consider the mantissa
and exponent technique. I don't see that it buys me anything, as
the real "meat" is all in the mantissa.

> By making the exponent 31 bits, you can use the left-over
> bit for the sign of the number.

Number objects currently have instance variables for sign, dp
and length. Space is not really a design criterion at all in
this, so I'm not concerned with using bits.

> Of course, if that exponent isn't large enough, you can make the
> exponent a big int, but I suspect that would rarely be required,
> since floating point values are normally used for measurable
> quantities, and the number of atoms in the universe is estimated
> around 1e80 or so.

Understood. And for that sort of thing, the values of the lowest
digits don't much matter. For my project, they do (the user might
want to play with writing RSA, for example, or might want to write
something else that canNOT be "lossy").

>> Another idea is to keep integral values and remember where the DP
>> goes. For example, 42.5 would be 425(dp=1). The problem here is
>> this makes simple operations expensive. Merely comparing 42 and
>> 42.0000 requires multiplying the former by 10000 (granted, each
>> 10x shift can be done with two shifts and a fast add, but....).
>
> If you want decimal-based numbers, you can consider using base 1e9,
> which will fit in a 32-bit value. It makes the arithmetic routines
> slightly harder, but makes decimal conversion a breeze.

(Conversion to decimal is fairly trivial, so is not a consideration
one way or other.) I think my example wasn't clear. The storage
representation is *binary*, not decimal. But the binary value is
(in one design I'm considering) the "normalized integer value" of
the number, by which I mean that, e.g., 3.14159 would be stored as
the binary value the largish integer, 314159. The system simply
remembers (as a sort of exponent, if you will) that five of the
digits are right of the DP.

If I were to add/subtract/logicalOp/compareOp that value of pi with,
e.g., 42.5--stored as the integer 425 (with one decimal digit)--I'd
need to multiply the 425 by 10,000 (giving 4250000). Then the
values have equal "rank" and those operations will work as expected.

Multiplication and division don't require those games, just keeping
track of--and adjusting in the result--the new number of fractional
digits. For example, 425 * 314159 = 133517575. And the dp=1 and
dp=5 are here summed, so the result is 133517575 (dp=6): 133.517575

I was rather bemused to realize that this design makes multiplication
and division *less* expensive than the "simpler" operations!

-- 
|_ CJSonnack <Chris@Sonnack.com> _____________| How's my programming? |
|_ http://www.Sonnack.com/ ___________________| Call: 1-800-DEV-NULL  |
|_____________________________________________|_______________________|


Relevant Pages

  • Re: Complete RPL object type table
    ... Although HP allocated 20 bits for the DIGITS setting, ... The "LongFloat" library ... ddddddd....ddddddddd - mantissa digits ... - length of exponent and its sign + 5 ...
    (comp.sys.hp48)
  • Re: how do I get more numbers past the decimal?
    ... A floating point number is stored on a 32 bit machine using the 24 bit for the mantissa and its sign and 8 bits for the exponent and its sign. ... You are showing 12 significant digits. ... A float value can be exactly represented by up to 9 decimal digits. ...
    (comp.lang.php)
  • Re: What I can to do with old PL/I code?
    ... A decimal floating-point constant is a mantissa followed by an exponent. ... The exponent is the letter E, S, D, or Q followed by an optionally-signed decimal integer of four or less digits. ... Constants using E have a precision where p is the number of digits of the mantissa. ...
    (comp.lang.pl1)
  • Re: BigNum -- Floating Point
    ... The 'N' is the number of decimal digits. ... The internal representation is really just a string of bits. ... the number of shifts for various multiples of ten: ... The 'exponent' is very closely related to ...
    (comp.programming)
  • Re: Fixed-point Math help
    ... > suggestion of using google is probably a good one. ... > can be packed in any format you like or is convenient to you. ... but it is usually assumed for the mantissa at any convenient ... > values of the exponent. ...
    (comp.arch.embedded)