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

dedndave

Thanks, Steve
you're right - lol - i was asleep
i missed that first one - the sign bit (which i knew was 0) threw me off for some reason
when i say stupid stuff, ignore me - lol - i am getting old and my mind ain't as sharp as it used to be

dedndave

#31
ok - new day - rethunk - new approach

here is what i am working on, now

1) define constant data for 80-bit reals, values 1.0 and 1.0e+1
2) allocate 3010 bytes heap space and copy the 2 constants into the appropriate locations
3) generate 1.0e+2 to 1.0e+19 by using FPU multiplication
    that gives us 2 decades
    these should be precise with no rounding, in theory
    in fact, they are the only values in the table that will be
4) generate 1.0e+20 to 1.0e+150 using the initial 2 decades
    there are 2 ways this can be accomplished - testing will determine the best approach (first method is prefered)
    a) multiply 1.0e+1 by 1.0e+19 to obtain 1.0e+20
        then multiply the original 2 decades of data by 1.0e+20 to obtain the next 2 decades
        then multiply that resultant decade by 1.0e+20 again to obtain the next 2 decades
        and so on, until the upper half of the table is full
    b) the other approach is to store constants for 1.0e+20, 1.0e+40, 1.0e+60, and so on, up to 1.0e+140
        then use the original 2 decades to create the others
5) once the upper half of the table is complete (and if required, corrections applied),
    use the inverse of those values to generate the lower half of the table
    then, apply corrections to the lower portion, if required

dedndave

#32
here is my current source
i will update it as each section is completed

both attachments moved to July 10th, 2009 09:12:17 PM post

FORTRANS

Hi,

   I threw together a quick and dirty comparison program.
Uses FPU to multiply by ten (FIMUL) and an extended
precision integer routine, with a shift to compare with the
mantissa of the float value.  Just multiplying by tens works
exactly out to 10^27.

F424:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:
0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:

6 4012F424000000000000

CECB:8F27:F420:0F3A:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:
0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:

27 4058CECB8F27F4200F3A


88D8:762B:F324:CD0F:A588:0A69:FB6A:C800:0000:0000:0000:0000:0000:0000:0000:0000:
0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:

50 40A588D8762BF324CD11


9C69:A972:84B5:78D7:FF2A:7604:1453:6EFB:CA75:8CBF:4FBB:7447:65D2:CCCB:79B7:6532:
9A3A:BF23:CE4A:0095:A804:C648:0000:0000:0000:0000:0000:0000:0000:0000:0000:0000:

150 41F19C69A97284B578DA


  FWIW.

   I will try and get the display to make a little more sense,
maybe.

Regards,

Steve N.

dedndave

that may be the way to fly - lol - i am having problems with the simplest of instructions

i want to do this:

        fmul    st,st(1)           ;st(0) * st(1)
        fst  tbyte ptr [edi]       ;store the result

the assembler gives me "invalid operand error 2007" for the fst instruction
trying things out, i changed it to fstp and it assembles and works, sort of - still not what i want

        fmul    st,st(1)           ;st(0) * st(1)
        fstp tbyte ptr [edi]       ;store the result
        fld  tbyte ptr [edi]       ;crazy, huh

that code works, kinda
the values stored in memory always have the last 2 bytes set to 0 (kind of like real8)

how do i store the st(0) value in 80-bit precision without popping it ?

dedndave

ok - having read the intel instruction set reference, i see that fst only stores real4 and real8's
fstp, on the other hand, is supposed to store the extended precision format provided the operand is a tbyte
so my code should work ok as is - i can live with that
now - instead of re-loading the thing, i will make a copy in st(1) first, then store it
maybe that will alleviate my headache - lol

dedndave

#36
ok - got it - appearantly, they are 0's - i let the loop run a few more times and the lower bits fill in
this does not make sense to me because the 80-bit extended real format has a 64-bit mantissa
that means that 18,446,744,073,709,551,615 is the largest value it can hold without rounding
ignoring this point for the time being and moving forward - lol

both attachments moved to July 10th, 2009 09:12:17 PM post
i also modified the program to generate a bin file, rather than looking at the table with a debugger

in a future update, i will probably define the entire table as data, then run a comparison test

jj2007

Hi Dave,
48 bytes that may change your life :wink
Here is the table with the necessary corrections:
  SHL ebx, 1
  .if Carry?
    SHL ebx, 1
    .if Carry?
      fmul 1.0000xxx1
    .else
      fmul 0.9999xxxx
    .endif
  .endif
Only 31 bits are valid, so the next dword must be loaded after 31 shifts.

        01234567890123456789012345678901
dd     00000001000100000011100100010000b
dd     10000000000010010000110000000010b
dd     01011001100100001100000000000000b
dd     10110110000000011000011011110110b
dd     00001110000010000110110000001000b
dd     00000000001101100110000000000000b
dd     00000100000000000011001000000000b
dd     01000010010001010000000001100110b
dd     11010001011011000001110011001100b
dd     00001110001100000000000100100000b
dd     00000100000000001100000100010000b
dd     00001000010000000000000000000000b

dedndave

#38
ok - the upper portion of the table is generated
the last value matches exactly that generated by a masm define
let me create the lower portion

both attachments moved to July 10th, 2009 09:12:17 PM post

dedndave

corrections ? - what corrections - lol

or are you already done with it ?

dedndave

ok - the first value and the last value look good with no corrections
verification time

the d/l in the above post is updated with a version that appears to generate the entire table correctly (at first glance)
now working on comparison tests

a few 1 and 2 lsb errors by comparing files

i don't understand your post, Jochen

jj2007

Quote from: dedndave on July 10, 2009, 08:52:28 PM
corrections ? - what corrections - lol

or are you already done with it ?

Well, kind of - I generated an algo that compares (in REAL10 memory, not FPU) the last bit of the real thing against the last bit of the generated one. If they differ, it sets the current bit in a register, and the next bit to 1 if eax>0 and 0 if eax<0. But I just saw I forgot a tiny little step when the correction does not produce the desired result. Given that I am very tired, and Saturday is booked, you might get the good one only on Sunday. So you still have a chance to catch up, but don't neglect Z!

dedndave

#42
Z told me to go play
over time, i have learned not to argue with her - lol
(her "lappy" is all fixed up - she is having fun online at the moment)

in the upper portion of my table, i have 45 values that need 1 or 2 lsb correction (i.e. +/- 1 or 2)
if those corrections are applied prior to creating the lower portion, it appears it will be generated with no need for correction

before i correct anything, i am going to take a look at a few values and make sure masm is right and i am wrong

EDIT
it does not look like my routine generates the cumulative type errors i might have expected
for example, my value for 1.0e+48 is 1 lsb lower than that generated by masm (this is my frst generated error, btw - 2 thru 47 are good)
that value is used to generate 1.0e+68, 1.0e+88, 1.0e+108, and so on
my generated values for 1.0e+88 and 1.0e+108 match those generated by masm
if i corrected that value as it was generated, it may or may not cause errors down the road - hard to know, really, without trying it

only 3 of my values are off by +/-2 - the other 42 errors are +/- 1 lsb
the type of pattern suggests that masm may be off on some and i may be off on others
if all the errors were mine, i would expect them to propogate into all the values that are based on those first-generated errors

also, the differences are flat 1 or 2 lsb errors
if my routine was generating cumulative errors, they would be become more severe as generation progressed

what all this means is, i have to work harder now, to verify which are correct and which aren't - lol
i have to write a routine that will evaluate the binaries to at least a few digits more than those usable
then, see which table has the value closest to the desired value
i guess i could work it the other way and write a routine that generates the table
to a high degree of accuracy, round those results to nearest, then compare
i think the first method may be easier - lemme think on it

it is interesting to note that my ordinals are pretty good
i use my generated values for 1.0e+20, 1.0e+40, 1.0e+60, 1.0e+80, 1.0e+100, 1.0e+120, and 1.0e+140
to generate the 2-decade group that follows
of all those values, only the last one disagrees with masm (by 1 lsb)

both attachments moved to July 10th, 2009 09:12:17 PM post

dedndave

a simple little change
i got it down to 35 errors in upper portion
all of them are +/- 1 lsb

by the way - i tested a few of the values - masm has the right answers, at least for the ones i tested

both files updated on this post


[attachment deleted by admin]

raymond

FORTRANS summarized it well. Powers of 10 will be exact only in the range of 100-1019 for floats when converted back to decimal. They would however still be exact up to 1027 before conversion to decimal, the 27 trailing bits all being 0 anyway if you write 1027 in binary (90 bits required).

All other powers of 10 will thus loose some relative precision equivalent to at least +/- 2-63 in the REAL10 format. I believe that the best precision with the FPU would be obtainable using the procedure based on log2/antilog2 as suggested in a previous post. That would most probably be the approach used by the assembler when declaring such values in the .data section.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com