Re: First --with-long-double, then _Decimal64!



On 10-11-11 07:40 AM, Morten Welinder wrote:
How many pieces have to be in place to make a --with-Decimal64 option
that works similarly to --with-long-double in configure?

Not many.  Search for GNM_WITH_LONG_DOUBLE
and its counterpart over in goffice.

Thank you.  Once all the pieces are ready, this will be easy to do.


However, ...

1. You are going to need versions of the math functions
    in the C library that works with your type.  sin, cos, sqrt,
    pow, etc.

As per the below, I had imagined that using long-double routines plus
tricks might make a good start, but a closer reading of the code
suggests that I need to have printf() and scanf() support in the C
library before it could be done cleanly.  So I guess this needs to wait
until C library support for decimal conversions is widely available.

2. You need compiler support.  The compiler must do the
    right thing for *, /, +, -, etc.  The compiler must have
    a way of specifying decimal constants of the relevant
    type.  Also, the type cannot need a constructor,
    a destructor, or special assignment handling.

GCC does it all, already.  That part is done.  That's what piqued my
interest in the first place.


Morten

John Harrison's paper shows that in many cases, if you have 80 bit
long doubles, you can just cast your _Decimal64 to long double and pass
it to the existing long double libc function to get accurate results, at
least for transcendentals.

I have actually met John a couple of times.  Without having
read this particular paper of his, I can tell you that he probably
assumes that the C library's long-double functions are accurate
to begin with.  For glibc that just isn't true.  Also, my gut feeling

On i386 architecture machines, the transcendentals are computed in
hardware, so for this particular (lucky?) case, the long-double
functions  get quite close, albeit typically not correctly rounded
because of the need to scale base 2 logs/antilogs and play tricks to
accomodate the ranges of the hardware functions.  The objective in
John's paper is to make Intel machines do fast decimal transcendentals,
and he achieves a "nice" result, albeit not a correctly rounded one.

is that going from exact to long-double to Decimal64 will
occasionally give you the wrong last bit.  For example, if my
memory serves me right, you need something like 119 bits
of log's result before can guarantee correct rounding to plain
old double.  I'm sure John's paper spells this out in all its glory.

This is where you get into a philosophy question:  is it better to do
spreadsheet transcendentals in correctly-rounded binary floating point
libraries and then take the representational error hit when you go back
and forth to decimal representations, or to try to get a decimal
transcendental that is within a couple of ulps and use it directly?
Given that converting decimal user input in a spreadsheet to a double
incurs representational error on the order 2^-53, and given that many
transcendentals amplify this error at certain trouble spots, a naive
decimal transcendental that simply converts to binary and uses an
existing binary library will do no worse in terms of user-input to
user-output total error than the theoretical very best that binary
floating point can do, and any improvements due to high-precision binary
floating point or sophisticated handling of special cases at the decimal
level offer a chance to make things quite a bit better.

On the other hand, correctly rounded decimal transcendentals is what
should ultimately be done, and maybe the best thing to do is wait until
the C libraries do a decent job directly.  (As noted above, until
C-library support for decimals in printf/scanf is more widely available,
it needs to wait anyway so the code does not get cluttered with
conversion spaghetti.)

Thanks for your help.  The GNU C library probably needs more work before
decimal types could be used in Gnumeric, but once that is done, the
addition would be fairly easy.

Jeffrey Streifling



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]