News:

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

float$ macro and algo for testing

Started by jj2007, August 26, 2008, 03:48:53 PM

Previous topic - Next topic

dedndave

#45
if this is the value from the fpu fldpi instruction:
Quote35 c2 68 21 a2 da 0f c9 00 40

then these should be correct
Pi_80   label   tbyte
        db      35h,0C2h,68h,21h,0A2h,0DAh,0Fh,0C9h,0,40h

Pi_64   label   qword
        db      69h,21h,0A2h,0DAh,0Fh,0C9h,0,40h

Pi_32   label   dword
        db      10h,0C9h,0,40h

jj2007

Quote from: MichaelW on July 06, 2009, 04:46:46 PM
Perhaps Olly can do better.

Marginally - I get 370, 380, 380, 400, 400, 410, 420 for increments of 4 of the lowest byte of MyPI10.
I must admit I am a bit confused - I always thought that REAL10 and FPU use the same precision, and therefore had assumed that incrementing the lowbyte would result in a change of respective ST(n)...
3.141592653589793238 is 19 digits

dedndave

well - that tells me the float to string routine has a problem
although, you can't expect perfection because the float format is base2 and the ascii string is base10
whenever you perform a base conversion, there are going to be rounding errors, however small
if the string routine returned a few more digits, you might see a more linear pattern
but, those digits are really meaningless, as they represent a value less than +/- 1/2 LSB of the float
that is why 80 bits are generally used for calculations, but are not really intended for display

EDIT:
there is no reason you couldn't write a test routine that performs the conversion with, say, 88 bits
that would let you see the effect of stepping one LSB with more resolution
in fact, 96 bits would be easy enough - speed is not an issue

jj2007

Quote from: dedndave on July 06, 2009, 05:24:50 PM
well - that tells me the float to string routine has a problem
The values are from Olly's display, and they have the 19 digits that are theoretically possible.

Quote
that is why 80 bits are generally used for calculations, but are not really intended for display

The 80 bits of the Real10 format refers to a 64-bit mantissa - and a max of 19.5 digits is possible. This is why I do not understand why fumbling with the lowest byte does not change the display in Olly.

dedndave

here is a simpler way, perhaps...
it might be interesting to see the result if you stripped the exponent and sign bits from the 80-bit value
then, display the remaining 64-bit value as an unsigned integer using one of the reliable routines we were playing with in the other thread

EDIT:
one little flaw, here
due to the implied leading 1 of the float format, a 64-bit mantissa is actually a 65 bit value
but, that could be ignored if you are only looking for the LSB delta
of course, you will see a delta of 1, but you get the idea

dedndave

QuoteThe values are from Olly's display, and they have the 19 digits that are theoretically possible.
there are more digits there because the true binary value is a much longer number
they simply have little meaning because they are beyond the represented precision (i.e. less than +/- 1/2 LSB)
because of this fact, display routines do not show them
that does not mean you cannot examine those digits for test purposes

MichaelW

Near the ends of the range the representable values are further apart.

Incrementing the low-order byte alone will not work correctly when the operation generates a carry.

For the REAL10 format the 1 in the first bit is stored, so the significand is 64 bits.

eschew obfuscation

dedndave

ahhhh - ty Michael
so - it is easy to show the true binary value, and simply ignore the decimal placement and sign

MichaelW

Same idea for a REAL4, with the representable values displayed as a REAL8.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
      r8  REAL8 0.0
      r4 REAL4 0.0
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    fldpi
    fstp r4
    sub DWORD PTR r4, 10
    mov ebx, 21
    mov esi, -10
    .WHILE ebx
      inc DWORD PTR r4
      fld r4
      fstp r8
      invoke crt_printf, chr$("%d",9,"%.17f",10), esi, r8
      dec ebx
      inc esi
    .ENDW

    inkey "Press any key to exit..."
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


-10     3.14159059524536130
-9      3.14159083366394040
-8      3.14159107208251950
-7      3.14159131050109860
-6      3.14159154891967770
-5      3.14159178733825680
-4      3.14159202575683590
-3      3.14159226417541500
-2      3.14159250259399410
-1      3.14159274101257320
0       3.14159297943115230
1       3.14159321784973140
2       3.14159345626831050
3       3.14159369468688960
4       3.14159393310546870
5       3.14159417152404790
6       3.14159440994262700
7       3.14159464836120610
8       3.14159488677978520
9       3.14159512519836430
10      3.14159536361694340

eschew obfuscation

dedndave

#54
here is the result i got - 20 usable digits

0C90FDAA22168C235h / 2^62 = 3.1415926535897932385

              Pi is roughly 3.1415926535897932384626433832795


of course, if i were to draw a circle with a compass and try to measure its' circumference, it would have to be precisely drawn
and i would have to use extremely fine measurement techniques to measure it with 7 usable digits of accuracy
5 digits would be more practical in day-to-day use
i would be doing well to measure Pi at 3.1416, in fact - lol
i think my good buddy Archimedes calculated it to 6 places or something like that
oops - i looked it up - Archie only got to 3.1418 - still, not bad for 250 b.c.
i find this a little disappointing, though - i thought he did better
imagine what he could have done with a pentium pc - lol (without pi already in it, of course)
the OS would be named Eureka instead of windows
and we would be getting our updates from a vaccuum cleaner manufacturer

dedndave

0C90FDAA22168C234h / 2^62 = 3.1415926535897932383 (Pi-1 lsb)
0C90FDAA22168C235h / 2^62 = 3.1415926535897932385 (Pi)
0C90FDAA22168C236h / 2^62 = 3.1415926535897932387 (Pi+1 lsb)
                   actual value of Pi = 3.14159265358979323846

dedndave

oh - btw
my short and long real values are incorrect, as i forgot about the 80 bit leading 1 not being implied

let's see if i can do this without screwing it up - lol

Pi_80   label   tbyte
        db      35h,0C2h,68h,21h,0A2h,0DAh,0Fh,0C9h,0,40h

Pi_64   label   qword
        db      18h,2Dh,44h,54h,0FBh,21h,9,40h

Pi_32   label   dword
        db      0DBh,0Fh,49h,40h

MichaelW

I had another go at this using the Digital Mars compiler version 8.50 from here. Unlike the Microsoft compilers, GCC, and I think probably many others, under Windows the DM RTL apparently does not use MSVCRT. Using my previous TC 3.0 source changing only the precision value from 19 to 20 I get an EXE that produces these results:

3.14159265358979323846
3.14159265358979323850
3.14159265358979323850
3.14159265358979311590


One of my goals here was to find a RTL that supports an 80-bit long double and that I could link with a MASM app. Unfortunately, the DM libraries appear to be incompatible with the Microsoft linker.
eschew obfuscation

ToutEnMasm


Searching for precision of rounded values seems to be a  vast subject.
The mapm libraries (free) seems to offers valuable source codes and documentation.
Quote
http://www.mpfr.org/

jj2007

Quote from: MichaelW on July 07, 2009, 04:39:00 AMI get an EXE that produces these results:

3.14159265358979323846
3.14159265358979323850


I am stuck at 3.141592653589793239 using print Str$("\nPI=\t%Jf", MyPI) :bg