These functions are to help visualize integer and rational numbers in
a more comprehensible format. The SigFig
argument is optional;
the default value is 5.
MantissaAndExponent(N, SigFig)
splits the number N
into three parts:
the sign, the mantissa (with SigFig
decimal digits), and the exponent
If N
is non-zero then the mantissa is a BigInt
whose value lies between
10^SigFig
and 10^(SigFig+1)-1
where both extremes are included.
The result is a struct of type MantExp
whose fields are mySign
,
myMantissa
and myExponent
.
FloatStr(N, SigFig)
convert the number N
into a string of the form
mantissa times power-of-ten, with SigFig
digits in the mantissa. Note
that trailing zeroes are not removed from the mantissa.
DecimalStr(N, SigFig)
convert the number N
into a decimal string with
SigFig
digits. If N
is very large or very small then it is passed to
FloatStr
. Note that trailing zeroes are not removed from the mantissa.
See also the functions ILogBase
(in the doc for BigInt
and BigRat
).
The functions MantissaAndExponent
do the real work. The only tricky
parts were deciding how to round in the case of a tie, and correct
behaviour when the mantissa "overflows". I finally decided to round away
from zero: it is easy to implement, and I wanted a solution which was
symmetric about zero, so that MantissaAndExponent
applied to N
and
to -N
would always give the same result except for sign.
Mantissa overflow occurs only when the last digit rounds away from zero, and all the digits were 9 before rounding. This case would never occur if I'd chosen simply to truncate when forming the mantissa.
Printing of a MantExp
structure is simple rather than elegant.
The function DecimalStr
passes its args to FloatStr
in two
situations: if the number is so large that padding would be needed
before the decimal point; if the number is so small that the
FloatStr
format would be shorter (i.e. if the exponent is less
than -8).
The fields of a MantExp
are publicly accessible; I'm undecided whether
it is really better to supply the 3 obvious accessor fns.
The conversion in MantissaAndExponent
is rather slow when the input
number is large.
In principle the call to ILogBase
could fail because of overflow;
but in that case ILogBase
itself should report the problem.
In principle a mantissa overflow could trigger an exponent overflow (i.e. if the exponent was already the largest possible long).
These functions cannot be applied directly to a machine integer; to call
them you have to convert explicitly into a BigInt
(or BigRat
).
2011