Hello! Please, tell me how to display 80-bit number from the FPU to the console?
As we don't do "requests", show us your code first.
Seeing your code would be nice indeed ;-)
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
fld1
fldl2e
fldl2t
fldlg2
fldln2
fldpi
; with deb macro (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1018):
deb 4, "Debug macro:", ST(0), ST(1), ST(2), ST(3), ST(4), ST(5)
; with ordinary Str$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1167):
Inkey Str$("PI=%Jf", ST(0))
fstp st ; don't forget to clear the FPU
Exit
end start
Output:
Debug macro:
ST(0) 3.14159265358979324
ST(1) 0.693147180559945309
ST(2) 0.301029995663981195
ST(3) 3.32192809488736235
ST(4) 1.44269504088896341
ST(5) 1.00000000000000000
PI=3.141592653589793238
understand the number format
understand base conversion
after that, it's a matter of whether you want it to be fast or not
speed may not be a real issue (pun) :P
Quote from: Mikl__ on March 19, 2013, 10:15:12 PM
Hello! Please, tell me how to display 80-bit number from the FPU to the console?
Hi
convert that 80-bit number to string and print it.
It's not easy to do. you can find a library Math10
here in the forum that do it
QuoteAs we don't do "requests", show us your code first.
; masm windows gui #
.686P
.model flat
include \masm32\include\windows.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\fpulib\fpu.lib
include \masm32\fpulib\fpu.inc
;--------------------------------------------------
.data
result dt ?
szBuffer db 100 dup(0)
.code
start: finit
fldpi
fstp result
invoke FpuFLtoA, ADDR result,40,ADDR szBuffer,SRC1_REAL Or SRC2_DIMM
invoke MessageBox, NULL, addr szBuffer, 0, MB_OK
retn
end start
Hi! function FpuFLtoA from masm32/fpulib displays only 15 digits maximum, and I would like to have 31 as a Windows-calculator
Quote from: Mikl__ on March 20, 2013, 01:23:23 PMHi! function FpuFLtoA from masm32/fpulib displays only 15 digits maximum, and I would like to have 31 as a Windows-calculator
you probably won't find any solution that produce more than 19 or 20 digits, because the 80Bit format does not allow higher precisions (64 precision bits --> lg(2^64) = 19.3 ).
If you really need 31 digits, you must use a high/arbitrary precision library.
qWord is absolutely correct
precision of 31 decimal digits will reguire something in the order of 100 bits binary
you can find 128 bit libraries, usually called big num or arbitrary lib's
i have sometimes wondered how hard it might be to use double-precision FPU calculations, though
we could apply the same techniques we use to extend x86 instructions :P
even then, you might be limited in divisor size
May be exist decompress compress decimal theory and established optimal algorythm?
QuoteTW "000102030405060708090A0B0C0D0E0F", compressdecimaltable
TW "101112131415161718191A1B1C1D1E1F"
TW "202122232425262728292A2B2C2D2E2F"
TW "303132333435363738393A3B3C3D3E3F"
TW "404142434445464748494A4B4C4D4E4F"
TW "505152535455565758595A5B5C5D5E5F"
TW "606162636465666768696A6B6C6D6E6F"
TW "707172737475767778797A7B7C7D7E7F"
TW "808182838485868788898A8B8C8D8E8F"
TW "90919293949596979899";9A9B9C9D9E9F"
..........................................................................
FString db 40 dup(?)
CReg dt ?
..........................................................................
fbstp CReg
lea esi,CReg
lea edi,FString+32
mov ecx, 9
next:
xor eax, eax
lodsb
shl eax, 2
add eax, offset compressdecimaltable
mov eax, dword ptr[eax]
mov dword ptr[edi], eax
sub edi, 4
loop next
invoke MessageBoxW,0,addr FString,0,MB_OK + MB_ICONASTERISK
qWord,
Thanks for the clarification
dedndave,
You are right, lg(2128)=38.531839444989592987358578524735 I could calculate it in advance
bomz,
I would like to discuss it in our native language
Many thanks to all!
http://forum.ru-board.com/topic.cgi?forum=33&bm=1&topic=3174&glp#lt
Quote from: bomz on March 20, 2013, 04:37:20 PM
http://forum.ru-board.com/topic.cgi?forum=33&bm=1&topic=3174&glp#lt
google translate is not very nice :lol:
Quote from: dedndavegoogle translate is not very nice
excuse me for my english
you are ok :t
bomz is scaring me, a little - lol
dedndave,
to me wrote about the Windows-calculator that in it uses its own implementation of long numbers, rather than the standard built-in types.
google translate does a funny job of converting it to English
convert it to English, then convert that back to Russian, and let me know what is says :biggrin:
I think the simplest and quickest
Quotefbstp CReg
lea esi,CReg
lea edi,FString+32
mov ecx, 9
@@:
xor eax, eax
lodsb
shl ax, 4
shr al, 4
add ax, 3030h
mov byte ptr[edi], al
sub edi, 2
mov byte ptr[edi], ah
sub edi, 2
loop @B
;invoke MessageBoxW,0,ADDR FString,ADDR mestitle,MB_ICONASTERISK
mov ecx, 18
lea edi, FString
mov ax, "0"
repe scasw
sub edi, 2
invoke wsprintfW,ADDR buffer,addr form,ecx
invoke MessageBoxW,0,ADDR buffer,ADDR mestitle,MB_ICONASTERISK
invoke MessageBoxW,0,edi,0,MB_OK + MB_ICONASTERISK
When you talking through google translation you need use "special easy language" each native speaker feel it and know how to say
i guess, if i wanted to write a calculator program, i would limit it to 18 decimal digits (or less) :P
real-world calculations rarely need more precision
Hi Mikl__
I did my "The calculator" with 18 digits of precision
We dont need more. You can search this forum and
you can find it. The windows calculator gives 18/19 digits
plus something else we dont know what ...
15 digits is very good !
Try to search Math10 too and read what we did there
Hi, bomz!
I think your decision on a conversion BCD to text is wonderful!; masm windows gui #
.686P
.model flat
include \masm32\include\windows.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
;--------------------------------------------------
.data
result dt ?
szBuffer db 100 dup(0)
ten dq 10.0e+15
compressdecimaltable dw "00","10","20","30","40","50","60","70","80","90",6 dup (0)
dw "01","11","21","31","41","51","61","71","81","91",6 dup (0)
dw "02","12","22","32","42","52","62","72","82","92",6 dup (0)
dw "03","13","23","33","43","53","63","73","83","93",6 dup (0)
dw "04","14","24","34","44","54","64","74","84","94",6 dup (0)
dw "05","15","25","35","45","55","65","75","85","95",6 dup (0)
dw "06","16","26","36","46","56","66","76","86","96",6 dup (0)
dw "07","17","27","37","47","57","67","77","87","97",6 dup (0)
dw "08","18","28","38","48","58","68","78","88","98",6 dup (0)
dw "09","19","29","39","49","59","69","79","89","99"
.code
start: finit
fldpi
fmul ten
fbstp result
lea esi,result
lea edi,szBuffer+16
mov ecx, 9
next: xor eax, eax
lodsb
mov eax,dword ptr compressdecimaltable[eax*2]
mov word ptr[edi],ax
sub edi,2
loop next
invoke MessageBox, NULL, addr szBuffer, 0, MB_OK
retn
end start
It's original (oddball). but not optimal. two sh* x 4 operation much faster even old processors than table reading from memory
Quote.386
.model flat, stdcall
option casemap :none
include \MASM32\INCLUDE\windows.inc
include \MASM32\INCLUDE\user32.inc
include \MASM32\INCLUDE\kernel32.inc
includelib \MASM32\LIB\user32.lib
includelib \MASM32\LIB\kernel32.lib
.data
mestitle db "Bomz",0
realform db "%u.%010hu", 0
decimalplaces INT64 10000000000
;value REAL8 0.00001
value REAL10 1.00001
.data?
buffer db 512 dup(?)
realint dd ?
realfract dd ?
.code
start:
finit
fldpi
;fld value
fist realint
fisub realint
fild decimalplaces
fmul
fistp realfract
invoke wsprintf,addr buffer,addr realform,realint,realfract
invoke MessageBox,0,addr buffer,addr mestitle,MB_ICONASTERISK
invoke ExitProcess,0
end start
bomz,
wrong suggestions won't get correct by repeating them.
prove it (http://smiles.kolobok.us/light_skin/blum3.gif)
Quote.386
.model flat, stdcall
option casemap :none
include \MASM32\INCLUDE\windows.inc
include \MASM32\INCLUDE\user32.inc
include \MASM32\INCLUDE\kernel32.inc
include \MASM32\INCLUDE\ntdll.inc
include \masm32\macros\Strings.mac
.data
TW0 "Bomz",mestitle
TW0 "%u.", realform
decimalplaces INT64 1000000000000000000
value REAL10 0.000000000000000001
.data?
String db 512 dup(?)
Buffer db 512 dup(?)
CompressDec dt ?
realint dd ?
;;;;TABFLAG dd ?
.code
start:
finit
fldpi
;;;;fld value
fist realint
invoke wsprintfW,addr Buffer,addr realform,realint
fisub realint
fild decimalplaces
fmul
call compressdecimal2string
invoke MessageBoxW,0,addr Buffer,ADDR mestitle,MB_ICONASTERISK
invoke ExitProcess,0
;===================================
compressdecimal2string:
mov edx, esi
fbstp CompressDec
lea esi,CompressDec
lea edi,String+34
mov dword ptr [edi], 0
mov ecx, 9
@@:
xor eax, eax
lodsb
shl ax, 4
shr al, 4
add ax, 3030h
mov byte ptr[edi], al
sub edi, 2
mov byte ptr[edi], ah
sub edi, 2
loop @B
mov esi, edx
invoke wcscat, addr Buffer, addr String
ret
; ==
end start
(http://s017.radikal.ru/i422/1303/2f/b13bf4d78880.png)
Quote3,1415926535897932384626433832795
the range for intel 80-bit extended reals is approx:
normal
-1.1897E+4932 to -3.3621E-4932, 0, +3.3621E-4932 to +1.1897E+4932
denormal
-1.1897E+4932 to -1.8225E-4951, 0, +1.8225E-4951 to +1.1897E+4932
you can't plug 1 value in, pi, and call that a test :P
For my purpose I need only 2 sign after , to convert volume size in bytes (from 1 mb to 2 terabyte) to gigabyte.
(http://s017.radikal.ru/i443/1303/cd/e971e85d031c.png)
(http://s47.radikal.ru/i118/1303/1a/e03ac11d44b5.png)
Quote from: bomz on March 26, 2013, 01:53:05 PM
For my purpose I need only 2 sign after
that's funny - so bomz and Mikl__ are the same person?
thats funny conducted online psychiatric clinics
In russian says: "2 sign after ," I don't know hot it's say in english because i learn mathematics in russian
Quote from: qWordthat's funny - so bomz and Mikl__ are the same person?
qWord,
You are mistaken ....
bomz is on this forum for a long time, and I asked only one question
; masm windows gui #
.686
.model flat
.mmx
include windows.inc
includelib user32.lib
includelib kernel32.lib
extern _imp__MessageBoxA@16:dword
extern _imp__ExitProcess@4:dword
.code
start: finit
mov edi,offset buffer
fld x
fxam
fstsw ax ;stores the current value of the FPU control word at AX
and eax,4700h ;extract bits c3, c2, c1, c0 of the FPU control word
shr eax,3
shr ah,3
shr eax,3
jmp table[eax]
a2: fabs
mov al,'-'
stosb
a1:; get the size of the number
fldlg2 ;st(0)=lg(2)
fld st(1);copy Src
fyl2x ;st(0)=lg(x)
fldcw truncw ;insure rounding code of FPU to truncating
fist esize ;store characteristic of logarithm
fldcw oldcw ;load back the former control word
ftst ;test logarithm for its sign
fstsw ax ;get result
sahf ;transfer to CPU flags
sbb esize,0 ;decrement esize if log is negative
fstp st(0) ;get rid of the logarithm
mov eax,15 ;a maximum of 15 decimals is allowed
sub eax,esize
mov tempdw,eax
;----------------------------------------
; multiply the number by the power of 10 to generate required
; integer and store it as BCD
;-------------------------------------------------------------
test eax,eax
jz @f;if tempdw != 0
fild tempdw
fld ten
fyl2x ;log2(10)*tempdw
;the FPU can compute the antilog only with the mantissa
;the characteristic of the logarithm must thus be removed
fld st ;copy the logarithm
frndint ;keep only the characteristic
fsub st(1),st;keeps only the mantissa
fxch ;st(0) <--> st(1)
f2xm1 ;st(0)=2^(mantissa)-1
fld1
fadd
;the number must now be readjusted for the characteristic of the logarithm
fscale ;scale it with the characteristic
fstp st(1);get rid of the characteristic of the log
fmul
;------------------------------------------------
@@: push edi
mov edi,offset unpacked
fld st
fbstp bcdstr ;->TBYTE containing the packed digits
fbld bcdstr
fsubp st(1),st
fmul thousand
fldcw tmp ;round up
frndint
fmul ten
fbstp y;fractional part
;------- BCD -> ASCII-string --------------------
mov al,byte ptr bcdstr+8
or al,'0'
stosb ;BCD -> ASCII-string 1 decimal digit
movq mm0,qword ptr bcdstr
movq mm1,mm0
push 0F0F0F0Fh
push 0F0F0F0Fh
pand mm0,qword ptr [esp]
movq mm2,mm0
push 0
push 4
psrlq mm1,qword ptr [esp]
pand mm1,qword ptr [esp+8]
punpckhbw mm0,mm1
por mm0,mask2
movq [esp],mm0
pop ecx
pop eax
bswap eax
add esp,8
bswap ecx
stosd ;BCD -> ASCII-string 4 decimal digits
mov eax,ecx
stosd ;BCD -> ASCII-string 4 decimal digits
punpcklbw mm2,mm1
por mm2,mask2
movq qword ptr bcdstr,mm2
mov eax,dword ptr bcdstr+4
bswap eax
stosd ;BCD -> ASCII-string 4 decimal digits
mov eax,dword ptr bcdstr
bswap eax
stosd ;BCD -> ASCII-string 4 decimal digits
call routine ;BCD -> ASCII-string 4 decimal digits
pop edi
;------------------------------------------------
mov esi,offset unpacked+1
cmp byte ptr[esi-1],"1"
jnz @f
lea esi,[esi-1]
@@: lodsb
mov ah,"."
stosw ;copy the integer and pointer
movq mm0,[esi]
movq [edi],mm0
movq mm0,[esi+8]
movq [edi+8],mm0
lea edi,[edi+16]
lea esi,[esi+16]
movsw ;copy 18 decimal digits
jnz @f ;no extra "1"
inc esize ;adjust exponent
@@: mov edx,esize
mov eax,"+E" ;"E+" -> ASCII-string
sar edx,31
and edx,200h
add eax,edx ;"E-" -> ASCII-string
stosw ;insert proper sign
;Note: the absolute value of the size could not exceed 4931
finit
fild esize
fabs ;make number positive
fbstp y
call routine
xor eax,eax
stosb ;0-terminator -> ASCII-string
mov edi,offset buffer
jmp @f
a0: mov edi,tablemsg[eax]
@@: push MB_OK
push offset wTitle
push edi;offset buffer
push 0
call _imp__MessageBoxA@16
push 0
call _imp__ExitProcess@4
;---------------------------------------
routine proc
movq mm0,qword ptr y
movq mm1,mm0
push 0F0F0F0Fh
push 0F0F0F0Fh
pand mm0,qword ptr [esp];mask1
push 0
push 4
psrlq mm1,qword ptr [esp]
pand mm1,qword ptr [esp+8];mask=0F0F0F0F0F0F0F0F
punpcklbw mm0,mm1
por mm0,mask2
movq [esp],mm0
pop eax
bswap eax
stosd ;BCD -> ASCII-string 4 decimal digits
add esp,12
ret
routine endp
;--------------------------------------
.data
tmp dw 0FBFFh
mask2 dq 3030303030303030h
oldcw dw 037Fh
truncw dw 0F7Fh
bcdstr dt ?
esize dd ?
tempdw dd ?
y dt ?
x dt 0.69314718055994530941;723212145818
thousand dq 1000.0
ten dq 10.0
unpacked db 30 dup(0)
wTitle db '0,69314718055994530941723212145818',0
buffer db 40 dup(0)
pinf db "+ INFINITY",0
ninf db "- INFINITY",0
empty db "Empty",0
pnan db "+ NaN",0
nnan db "- NaN",0
pzero db "+ 0.0",0
nzero db "- 0.0",0
pdnnum db "+ Denormal number",0
ndnnum db "- Denormal number",0
pnnnum db "+ Unsupported",0
nnnnum db "- Unsupported",0
table dd a0,a0,a0,a0,a1,a0,a2,a0,a0,a0,a0,a0,a0,a0,a0,a0
tablemsg dd pnnnum,pnan,nnnnum,nnan,0,pinf,0,ninf,pzero,empty,nzero,\
empty,pdnnum,empty,ndnnum,empty
end start
Please, test it!
Easy method with sprintf_s (msvcr100.dll)
Perfect for me.
There are 19 decimal digits in my program
Quote from: Mikl__ on April 08, 2013, 03:28:30 PM
There are 19 decimal digits in my program
Str$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1167) - good for 18.9 digits ;-)
Point is, there is an output limit imposed by the signed QWORD:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
.data
MyQ1 dq 1234567890123456789
MyQ2 dq 9222567890123456789
MyQ3 dq 9223567890123456789
Init
Print Str$("Q1=%Jf\n", MyQ1)
Print Str$("Q2=%Jf\n", MyQ2)
Inkey Str$("Q3=%Jf\n", MyQ3)
Exit
end start
Q1=1234567890123456789.0
Q2=9222567890123456789.0
Q3=-9223176183586094827.0
That is, numbers starting with 9.22 and less can be displayed with 19 digits precision, numbers starting with 9.23 only with 18 digits.
Mikl,
i would have to say, for someone new to assembler, that is a wonderful job :t
the code is a bit long and mangled, but it seems to work :P
i made some changes, just to make it easier to read and understand
the biggest changes:
include \masm32\include\masm32rt.inc
.686p
.MMX
.XMM
;
;
;
@@: INVOKE MessageBox,0,edi,offset wTitle,MB_OK
INVOKE ExitProcess,0
Quote from: jj2007 on April 08, 2013, 03:46:15 PM
That is, numbers starting with 9.22 and less can be displayed with
19 digits precision, numbers starting with 9.23 only with 18 digits.
i don't agree with that, at all - lol
in fact, i was reading a paper, the other day
it said that it was valid to return 21 digits, even though they may not all be mathematically usable
it would ensure that bin->decimal->bin yields the same result as the original binary value
Quote from: dedndave on April 08, 2013, 11:38:00 PM
Quote from: jj2007 on April 08, 2013, 03:46:15 PM
That is, numbers starting with 9.22 and less can be displayed with
19 digits precision, numbers starting with 9.23 only with 18 digits.
i don't agree with that, at all - lol
in fact, i was reading a paper, the other day
it said that it was valid to return 21 digits, even though they may not all be mathematically usable
it would ensure that bin->decimal->bin yields the same result as the original binary value
:biggrin:
Dave,
I solved this problem some time ago
and it seems to me now that Jochen is right.
Dave, try to write a converter and you get the problem.
Yes,
we use only FPU and qword converters. :t
note: from raymond docs:
QWORD range ±(263-1) or ±
9223372036854775807
Quote from: Mikl__ on April 08, 2013, 03:28:30 PM
There are 19 decimal digits in my program
:biggrin:
Hi Mikl__
19 decimal digits are not 19 integer digits.
But if you want to print numbers like
-9123456789012345678.12345678901234...
divide it in integer part and decimal part
convert each and at the and put it together.
Did you understand ? It's math it's simple
here is that paper i was reading that mentioned 21 decimal digits...
http://www.cs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF (http://www.cs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF)
Well, it does mention 18-21 digits for extended double, i.e. 10+ bytes...
someplace, i saw accompaning text that referenced that article
i was trying to find it again, but at least i found the PDF - lol
Quote from: dedndave on April 09, 2013, 03:58:00 AM
here is that paper i was reading that mentioned 21 decimal digits...
http://www.cs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF (http://www.cs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF)
It is good to know this but the problem is how to implement it.
21 decimal digits may be this: 0.000000111110123456780 ? ;)
implement it the same as you did 18 or 19, except.....
..... it's 21
:lol:
i may want to do some calculation and testing to verify this value :t
Hi Dave,
Quote from: dedndave on April 09, 2013, 03:58:00 AM
here is that paper i was reading that mentioned 21 decimal digits...
http://www.cs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF (http://www.cs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF)
very interesting paper by Prof. Kahan, the father of floating point. :t
Gunther
Quote from: dedndave on April 09, 2013, 05:16:28 AM
i may want to do some calculation and testing to verify this value :t
:biggrin:
yes, i wait for your result, Dave
calculating the number of digits required is simple enough
but, the number required to go from bin to decimal to bin is a little different story :redface:
Tell me - what I can replace slow FBSTP?
SSE. But I think that modern processors emulate FPU with SSE registers
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
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.
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
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
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:
(http://img801.imageshack.us/img801/9459/fpureal10.png)
Dave,
thank you for your research. Indeed, there are discrepancies,
Gunther
the numbers, i can figure out
but, i found the number of digits interesting :P
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
(http://img838.imageshack.us/img838/9816/real10.gif)
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
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
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