News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

output 80-bits number from the FPU to the console

Started by Mikl__, March 19, 2013, 10:15:12 PM

Previous topic - Next topic

Mikl__


bomz

SSE. But I think that modern processors emulate FPU with SSE registers

Gunther

Hi bomz,

Quote from: bomz on April 10, 2013, 10:21:52 PM
SSE. But I think that modern processors emulate FPU with SSE registers

Probably not. SSE code is the new kid in town.

Gunther
You have to know the facts before you can distort them.

FORTRANS

Quote from: Mikl__ on April 10, 2013, 08:03:06 PM
Tell me - what I can replace slow FBSTP?

Hi,

   You can store the number as an integer and do the conversion
to BCD yourself.  But, that is not likely to be faster.

Regards,

Steve N.

RuiLoureiro

Quote from: Mikl__ on April 10, 2013, 08:03:06 PM
Tell me - what I can replace slow FBSTP?
Mikl__
          I dont know if it is slow or not ... but i am trying to help you
          Multiply the number X by 10^N in such a way that you
          go to get, for instance, 19 integers.
          Then, i did this

                    ; ------------------------------------------------------
                    ; fistp rounds the value in ST(0) to the nearest integer
                    ; ------------------------------------------------------
        _GoInteger0:fistp   qword ptr QWinteger   
                             fstsw   ax
                             fwait
                             shr     ax, 1
                             jc      _erro2                  ; go here again to 18 digits ...                     

        _GoInteger: lea     esi, buffer+21
                            lea     edx, QWinteger   
                            invoke  QwordDecCnv, edx, esi   ; convert qword put in buffer

                    ...
        now you should think and you get the right way. I did this some time ago.
        You may decide if you want sci or regular notation ... etc.
        Note that we give the address of the last byte (buffer+21)! QwordDecCnv
        gives you how many bytes in the buffer in ecx
       

Mikl__

This is test-program for calculation sqrt(2.0)
; masm windows gui #
.686
.model flat
.mmx
include windows.inc
include \masm32\include\masm32rt.inc
magic equ 4D10h
.data
x dt ?
step dd ?
string db 60 dup (0)
wTitle db "1.4142135623730950488016887242097",0
ten9 dd 1000000000
ten dd 10
.code
start: finit
fld1 ; st(0)=1
fld st ; st(0)=st(1)=1
fadd ; st(0)=2.0
fsqrt; st(0)=sqrt(2.0)
fstp x; x=1.4142135623730950488016887242097 from Windows-calc
        mov edi,offset string; output buffer
movzx eax,word ptr x+8; sign & exponent
        sub eax,16382
mov ecx,eax
imul eax,magic
shr eax,16
mov step,eax
xor eax,eax
        mov edx,dword ptr x
mov ebx,dword ptr x+4
shld eax,ebx,cl; integer part
shld dword ptr x+4,edx,cl
shl dword ptr x,cl
mov ebx,'0000'
        or eax,'.0'
stosw; integer part and point
        mov eax,dword ptr x+4
mov ecx,9; first 9 digits
@@: mul ten
mov [edi],dl
inc edi
loop @b
or [edi-9],ebx
or [edi-5],ebx
mov esi,eax
mov eax,dword ptr x
mul ten9
add edx,esi
mov esi,eax
mov eax,edx
mov ecx,9; second 9 digits
@@: mul ten
mov [edi],dl
inc edi
loop @b
or [edi-10],ebx
or [edi-6],ebx
mov edx,eax
mov eax,esi
mov esi,edx
mul ten9
add edx,esi
mov eax,edx
mul ten
mov [edi],dl ;19-th digit
or [edi-3],ebx
mov edi,offset string
mov eax,step
aam
or eax,'00'
bswap eax
mov ax,'+E'
mov dword ptr [edi+21],eax
a0: invoke MessageBoxA,0,edi,offset wTitle,MB_OK
invoke ExitProcess,0
end start

dedndave

the other day, we were talking about the number of meaningful decimal digits   :biggrin:

i was browsing some PDF's, looking at the real10 format
i noticed a couple discrepancies between 2 different documents

notice the decimal values - they don't match   :icon_eek:
my first thought was, "ok - so they didn't use the same code to evaluate the numbers - big deal"
then, i noticed that they both use 21 decimal digits   :biggrin:


Gunther

Dave,

thank you for your research. Indeed, there are  discrepancies,

Gunther

You have to know the facts before you can distort them.

dedndave

the numbers, i can figure out
but, i found the number of digits interesting   :P

dedndave

here are the values my code returns
the last one seems to be in error
which is where i am at - trying to figure out how it properly evaluates the min denormal, but not the max denormal
it may be possible that my code is correct, and their numbers are not - lol

0001_80000000_00000000: 3.36210314311209350626E-4932, min pos normal
7FFE_FFFFFFFF_FFFFFFFF: 1.18973149535723176502E+4932, max pos normal

0000_00000000_00000001: 1.82259976594123730126E-4951, min pos denormal
0000_7FFFFFFF_FFFFFFFF: 1.68105157155604675294E-4932, max pos denormal




EDIT: by the way, the "real" max pos denormal isn't 0000_7FFFFFFF_FFFFFFFF
the 80387 and later will not return values from 0000_80000000_00000000 to 0000_FFFFFFFF_FFFFFFFF
these are called "pseudo-denormals", and it should properly evaluate them

dedndave

ok - made a correction in my code
now, the max positive denormal matches
the min positive denormal does not, of course - lol

0001_80000000_00000000: 3.36210314311209350626E-4932, min pos normal
7FFE_FFFFFFFF_FFFFFFFF: 1.18973149535723176502E+4932, max pos normal

0000_00000000_00000001: 3.64519953188247460253E-4951, min pos denormal
0000_7FFFFFFF_FFFFFFFF: 3.3621031431120935059E-4932, max pos denormal

0000_80000000_00000000: 3.36210314311209350626E-4932, min pos pseudo-denormal
0000_FFFFFFFF_FFFFFFFF: 6.72420628622418701216E-4932, max pos pseudo-denormal

dedndave

i was just playing with my real number evaluation code

i figured out that i can shift the binary part of the real left n times, then use my ling long kai fang routine to get the decimal digits
n = exponent - bias + fractionAdjust
that works great for values that need to be multiplied (exponent > (bias+fractionAdjust))
for exponent = (bias+fractionAdjust), no need to shift, at all

so, i am working along on the small values where exponent < (bias+fractionAdjust)
when i have a value like 3.645e-4951 (with many more digits),
it is a little harder to convert a binary with bits to the right of the radix - lol
i figure - ok, i can multiply by 10^n, then convert to decimal, right
oh - we also have to divide by 2^n, first

why not just multiply by 5^n ???? - lol
i can use my ling long kai fang exponential routine

let me try it out........
5^16445         Exponential Integer Size: 4774 Bytes
3.6451995318824746025284059336194198163990508156935633437209804870283716e+11494

the smallest denormal REAL10 is 3.6451995318824746025284059336194198163990508e-4951
i'll be danged - it works - lol
all i have to do is adjust the decimal exponent   :biggrin:

now, i just have to figure out how to multiple-precision multiply really big values   :P