News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Multiplier table

Started by jj2007, July 09, 2009, 10:50:41 AM

Previous topic - Next topic

jj2007

Quote from: dedndave on July 09, 2009, 07:03:45 PM
1.0 expressed as a real is precise

Yes, but after 2 or three multiplications/divisions it is no longer precise...

dedndave

yes - but that will get rid of a large part of the errors - i know it will make a vast improvement on your current routine
next, we need to construct the reals ourselves - i am working on a routine

dedndave

here is the 3010 byte table generated by masm
we can use it as a reference to test against - not sure how precise even that is, though
i would be more inclined to believe my table

[attachment deleted by admin]

jj2007

Will check asap. My last hope was Raymond's lib, but FpuAtoFL yields 1.0000000000000000127E-100 :(

FORTRANS

Hi,

  Well multiplies should be okay from 1 to whenever the mantissa overflows.
There is a mild problem with the numbers less than 1 though, 1/10 does
not have an exact representation in binary.  Five is relatively prime with
respect to two.


0000:0000:0000:0000:0000:0000:0000:0000■0000:0010:1000:1111:0101:1100:0010:1001

0000:0000■028F:5C29

0000000000.01000000000931322574615478515625


Regards,

Steve N.

Jimg

The guts of this are from raymonds fpulib

.data?
tempex dd ?
ansx real10 301 dup (?)
.code
    mov tempex,-150
    lea edi,ansx
    finit
    .repeat   
      fild  tempex     ; start of Raymonds code
      fldl2t
      fmul                    ;->log2(10)*exponent
      fld   st(0)
      frndint                 ;get the characteristic of the log
      fxch
      fsub st,st(1)           ;get only the fractional part but keep the characteristic
      f2xm1                   ;->2^(fractional part)-1
      fld1
      fadd                    ;add 1 back
      fscale                  ;re-adjust the exponent part of the REAL number
      fstp  st(1)             ;get rid of the characteristic of the log
      fstp real10 ptr [edi]  ;end of raymonds code
      add edi,10
      inc tempex
    .until sdword ptr tempex>150

jj2007

Quote from: Jimg on July 09, 2009, 07:59:33 PM
The guts of this are from raymonds fpulib


Thanks, Jim, but even this one is inexact: 9.9999999999999999500E+54
My current precision is stuck at the very last digit...

dedndave

that looks more like a float2str problem - i.e. your real may be correct

jj2007

Quote from: dedndave on July 09, 2009, 08:13:37 PM
that looks more like a float2str problem - i.e. your real may be correct

Copied from Olly...

dedndave

lol - the assembler generated a NAN for 1.0e+0

EDIT
i must be reading it wrong
3FFF8000000000000000
the sign bit is 0
the 15 exponent bits are 1's
i thought that was a NAN
the mantissa is right

Mark Jones

IIRC, representing each decade exactly (or a multiplier table thereof) is impossible because the mantissa would need many more bits to represent all the possible values. As the value increases in magnitude from zero, the granularity increases, which in turn decreases the likelihood of "landing on" any particular standard exact integer. This curve itself would be non-linear, unsure what it is exactly, possibly a bell curve.

The link below hosts a conversion tool to tinker with several float types. Using the IEEE754 32-bit schema, it is easy to see that encoding increasing 1.0 decades causes more mantissa bits to be used, and at some point (1.0e10 == 9999998976), decade values cannot be represented exactly any longer.

http://www.piclist.com/techref/microchip/math/fpconvert.htm

One idea could be to delta-encode the difference, and account for that somehow. Or just do things the "hard way," with a huge BCD and sign bit. Zero error in that.

http://steve.hollasch.net/cgindex/coding/ieeefloat.html
http://msdn.microsoft.com/en-us/library/0b34tf65.aspx
http://www.cs.grinnell.edu/~stone/courses/fundamentals/IEEE-reals.html
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

dedndave

#26
well - going up from 1.0, you are good up to 1.0e+19
all those should be precise
after that, small errors begin to accumulate
this is because you shift bits off the right end and increment the exponent
once the MSB 1 is in bit 63, you stop shifting
then, you use the carry flag to round the LSB - this is the error that accumulates
by retaining the right-shifted bits for the next successive multiplication, you can eliminate the errors
i am working on a routine right now to generate the upper portion of the table without rounding errors
i am using shl/add to multiply by 10, but it may be simpler to use multiple-precision mul's
speed is not really an issue here
well - except for how fast i can write it - lol
Zara comes first - so i work on it when she is sleeping

jj2007

Quote from: Mark Jones on July 10, 2009, 12:25:29 AM
One idea could be to delta-encode the difference, and account for that somehow.
Quote
I tried that already, hoping to find some kind of regular pattern, e.g. one up each ten numbers, but nope. 300 numbers with bit-encoded corrections means roughly 10 doubles or 40 bytes, which would be more acceptable than 3k, of course.

Or just do things the "hard way," with a huge BCD and sign bit. Zero error in that.

Since speed is not an issue, this could be interesting (how would 1.0e-150 look in BCD??)
Thanks, Mark & Dave :thumbu

dedndave

#28
in packed BCD, it would be 75 bytes long, mostly 0's, with a 1 in the low nybble of the last byte
in binary, it is a little shorter - oops - when you divide they all have lost bits
1 is 1 bit long
10 is 4 bits (add 3)
100 is 7 bits (add 3)
1000 is 10 bits (add 3)
10000 is 14 bits (add 4)

notice the 3,3,3,4 pattern - my theory is that, at some point it is 4,3,3,3,4,3,3,4,3,3,3,4 (a 3 gets dropped)
that's only a guess, though - i have been wanting to see what that pattern is - maybe 150 is enough to see the hiccup
the length is important to know because, by keeping track, you know how many bytes require shift/add during mul by 10
you can speed up the shl/add mul by 10 procedure by only shifting bytes needed
with packed BCD, it is always 4, of course

FORTRANS

Quote from: dedndave on July 09, 2009, 09:19:20 PM
lol - the assembler generated a NAN for 1.0e+0

EDIT
i must be reading it wrong
3FFF8000000000000000
the sign bit is 0
the 15 exponent bits are 1's
i thought that was a NAN
the mantissa is right

   Let's see:  2 bits for the three, four bits for each F, you
want to add a bunch of even numbers to get an odd number...
To paraphrase the movie; "I'm sorry Dave, I can't do that".
14 of the 15 exponent bits are 1's.

Cheers,

Steve N.