Hi all,
. Sometimes some friends here ask me
where is the
ASM file. (Hi Dave ! Hi qWord !)
. Well, in this post i give
ConvertString4D.inc which contains the ASM
ConvertString4D procedure,
constants and macros, and a
text file Converter4.txt where i explain something about that. (
See Converter4.zip below)
. ConvertString4D procedure is a proc that converts
a null terminated string into a real4 dword variable.
The string may be written like this one:
"-123.4567E-1" or the same as " - 000 1 2 3 . 45 67 E - 0001"
It takes
119 cycles more or less in my P4.
(qWord, in your i7 119 may give 40, no ?)
.
TestCnvDD9.exe shows conversions of 10 strings
by all converters
. Please, could you run
TestCnvDD10.exe and show the results here ?
Thanks
Rui
NOTE: ConvertString4Y0 doesnt convert a string like this:
"- 123" or "-001236789" or "-1.234 E5" (
spaces and more than 8 integers)
About each converter
--------------------
load stack intermediate save conversion
access buffer FPU & CPU method obs.
------------------------------------------------------------------------------
1 ConvertString4BZ 1 byte ebp yes no BCD (1,3)
2 ConvertString4BX 1 byte ebp yes yes BCD (1,3)
3 ConvertString4BY 1 byte esp yes no BCD (1,3)
4 ConvertString4B 1 byte esp yes yes BCD (1,3)
5 ConvertString4BW 1 byte ebp no no BCD (1,3)
6 ConvertString4BF 1 byte esp no no BCD (1,3)
-------------------------------------------------------------------------------
7 ConvertString4Y0 1 byte ebp no no direct (1)
8 ConvertString4Y 1 byte ebp no no direct (2)
9 ConvertString4YM 1 byte ebp no no direct (2)
10 ConvertString4YF 1 byte esp no no direct (2)
--------------------------------------------------------------------------------
11 ConvertString4T 1 byte ebp yes no xlatb (2)
12 ConvertString4TX 1 " esp yes no xlatb (2)
13 ConvertString4TY 1 byte esp yes no code table (2)
14 ConvertString4TW 1 " esp yes no " (2)
15 ConvertString4T4 4 " esp yes no " (2)
--------------------------------------------------------------------------------
16 ConvertString4D 1 " ebp no no direct (2)
17 ConvertString4DS 1 " ebp no yes direct (2)
---------------------------------------------------------------------------------
obs. (1) no spaces/no zeroes
(2) remove spaces/zeroes
(3) rcl strings sampled from right to left
(4) all use tables of qwords to get the power of 10: 10^n or 10^-n
file: TestCnvDD9.exe
It is to show the results in P4 XP sp3
converting 10 different strings
--------------------------------------
ConvertString4TW
1234.567
ConvertString4T4
1234.567
ConvertString4D
1234.567
ConvertString4DS
1234.567
*** STOP RclStr04 +1234.567 ***
converting _RclStr05 +1234E+12
ConvertString4B
1.2339999E+15
ConvertString4BX
1.2339999E+15
ConvertString4BZ
1.2339999E+15
ConvertString4BY
1.2339999E+15
ConvertString4BW
1.2339999E+15
ConvertString4BF
1.2339999E+15
ConvertString4Y0
1.2339999E+15
ConvertString4Y
1.2339999E+15
ConvertString4YM
1.2339999E+15
ConvertString4YF
1.2339999E+15
ConvertString4T
1.2339999E+15
ConvertString4TX
1.2339999E+15
ConvertString4TY
1.2339999E+15
ConvertString4TW
1.2339999E+15
ConvertString4T4
1.2339999E+15
ConvertString4D
1.2339999E+15
ConvertString4DS
1.2339999E+15
*** STOP RclStr05 +1234E+12 ***
converting _RclStr06 .567E+12
ConvertString4B
1 ERROR eax
ConvertString4BX
1 ERROR eax
ConvertString4BZ
1 ERROR eax
ConvertString4BY
1 ERROR eax
ConvertString4BW
1 ERROR eax
ConvertString4BF
1 ERROR eax
ConvertString4Y0
5.6699997E+11
ConvertString4Y
5.6699997E+11
ConvertString4YM
5.6699997E+11
ConvertString4YF
5.6699997E+11
ConvertString4T
5.6699997E+11
ConvertString4TX
5.6699997E+11
ConvertString4TY
5.6699997E+11
ConvertString4TW
5.6699997E+11
ConvertString4T4
5.6699997E+11
ConvertString4D
5.6699997E+11
ConvertString4DS
5.6699997E+11
*** STOP RclStr06 .567E+12 ***
converting _RclStr07 +1234.567E+12
ConvertString4B
1.234567E+15
ConvertString4BX
1.234567E+15
ConvertString4BZ
1.234567E+15
ConvertString4BY
1.234567E+15
ConvertString4BW
1.234567E+15
ConvertString4BF
1.234567E+15
ConvertString4Y0
1.234567E+15
ConvertString4Y
1.234567E+15
ConvertString4YM
1.234567E+15
ConvertString4YF
1.234567E+15
ConvertString4T
1.234567E+15
ConvertString4TX
1.234567E+15
ConvertString4TY
1.234567E+15
ConvertString4TW
1.234567E+15
ConvertString4T4
1.234567E+15
ConvertString4D
1.234567E+15
ConvertString4DS
1.234567E+15
*** STOP RclStr07 +1234.567E+12 ***
converting _RclStr08 +000000 012 34.56 7 E + 000012
ConvertString4B
3 ERROR eax
ConvertString4BX
3 ERROR eax
ConvertString4BZ
3 ERROR eax
ConvertString4BY
3 ERROR eax
ConvertString4BW
3 ERROR eax
ConvertString4BF
1 ERROR eax
ConvertString4Y0
1 ERROR eax
ConvertString4Y
1.234567E+15
ConvertString4YM
1.234567E+15
ConvertString4YF
1.234567E+15
ConvertString4T
1.234567E+15
ConvertString4TX
1.234567E+15
ConvertString4TY
1.234567E+15
ConvertString4TW
1.234567E+15
ConvertString4T4
1.234567E+15
ConvertString4D
1.234567E+15
ConvertString4DS
1.234567E+15
*** STOP RclStr08 +000000 012 34.56 7 E + 000012 ***
converting _RclStr09 +1.234E+45
ConvertString4B
8 ERROR eax
ConvertString4BX
8 ERROR eax
ConvertString4BZ
8 ERROR eax
ConvertString4BY
8 ERROR eax
ConvertString4BW
8 ERROR eax
ConvertString4BF
8 ERROR eax
ConvertString4Y0
8 ERROR eax
ConvertString4Y
8 ERROR eax
ConvertString4YM
8 ERROR eax
ConvertString4YF
8 ERROR eax
ConvertString4T
8 ERROR eax
ConvertString4TX
8 ERROR eax
ConvertString4TY
8 ERROR eax
ConvertString4TW
8 ERROR eax
ConvertString4T4
8 ERROR eax
ConvertString4D
8 ERROR eax
ConvertString4DS
8 ERROR eax
*** STOP RclStr09 +1.234E+45 ***
converting _RclStr10 +1.234E-45
ConvertString4B
8 ERROR eax
ConvertString4BX
8 ERROR eax
ConvertString4BZ
8 ERROR eax
ConvertString4BY
8 ERROR eax
ConvertString4BW
8 ERROR eax
ConvertString4BF
8 ERROR eax
ConvertString4Y0
7 ERROR eax
ConvertString4Y
1.4012985E-45
ConvertString4YM
1.4012985E-45
ConvertString4YF
1.4012985E-45
ConvertString4T
1.4012985E-45
ConvertString4TX
1.4012985E-45
ConvertString4TY
1.4012985E-45
ConvertString4TW
1.4012985E-45
ConvertString4T4
1.4012985E-45
ConvertString4D
1.4012985E-45
ConvertString4DS
1.4012985E-45
*** STOP RclStr10 +1.234E-45 and END ***
file: TestCnvDD10.exe
My results in P4 XP sp3
-----------------------
Quote
converting _RclStr04 +1234.567
2665 cycles, ConvertString4, _RclStr04
2642 cycles, ConvertString4BX, _RclStr04
566 cycles, ConvertString4BZ, _RclStr04
528 cycles, ConvertString4BY, _RclStr04
452 cycles, ConvertString4BW, _RclStr04
455 cycles, ConvertString4BF, _RclStr04
107 cycles, ConvertString4Y0, _RclStr04
127 cycles, ConvertString4Y, _RclStr04
138 cycles, ConvertString4YM, _RclStr04
122 cycles, ConvertString4YF, _RclStr04
231 cycles, ConvertString4T, _RclStr04
177 cycles, ConvertString4TX, _RclStr04
169 cycles, ConvertString4TY, _RclStr04
151 cycles, ConvertString4TW, _RclStr04
211 cycles, ConvertString4T4, _RclStr04
119 cycles, ConvertString4D, _RclStr04
2218 cycles, ConvertString4DS, _RclStr04
*** STOP and END ***
***** Time table *****
107 cycles, ConvertString4Y0, direct - no spaces, no zeroes
119 cycles, ConvertString4D, direct
122 cycles, ConvertString4YF, direct
127 cycles, ConvertString4Y, direct
138 cycles, ConvertString4YM, direct
151 cycles, ConvertString4TW, code table
169 cycles, ConvertString4TY, code table
177 cycles, ConvertString4TX, xlatb
211 cycles, ConvertString4T4, code table
231 cycles, ConvertString4T, xlatb
452 cycles, ConvertString4BW, BCD
455 cycles, ConvertString4BF, BCD
528 cycles, ConvertString4BY, BCD
566 cycles, ConvertString4BZ, BCD
2218 cycles, ConvertString4DS, direct, save FPU
2642 cycles, ConvertString4BX, BCD, save FPU
2665 cycles, ConvertString4B, BCD, save FPU
********** END **********
Hi RuiLoureiro
here are my results with an i7 (Windows 64 bit):
Quote
converting _RclStr04 +1234.567
677 cycles, ConvertString4, _RclStr04
636 cycles, ConvertString4BX, _RclStr04
208 cycles, ConvertString4BZ, _RclStr04
198 cycles, ConvertString4BY, _RclStr04
195 cycles, ConvertString4BW, _RclStr04
182 cycles, ConvertString4BF, _RclStr04
44 cycles, ConvertString4Y0, _RclStr04
50 cycles, ConvertString4Y, _RclStr04
46 cycles, ConvertString4YM, _RclStr04
51 cycles, ConvertString4YF, _RclStr04
84 cycles, ConvertString4T, _RclStr04
66 cycles, ConvertString4TX, _RclStr04
57 cycles, ConvertString4TY, _RclStr04
62 cycles, ConvertString4TW, _RclStr04
67 cycles, ConvertString4T4, _RclStr04
49 cycles, ConvertString4D, _RclStr04
483 cycles, ConvertString4DS, _RclStr04
*** STOP and END ***
***** Time table *****
44 cycles, ConvertString4Y0, direct - no spaces, no zeroes
46 cycles, ConvertString4YM, direct
49 cycles, ConvertString4D, direct
50 cycles, ConvertString4Y, direct
51 cycles, ConvertString4YF, direct
57 cycles, ConvertString4TY, code table
62 cycles, ConvertString4TW, code table
66 cycles, ConvertString4TX, xlatb
67 cycles, ConvertString4T4, code table
84 cycles, ConvertString4T, xlatb
182 cycles, ConvertString4BF, BCD
195 cycles, ConvertString4BW, BCD
198 cycles, ConvertString4BY, BCD
208 cycles, ConvertString4BZ, BCD
483 cycles, ConvertString4D, direct, save FPU
636 cycles, ConvertString4BX, BCD, save FPU
677 cycles, ConvertString4B, BCD, save FPU
********** END **********
Gunther
Hi Gunther
Thanks ! :icon14:
----------------------------------------------------
Converting from string to real4 using FPU
----------------------------------------------------
We know it is an old story that many of us know well.
Nevertheless, there are people that want to try to write
his own converter or they are trying to learn.
For this reason, i will try to remember some basic concepts
based on a general example, to be simple. This is just to
answer some questions like «why you do this ?»,
«why you do that ?» ...
Quote
----------------
A. introduction
----------------
If our string is defined as _string db "-1234.567E+12",0
or _string db "-1234.567e+12",0
In general, we have only the symbols: '0' to '9', '+', '-', '.', 'E' and 'e'
In general, we have 3 parts:
1. integer part: -1234 ( from starting point to '.' )
2. decimal part: 567 ( after '.' to 'E' )
3. exponent part: +12 ( after 'E' to 0 )
This -1234.567E+12 means this: -1234.567 * 10^+12
But -1234.567 = -(1234 + 0.567)
or = -1234 - 0.567 = -1234 - 567 * 10^-3
= (-1234) + (-567) * (10^-3) (to use + instead of -)
( 0.567 = 567 * 10^-3 where 3 is the number of decimal places = ndd ).
note: if we have an expression 10^-n, then -n means «go backward n digits»
if we have an expression 10^+n, then +n means «go forward n digits»
Finally, we have the complete expression
-1234.567E+12= -1234.567 * 10^+12 = [(-1234) + (-567 * 10^-4)] * 10^+12
= (ecx + edi * 10^-ebx) * 10^edx
where:
ecx = integer part
edi = decimal part (has the same sign as the integer part)
ebx = number of decimal places (is allways a positive value)
edx = exponent
-------------------------------------------------------
B. floating point notation or scientific notation
-------------------------------------------------------
siiiiii.dddddddEsxxxx where s = sign +/- e or E = 10^ factor
i = integer digit
d = decimal digit
x = exponent digit
means or stands for: siiiiii.ddddddd * 10^sxxxx (well, 's' is one 's' not the same!)
we have 3 things:
1. integer part = siiiiii
2. decimal part = sddddddd (the sign is implied)
3 exponent part = sxxxx => power part = 10^sxxxx
all different cases
----------------------
case 1: 1234 -> start with integer
case 2: .567 -> start with decimal (point)
case 3: E+12 -> start with power. this case should be error
because e+10 may be 2.718281828459045+10=12.718281828459045
and not scientific notation
case 4: 1234.567 -> integer plus decimal
case 5: 1234E+12 -> integer plus power
case 6: .567E+12 -> decimal plus power
case 7: 1234.567E+12 -> integer plus decimal plus power
other cases: 1.234E+45 or 1.234E-45 (overflow/underflow)
------------------------------
C. spaces or not spaces
------------------------------
Is there another meaning for -123.45 6782 than the same as -123.456782 ?
or
Is there another meaning for -1 23.45 67 82 than the same as -123.456782 ?
I like to write with spaces and i dont like to get error from a converter
if i use spaces. The converter should remove it.
--------------------------------------
D. one idea to parse the string
--------------------------------------
note: if we want to use FPU, we should define 3 local variables
For instance, integerDD, decimalDD, exponentDD (all dwords)
because we cannot pass values in registers to FPU
1. find the sign (and save it if it is negative)
2. a) IntegerPart
-----------------
a1) get the character to AL and subtract 30h
. If carry set, we have 3/4 cases:
. -2 is '.' -> go to DecimalPart
. -16 is space (if we want)
. -48 is 0 => endinteger
. unacceptable character
. cmp al, 9
jbe isdigit -> save it or do what you want
. now, it must be:
. 21 is 'E' -> go to ExponentPart
. 53 is 'e'
. unacceptable character
b) DecimalPart
----------------
b1) get the character to AL and subtract 30h
. If carry set, we have 2/3 cases:
. -16 is space (if we want)
. -48 is 0 => enddecimal
. unacceptable character
. cmp al, 9
jbe isdigit -> save it or do what you want
. now, it must be:
. 21 is 'E' -> go to ExponentPart
. 53 is 'e'
. unacceptable character
c) ExponentPart
------------------
c1) find the sign (and save it if it is negative)
c2) get the character to AL and subtract 30h
. If carry set, we have 2/3 cases:
. -16 is space (if we want)
. -48 is 0 => endexponent
. unacceptable character
. cmp al, 9
jbe isdigit -> save it or do what you want
. now it must be:
. unacceptable character
endinteger: we must have at least 1 integer or integer = 0 or error
----------
enddecimal: we must have at least 1 integer or integer = 0 or error
----------
endexponent: we must have at least 1 integer or 1 decimal or error
----------- (.E should be error)
neg the value if negative
3. now, we have the values of each part in integerDD, decimalDD, exponentDD
3.1 change the sign of integerDD and decimalDD if there is sign
3.2 load the values into FPU and compute the expression
fild integerDD
fild decimalDD
multiply by 10^-ndd (ndd=number of decimal digits)
multiply by 10^exponentDD
4. store the result
(and test if there is an error if you want. The result may be infinity!)
-----------------------------------------
D1. one solution to remove spaces
------------------------------------------
When we start, we test if space (al=20h) and then the sign.
Whenever we start IntegerPart or DecimalPart or ExponentPart
we test if space (al=20h.)
If we are in IntegerPart or ExponentPart, then we test sign
and then we test space or zeros (may be -000555).
---------------------------
D2. removing zeroes
---------------------------
In cases like 000000123.25E00032 the integer part has not 9 digits but 3
So, while it is '0', get another and dont go to the next step.
---------------------------
D3. errors
---------------------------
We have 3 types of erros:
1. user erros
a) expression error
b) unacceptable character
c) more than 8 integer digits
d) more than 7 decimal digits
e) more than 2 exponet digits
2. programming errors
a) undefined pointers
3. FPU errors
a) invalid operation
b) overflow/underflow
c) Indefinite or NAN number
-------------------------------------------
D.4 To multiply by 10 and add eax
-------------------------------------------
solution 1: lea edx, [edx+edx*4]
lea edx, [eax+edx*2]
solution 2: imul edx, 10
add edx, eax
...
---------------------------
E. Real4 format
---------------------------
offset: +0 +16 +22 +31
---------------------------------------------
|f23 | f1|e0 e7|S|
---------------------------------------------
a) S bit 31 = sign -> 0 = positive, 1= negative
to test sign bit: «test eax, 80000000H» or «and eax, 80000000H»
b) 8 exponent bits: bits e0-e7 , from offset 23 to 30
to extract exponent bits: «and eax, 7F800000H»
or «shl eax, 23»
«and eax, 0FFh»
exponent bits
-------------
exponent < 0 -> < 7Fh
if exponent = 0 -> = 7Fh=127 (real expoent=0 => exponent bits=7Fh)
exponent > 0 -> > 7Fh
if expoent bits = FFh => NAN
if NAN and fraction bits= 0 => INFINITY (S=0 => +infinity S=1 => -infinity)
if NAN and fraction bits= 1 => INDEFINITE
c) 23 fraction bits: bits f1 - f23, from offset 0 to 22
to extract fraction bits: «and eax, 07FFFFFH»
-------------------------------
F. test real4 format in EAX
-------------------------------
move a dword from memory to eax.
If it is in st(0), move it to memory
output:
stc: is Indefinite or NAN
clc: is a number (not infinity)
TestReal4 proc
or eax, eax
jz short @F
shr eax, 23 ; exponent and sign in AX; AH=sign AL=exponent
cmp al, 0FFh
je short _isNan
; ---------------
; is real4 number
; ---------------
@@: clc
ret
; --------------------------------
; is INFINITY or INDEFINITY or NAN
; --------------------------------
_isNan: stc
ret
TestReal4 endp
--------------------------------------
examine 1 real4 format in EAX
--------------------------------------
move a dword from memory to eax
If it is in st(0), move it to memory
output:
stc: is Indefinite or NAN
clc: EAX = 0 is 0
= 1 is +INFINITY
= 2 is -INFINITY
= 3 is POSITIVE
= 4 is NEGATIVE
Examine1Real4 proc
or eax, eax
jnz short @F
; -------------
; is 0 -> EAX=0
; -------------
clc
ret
@@: mov edx, eax
shr edx, 23 ;exponent and sign in DX; DH=sign DL=exponent
and eax, 07FFFFFH ; fraction in EAX
;
cmp dl, 0FFh
je short _isNan
; ---------------
; is real4 number
; ---------------
mov eax, 3
shr dh, 1
jnc short _isRealP
; -----------
; is negative
; -----------
add eax, 1
; -----------
; is positive
; -----------
_isRealP: clc
ret
_isNan: or eax, eax
jz short _isInfinity
; --------------------
; is indefinite or NAN
; --------------------
stc
ret
_isInfinity: mov eax, 3
shr dh, 1
jnc short _isInfinityP
; ------------
; is -infinity
; ------------
add eax, 1
; ------------
; is +infinity
; ------------
_isInfinityP: stc
ret
Examine1Real4 endp
-------------------------------------
examine 2 real4 format in EAX
--------------------------------------
move a dword from memory to eax
If it is in st(0), move it to memory
output:
stc: is Indefinite or NAN
clc: EAX = 0 is a number
= 1 is INFINITY
Examine2Real4 proc
or eax, eax
jnz short @F
; -------------
; is 0 -> EAX=0
; -------------
_isNumber: xor eax, eax
clc
ret
@@: mov edx, eax
shr edx, 23 ; exponent and sign in DX; DH=sign DL=exponent
and eax, 07FFFFFH ; fraction in EAX
;
cmp dl, 0FFh
jne short _isNumber
or eax, eax
jz short _isInfinity
; --------------------
; is indefinite or NAN
; --------------------
stc
ret
_isInfinity: mov eax, 1
clc
ret
Examine2Real4 endp
Hi RuiLoureiro,
good explanation and a good refresher. :t
Gunther
Hi RuiLoureiro!
Here are tests for Celeron D:
TestCnvDD9:
ConvertString4YF
1234.0
ConvertString4T
1234.0
ConvertString4TX
1234.0
ConvertString4TY
1234.0
ConvertString4TW
1234.0
ConvertString4T4
1234.0
ConvertString4D
1234.0
ConvertString4DS
1234.0
*** STOP RclStr01 +1234 ***
converting _RclStr02 .567
ConvertString4B
1 ERROR eax
ConvertString4BX
1 ERROR eax
ConvertString4BZ
1 ERROR eax
ConvertString4BY
1 ERROR eax
ConvertString4BW
1 ERROR eax
ConvertString4BF
1 ERROR eax
ConvertString4Y0
0.567
ConvertString4Y
0.567
ConvertString4YM
0.567
ConvertString4YF
0.567
ConvertString4T
0.567
ConvertString4TX
0.567
ConvertString4TY
0.567
ConvertString4TW
0.567
ConvertString4T4
0.567
ConvertString4D
0.567
ConvertString4DS
0.567
*** STOP RclStr02 .567 ***
converting _RclStr03 E+12
ConvertString4B
1 ERROR eax
ConvertString4BX
1 ERROR eax
ConvertString4BZ
1 ERROR eax
ConvertString4BY
1 ERROR eax
ConvertString4BW
1 ERROR eax
ConvertString4BF
1 ERROR eax
ConvertString4Y0
1 ERROR eax
ConvertString4Y
1 ERROR eax
ConvertString4YM
1 ERROR eax
ConvertString4YF
1 ERROR eax
ConvertString4T
1 ERROR eax
ConvertString4TX
1 ERROR eax
ConvertString4TY
1 ERROR eax
ConvertString4TW
1 ERROR eax
ConvertString4T4
1 ERROR eax
ConvertString4D
1 ERROR eax
ConvertString4DS
1 ERROR eax
*** STOP RclStr03 E+12 ***
converting _RclStr04 +1234.567
ConvertString4B
1234.567
ConvertString4BX
1234.567
ConvertString4BZ
1234.567
ConvertString4BY
1234.567
ConvertString4BW
1234.567
ConvertString4BF
1234.567
ConvertString4Y0
1234.567
ConvertString4Y
1234.567
ConvertString4YM
1234.567
ConvertString4YF
1234.567
ConvertString4T
1234.567
ConvertString4TX
1234.567
ConvertString4TY
1234.567
ConvertString4TW
1234.567
ConvertString4T4
1234.567
ConvertString4D
1234.567
ConvertString4DS
1234.567
*** STOP RclStr04 +1234.567 ***
converting _RclStr05 +1234E+12
ConvertString4B
1.2339999E+15
ConvertString4BX
1.2339999E+15
ConvertString4BZ
1.2339999E+15
ConvertString4BY
1.2339999E+15
ConvertString4BW
1.2339999E+15
ConvertString4BF
1.2339999E+15
ConvertString4Y0
1.2339999E+15
ConvertString4Y
1.2339999E+15
ConvertString4YM
1.2339999E+15
ConvertString4YF
1.2339999E+15
ConvertString4T
1.2339999E+15
ConvertString4TX
1.2339999E+15
ConvertString4TY
1.2339999E+15
ConvertString4TW
1.2339999E+15
ConvertString4T4
1.2339999E+15
ConvertString4D
1.2339999E+15
ConvertString4DS
1.2339999E+15
*** STOP RclStr05 +1234E+12 ***
converting _RclStr06 .567E+12
ConvertString4B
1 ERROR eax
ConvertString4BX
1 ERROR eax
ConvertString4BZ
1 ERROR eax
ConvertString4BY
1 ERROR eax
ConvertString4BW
1 ERROR eax
ConvertString4BF
1 ERROR eax
ConvertString4Y0
5.6699997E+11
ConvertString4Y
5.6699997E+11
ConvertString4YM
5.6699997E+11
ConvertString4YF
5.6699997E+11
ConvertString4T
5.6699997E+11
ConvertString4TX
5.6699997E+11
ConvertString4TY
5.6699997E+11
ConvertString4TW
5.6699997E+11
ConvertString4T4
5.6699997E+11
ConvertString4D
5.6699997E+11
ConvertString4DS
5.6699997E+11
*** STOP RclStr06 .567E+12 ***
converting _RclStr07 +1234.567E+12
ConvertString4B
1.234567E+15
ConvertString4BX
1.234567E+15
ConvertString4BZ
1.234567E+15
ConvertString4BY
1.234567E+15
ConvertString4BW
1.234567E+15
ConvertString4BF
1.234567E+15
ConvertString4Y0
1.234567E+15
ConvertString4Y
1.234567E+15
ConvertString4YM
1.234567E+15
ConvertString4YF
1.234567E+15
ConvertString4T
1.234567E+15
ConvertString4TX
1.234567E+15
ConvertString4TY
1.234567E+15
ConvertString4TW
1.234567E+15
ConvertString4T4
1.234567E+15
ConvertString4D
1.234567E+15
ConvertString4DS
1.234567E+15
*** STOP RclStr07 +1234.567E+12 ***
converting _RclStr08 +000000 012 34.56 7 E + 000012
ConvertString4B
3 ERROR eax
ConvertString4BX
3 ERROR eax
ConvertString4BZ
3 ERROR eax
ConvertString4BY
3 ERROR eax
ConvertString4BW
3 ERROR eax
ConvertString4BF
1 ERROR eax
ConvertString4Y0
1 ERROR eax
ConvertString4Y
1.234567E+15
ConvertString4YM
1.234567E+15
ConvertString4YF
1.234567E+15
ConvertString4T
1.234567E+15
ConvertString4TX
1.234567E+15
ConvertString4TY
1.234567E+15
ConvertString4TW
1.234567E+15
ConvertString4T4
1.234567E+15
ConvertString4D
1.234567E+15
ConvertString4DS
1.234567E+15
*** STOP RclStr08 +000000 012 34.56 7 E + 000012 ***
converting _RclStr09 +1.234E+45
ConvertString4B
8 ERROR eax
ConvertString4BX
8 ERROR eax
ConvertString4BZ
8 ERROR eax
ConvertString4BY
8 ERROR eax
ConvertString4BW
8 ERROR eax
ConvertString4BF
8 ERROR eax
ConvertString4Y0
8 ERROR eax
ConvertString4Y
8 ERROR eax
ConvertString4YM
8 ERROR eax
ConvertString4YF
8 ERROR eax
ConvertString4T
8 ERROR eax
ConvertString4TX
8 ERROR eax
ConvertString4TY
8 ERROR eax
ConvertString4TW
8 ERROR eax
ConvertString4T4
8 ERROR eax
ConvertString4D
8 ERROR eax
ConvertString4DS
8 ERROR eax
*** STOP RclStr09 +1.234E+45 ***
converting _RclStr10 +1.234E-45
ConvertString4B
8 ERROR eax
ConvertString4BX
8 ERROR eax
ConvertString4BZ
8 ERROR eax
ConvertString4BY
8 ERROR eax
ConvertString4BW
8 ERROR eax
ConvertString4BF
8 ERROR eax
ConvertString4Y0
7 ERROR eax
ConvertString4Y
1.4012985E-45
ConvertString4YM
1.4012985E-45
ConvertString4YF
1.4012985E-45
ConvertString4T
1.4012985E-45
ConvertString4TX
1.4012985E-45
ConvertString4TY
1.4012985E-45
ConvertString4TW
1.4012985E-45
ConvertString4T4
1.4012985E-45
ConvertString4D
1.4012985E-45
ConvertString4DS
1.4012985E-45
*** STOP RclStr10 +1.234E-45 and END ***
TestCncDD10:
Quoteconverting _RclStr04 +1234.567
2566 cycles, ConvertString4, _RclStr04
2662 cycles, ConvertString4BX, _RclStr04
603 cycles, ConvertString4BZ, _RclStr04
561 cycles, ConvertString4BY, _RclStr04
446 cycles, ConvertString4BW, _RclStr04
465 cycles, ConvertString4BF, _RclStr04
113 cycles, ConvertString4Y0, _RclStr04
128 cycles, ConvertString4Y, _RclStr04
135 cycles, ConvertString4YM, _RclStr04
125 cycles, ConvertString4YF, _RclStr04
239 cycles, ConvertString4T, _RclStr04
181 cycles, ConvertString4TX, _RclStr04
174 cycles, ConvertString4TY, _RclStr04
157 cycles, ConvertString4TW, _RclStr04
218 cycles, ConvertString4T4, _RclStr04
115 cycles, ConvertString4D, _RclStr04
2221 cycles, ConvertString4DS, _RclStr04
*** STOP and END ***
***** Time table *****
113 cycles, ConvertString4Y0, direct - no spaces, no zeroes
115 cycles, ConvertString4D, direct
125 cycles, ConvertString4YF, direct
128 cycles, ConvertString4Y, direct
135 cycles, ConvertString4YM, direct
157 cycles, ConvertString4TW, code table
174 cycles, ConvertString4TY, code table
181 cycles, ConvertString4TX, xlatb
218 cycles, ConvertString4T4, code table
239 cycles, ConvertString4T, xlatb
446 cycles, ConvertString4BW, BCD
465 cycles, ConvertString4BF, BCD
561 cycles, ConvertString4BY, BCD
603 cycles, ConvertString4BZ, BCD
2221 cycles, ConvertString4D, direct, save FPU
2566 cycles, ConvertString4B, BCD, save FPU
2662 cycles, ConvertString4BX, BCD, save FPU
********** END **********
Thanks for your explanations on floating point basics . That's just what I want to understand (I'm among those trying to learn)
:t
going from a real to a string is fun
going from a string to a real is hard work :t
i was wondering - without me reading 15 more miles of documentation
do the fraction bits have any meaning for NaN's ?
EDIT - i see they can carry a "payload"
not much in the way of a description, though - lol
other than it may be some sort of ordinal indicating where the problem originated
Quote from: Gunther on April 15, 2013, 05:47:11 AM
Hi RuiLoureiro,
good explanation and a good refresher. :t
Gunther
:biggrin:
Thanks Gunther :t
Quote from: vertograd on April 15, 2013, 07:59:41 PM
Hi RuiLoureiro!
...
Thanks for your explanations on floating point basics . That's just what I want to understand (I'm among those trying to learn)
:t
Hi vertograd :t
I dont like to do things without some explanations
i was
a teacher so...
And i try to be clear, but sometimes ... we dont know
Thanks
more: this converter was the best i did
Quote from: dedndave on April 16, 2013, 12:47:51 AM
going from a real to a string is fun
going from a string to a real is hard work :t
i was wondering - without me reading 15 more miles of documentation
do the fraction bits have any meaning for NaN's ?
Dave,
i dont know. I think that FPU set it to NAN when it fails to
do some operation and set fraction to 0 if beyond the limit.
We need to know the details about the hardware, thing
that i have no time now to follow.
the special case values for REAL4 and REAL8 are pretty simple :biggrin:
a few more caveats when you do REAL10
Quote from: dedndave on April 20, 2013, 07:19:12 AM
the special case values for REAL4 and REAL8 are pretty simple :biggrin:
a few more caveats when you do REAL10
What ? the calculator works with real10, i dont know any problems :biggrin:
my mistake, Rui :redface:
i guess going from Ascii Decimal to REAL, you don't encounter all the caveats
it either fits or it doesn't - lol
and if it doesn't fit, you can assign the largest or smalllest value that does fit :biggrin:
i was thinking about going from REAL to Ascii Decimal
the REAL4 and REAL8 formats are a little simpler than REAL10
REAL4/REAL8
Exponent Fraction Meaning
0 0 Signed Zero
0 <> 0 Signed Denormal
Other Any Signed Normal
All 1's 0 Signed Infinity
All 1's <> 0 NaN
REAL10
Exponent Significand Meaning
0000 0000_0000_0000_0000 Signed Zero
0000_0000_0000_0001 to 7FFF_FFFF_FFFF_FFFF Signed Denormal
8000_0000_0000_0000 to FFFF_FFFF_FFFF_FFFF Signed Pseudo-Denormal
0001 to 7FFE 0000_0000_0000_0000 to 7FFF_FFFF_FFFF_FFFF Invalid
8000_0000_0000_0000 to FFFF_FFFF_FFFF_FFFF Signed Normal
7FFF 0000_0000_0000_0000 to 7FFF_FFFF_FFFF_FFFF Invalid
8000_0000_0000_0000 Signed Infinity
8000_0000_0000_0001 to BFFF_FFFF_FFFF_FFFF Signaling NaN
C000_0000_0000_0000 Indefinite Quiet NaN
C000_0000_0000_0001 to FFFF_FFFF_FFFF_FFFF Quiet NaN
Good to know, Dave ! :t
One of these days i will use that info
Quote
REAL10
Exponent Significand Meaning
0000 0000_0000_0000_0000 Signed Zero
0000_0000_0000_0001 to 7FFF_FFFF_FFFF_FFFF Signed Denormal
8000_0000_0000_0000 to FFFF_FFFF_FFFF_FFFF Signed Pseudo-Denormal
0001 to 7FFE 0000_0000_0000_0000 to 7FFF_FFFF_FFFF_FFFF Invalid
8000_0000_0000_0000 to FFFF_FFFF_FFFF_FFFF Signed Normal
7FFF 0000_0000_0000_0000 to 7FFF_FFFF_FFFF_FFFF Invalid
8000_0000_0000_0000 Signed Infinity
8000_0000_0000_0001 to BFFF_FFFF_FFFF_FFFF Signaling NaN
C000_0000_0000_0000 Indefinite Quiet NaN
C000_0000_0000_0001 to FFFF_FFFF_FFFF_FFFF Quiet NaN
Dave,
when exponent is 7FFF
is this -Infinity ?
8
000_0000_0000_0000 Signed Infinity
so this is +Infinity, no ?
0
000_0000_0000_0000 Signed Infinity
So, where is the bit 79 = sign bit ?
If the S+exponent = 7FFFh -> sign = +
=
FFFFh -> sign =
-Where is the problem ?
the problem is, you are looking at info for the REAL10 format
there are 10 bytes, or 5 words - you are looking at 4 words :P
the first column shows the exponent, bits 78 to 64
the second column shows the significand, bits 63 to 0
+infinity = 7FFF_8000_0000_0000_0000
-infinity = FFFF_8000_0000_0000_0000
Quote from: dedndave on April 24, 2013, 04:35:00 AM
the problem is, you are looking at info for the REAL10 format
there are 10 bytes, or 5 words - you are looking at 4 words :P
the first column shows the exponent, bits 78 to 64
the second column shows the significand, bits 63 to 0
+infinity = 7FFF_8000_0000_0000_0000
-infinity = FFFF_8000_0000_0000_0000
Ohh yes it is
; --------------------------
; examine real 10
; --------------------------
Quote
mov eax, dword ptr [ebx+0]
mov ecx, dword ptr [ebx+4]
mov dx, word ptr [ebx+8]
shl dx, 1 ; move sign -> carry
cmp dx, 0FFFEH
je short _isNAN ; All = 1
;
;
;
and ecx, 80000000h
jnz short _start
jz _iszero
; -------------------
; It is NAN
; -------------------
_isNAN: or eax, eax
jnz _erro1 <--------- NAN
xor ecx, 80000000h
jnz _erro1 <--------- NAN
mov dx, word ptr [ebx+8]
mov al, '+'
and dx, 8000H
jz _isinfinity ; is +infinity
;------------
; is -infinity
; ------------
mov al, '-'
jmp _isinfinity ; is -infinity
; --------------------
; test for sign
; --------------------
_start: mov dx, word ptr [ebx+8]
REAL10
Exponent Significand Meaning
0000 0000_0000_0000_0000 Signed Zero
0000_0000_0000_0001 to 7FFF_FFFF_FFFF_FFFF Signed Denormal
8000_0000_0000_0000 to FFFF_FFFF_FFFF_FFFF Signed Pseudo-Denormal
0001 to 7FFE 0000_0000_0000_0000 to 7FFF_FFFF_FFFF_FFFF Invalid
8000_0000_0000_0000 to FFFF_FFFF_FFFF_FFFF Signed Normal
7FFF 0000_0000_0000_0000 to 7FFF_FFFF_FFFF_FFFF Invalid
8000_0000_0000_0000 Signed Infinity
8000_0000_0000_0001 to BFFF_FFFF_FFFF_FFFF Signaling NaN
C000_0000_0000_0000 Indefinite Quiet NaN
C000_0000_0000_0001 to FFFF_FFFF_FFFF_FFFF Quiet NaN
you might find it easier to deal with the exponent like this, rather than using SHL
movzx edx, word ptr [ebx+8]
mov ecx, dword ptr [ebx+4]
mov _Sign, edx ;a local variable to save the sign for later
mov eax, dword ptr [ebx+0]
and dx, 7FFFh
je Test_Exp_0_Special_Values
cmp dx, 7FFFh
je Test_Exp_7FFF_Special_Values
test ecx, ecx
jns Invalid_Value
the only special values for exponent = 0 are signed zeros
so - if the significand is not zero, increment the exponent and evaluate it the same as a normal
all values are special for exponent = 7FFF
sooner or later, you are going to want the exponent with bit 0 right-justified :P
the one i am writing will evaluate all reals
you pass it a pointer to the real, and a wParam
it uses an internal buffer for the string - so the caller doesn't need to make one
the high word of wParam is used to determine the type
0 = REAL10
1 = REAL4
2 = REAL8
the low word of wParam allows them to limit the number of signifigant digits
here is my outline that i am using to write the code
maybe it will help you :t
;*****************************************************
; Operational Overview
;
;The routine is divided into the following seven sections.
;Each section begins with a detailed outline.
;
; 1. Strategy
; 2. Left-Shift Scaling (for large values)
; 3. Exponential Scaling (for small values)
; 4. Base Conversion
; 5. Scientific Formatting
; 6. Routine Exit
; 7. Special Values
;*****************************************************
;Strategy Section
;
; 1. validate wParam high word and determine type of real to be processed
; a. type:
; 0 for real10
; 1 for real4
; 2 for real8
; b. any other value yields an error result:
; EAX = ERROR_INVALID_PARAMETER = 87
; ECX = 0
; EDX = pointer to null string
; 2. if wParam low word is 0, set the default number of digits
; a. default maximum signifigant digits:
; 21 digits for real10
; 9 digits for real4
; 17 digits for real8
; 3. store the sign for later use (refer to the Scientific Format code section)
; a. stored in a local variable: bit 31 clear if positive, set if negative
; 4. filter out special values (refer to the Special Values code section)
; a. for all real types:
; signed 0
; signed infinity
; b. additional special value for real4 and real8 types:
; NaN
; c. additional special values for real10 type:
; Indefinite QNaN
; QNaN
; SNaN
; Invalid
; 5. standardize numerical format, allowing all types to be processed the same way
; a. sign stored in a local variable (see part 3)
; b. exponent:
; real10 exponent is 15 bits of the high word, sign bit removed
; real4 exponent is 8 bits of the high word, sign bit removed, shifted right by 7
; real8 exponent is 11 bits of the high word, sign bit removed, shifted right by 4
; c. qword significand:
; for real10 type, integer bit 63 is explicit
; for real4 type, integer bit 23 is set if it is not a denormal value
; for real8 type, integer bit 52 is set if it is not a denormal value
; 6. adjust exponent by subtracting "fraction-adjusted" bias
; a. for denormal values, we add one to the exponent, then process as a normal
; b. fraction-adjusted bias:
; real10 bias is 16383, fraction-adjusted bias is 16383+63 = 16446
; real4 bias is 127, fraction-adjusted bias is 127+23 = 150
; real8 bias is 1023, fraction-adjusted bias is 1023+52 = 1075
; 7. branch according to exponent
; a. if the fraction-adjusted exponent is 0, no scaling required, do base conversion
; b. if the fraction-adjusted exponent is positive, scale by left-shifting
; c. if the fraction-adjusted exponent is negative, scale by exponentiation
;*****************************************************
Quote from: dedndave on April 24, 2013, 04:54:40 AM
you might find it easier to deal with the exponent like this, rather than using SHL
movzx edx, word ptr [ebx+8]
mov ecx, dword ptr [ebx+4]
mov _Sign, edx ;a local variable to save the sign for later
mov eax, dword ptr [ebx+0]
and dx, 7FFFh
je Test_Exp_0_Special_Values
cmp dx, 7FFFh
je Test_Exp_7FFF_Special_Values
test ecx, ecx
jns Invalid_Value
Hummm Dave, i dont follow your argument. I remove the sign and if i may i go to
start. I read it again and i dont want to change it, for now.
Quote
the only special values for exponent = 0 are signed zeros
so - if the significand is not zero, increment the exponent and evaluate it the same as a normal
no, i dont want to follow this. What is there is what is there.
...
Quote
sooner or later, you are going to want the exponent with bit 0 right-justified :P
no, depends and we have it in a variable
You may replace test by or, i dont use it
Quotethe only special values for exponent = 0 are signed zeros
so - if the significand is not zero, increment the exponent and evaluate it the same as a normal
Quoteno, i dont want to follow this. What is there is what is there.
from the computation guide...
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_math.html (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_math.html)
denormals (aka subnormals) and pseudo-denormals are stored with the exponent adjusted to 0
to make them evaluate the same as a normal, add 1 to the exponent
the 0 value is used to signal that they are not normals
REAL4 and REAL8 denormals are similar, but you do not set the implicit integer bit
(http://img12.imageshack.us/img12/6/denorms.png)
Hi Dave,
Yesterday i had not enough time to pay attention
to some details. I wrote 14 procs to real10 and real8
and tested it.
Here, Table 1 is your table and
Table 2 is what i want to do
Table 1
Quote
REAL10
Exponent Significand Meaning
0000 0000_0000_0000_0000 Signed Zero
0000_0000_0000_0001 to 7FFF_FFFF_FFFF_FFFF Signed Denormal
8000_0000_0000_0000 to FFFF_FFFF_FFFF_FFFF Signed Pseudo-Denormal
0001 to 7FFE 0000_0000_0000_0000 to 7FFF_FFFF_FFFF_FFFF Invalid
8000_0000_0000_0000 to FFFF_FFFF_FFFF_FFFF Signed Normal
7FFF 0000_0000_0000_0000 to 7FFF_FFFF_FFFF_FFFF Invalid
8000_0000_0000_0000 Signed Infinity
8000_0000_0000_0001 to BFFF_FFFF_FFFF_FFFF Signaling NaN
C000_0000_0000_0000 Indefinite Quiet NaN
C000_0000_0000_0001 to FFFF_FFFF_FFFF_FFFF Quiet NaN
Table 2
Quote
REAL10
Exponent Significand Meaning
0000 0000_0000_0000_0000 ZERO
0000_0000_0000_0001 to 7FFF_FFFF_FFFF_FFFF Denormal
8000_0000_0000_0000 to FFFF_FFFF_FFFF_FFFF Pseudo-Denormal
0001 to 7FFE 0000_0000_0000_0000 to 7FFF_FFFF_FFFF_FFFF <-ERROR_1 (*)
8000_0000_0000_0000 to FFFF_FFFF_FFFF_FFFF <------- REAL10
7FFF 0000_0000_0000_0000 to 7FFF_FFFF_FFFF_FFFF ERROR_1
8000_0000_0000_0000 Infinity
8000_0000_0000_0001 to BFFF_FFFF_FFFF_FFFF ERROR_1
C000_0000_0000_0000 ERROR_1
C000_0000_0000_0001 to FFFF_FFFF_FFFF_FFFF ERROR_1
(*) particular case
To follow it better the 10 bytes pointed by EBX are:
string pointed by edi
mov eax, [ebx+0]
mov ecx, [ebx+4]
mov dx, [ebx+8] ; s+exponent
We have some ways to decode it. You have your own, of course.
But my idea is to think that the number we have is a real10 number.
It is not error, it is not infinity, it is not NAN, etc, it
is a real10 number.
Quote
In this way, first, we test exponent for 7FFFh.
. If exponent=7FFFh i assume "it_is_NAN", so... we have error/infinity.
. If ECX has sign bit set:
. If exponent <> 0 -> is real10 -> goto _start
. If = 0 -> is Pseudo-Denormal
. If ECX has NO sign bit set:
. If exponent <> 0 -> is error
. If = 0 -> is Zero/Denormal
Is zero if «or eax,ecx» is zero.
---------------------------------------------------------------------------------------
The problem is: what to do if it is Pseudo-Denormal or Denormal
and why. If we need to change the exponent, we need a local
variable to set the 10 bytes from where we load it to FPU.
The problem of sign: we may set it to string immediately.
If we use BCD we dont need the sign, but we may set it to
string immediately, also. If it is error, we remove it,
no problems: start at edi-1. If it is zero, also.
I think it is correct, now.
what's it called ?
"lemniscate"
you'd think i would have known that :(
ASCII = 0ECh, if you have the right font
in console mode, it displays correctly
but, if i redirect it to a text file, it is the letter "i" :redface:
i don't like that, because it's too close to the lower case "iota", which is used for (-1)1/2
(http://media.techtarget.com/WhatIs/images/lemniscate.gif)
(http://mathworld.wolfram.com/images/eps-gif/LemniscateToricSection_800.gif)
Here 3 macros to examine real10
Is there any problem ?
I like EXAMINE3REAL10.
Quote
EXAMINE1REAL10 MACRO ; 39 instructions
; --------------------------
; examine
; --------------------------
mov eax, dword ptr [ebx+0]
mov ecx, dword ptr [ebx+4]
mov dx, word ptr [ebx+8]
shl dx, 1 ; remove sign to carry
cmp dx, 0FFFEH ; <=> 7FFFh
je short _isNAN ; all = 1
; --------------------
; it is not NAN
; --------------------
and ecx, 80000000h
jz short _noECXsign
; --------------------------
; It must be Real10/Denormal
; --------------------------
or dx, dx
jnz short _start
jmp _isDenormal
_noECXsign: or dx, dx
jnz _erro1
; --------------------
; may be Zero/Denormal
; --------------------
or eax, ecx
jz _iszero
; --------------------
; may be Denormal
; or Pseudo-Denormal
; --------------------
_isDenormal:mov eax, dword ptr [ebx+0]
lea ebx, Real10Buf
;
mov [ebx+0], eax
mov [ebx+4], ecx
mov dx, word ptr [ebx+8]
mov dl, 1
mov word ptr [ebx+8], dx
jmp _start
; -------------------
; It is NAN
; -------------------
_isNAN: or eax, eax
jnz _erro1
; ---------------------
; eax= 0
; ecx must be 80000000h
; to be infinity
; ---------------------
xor ecx, 80000000h
jnz _erro1
; --------------
; It is infinity
; --------------
mov dx, word ptr [ebx+8]
mov al, '+'
and dx, 8000H
jz _isinfinity ; is +infinity
;------------
; is -infinity
; ------------
mov al, '-'
jmp _isinfinity ; is -infinity
; --------------------
; test for sign
; --------------------
_start: mov al, ' '
;
and word ptr [ebx+8], 8000H
jz short @F
;
mov al, '-'
@@: mov byte ptr [edi], al
add edi, 1
; ---------------------
; start load the real 10
; ---------------------
fld tbyte ptr [ebx] ; st(0) = X
ENDM
; --------------------------------------------------------------
another one
Quote
EXAMINE2REAL10 MACRO ; 37 instructions
; --------------------------
; examine
; --------------------------
mov eax, dword ptr [ebx+0]
mov ecx, dword ptr [ebx+4]
mov dx, word ptr [ebx+8]
shl dx, 1 ; remove sign -> carry
cmp dx, 0FFFEH
je short _isNAN ; all = 1
or dx, dx
jnz short _ECXsign
; --------------------
; may be Zero/Denormal
; --------------------
or eax, ecx
jz _iszero
; --------------------
; is Denormal
; or Pseudo-Denormal
; --------------------
mov eax, dword ptr [ebx+0]
lea ebx, Real10Buf
;
mov [ebx+0], eax
mov [ebx+4], ecx
mov dx, word ptr [ebx+8]
mov dl, 1
mov word ptr [ebx+8], dx
jmp _start
_ECXsign: and ecx, 80000000h
jnz short _start
jmp _erro1
; -------------------
; It is NAN
; -------------------
_isNAN: or eax, eax
jnz _erro1
; ---------------------
; eax= 0
; ecx must be 80000000h
; to be infinity
; ---------------------
xor ecx, 80000000h
jnz _erro1
; --------------
; It is infinity
; --------------
mov dx, word ptr [ebx+8]
mov al, '+'
and dx, 8000H
jz _isinfinity ; is +infinity
;------------
; is -infinity
; ------------
mov al, '-'
jmp _isinfinity ; is -infinity
; --------------------
; test for sign
; --------------------
_start: mov al, ' '
;
and word ptr [ebx+8], 8000H
jz short @F
;
mov al, '-'
@@: mov byte ptr [edi], al
add edi, 1
; ---------------------
; start load the real 10
; ---------------------
fld tbyte ptr [ebx] ; st(0) = X
ENDM
; ------------------------------------------------------------
another one
Quote
EXAMINE3REAL10 MACRO ; 31 instructions
; --------------------------
; examine
; --------------------------
mov ecx, dword ptr [ebx+4]
mov al, 20h
mov dx, word ptr [ebx+8]
shl dx, 1 ; remove sign -> carry
jnc short @F
mov al, '-'
;
@@: mov byte ptr [edi], al
add edi, 1
mov eax, dword ptr [ebx+0]
cmp dx, 0FFFEH
je short _isNAN ; all = 1
or dx, dx
jnz short _ECXsign
; --------------------
; may be Zero/Denormal
; --------------------
or eax, ecx
jz _iszero
; --------------------
; is Denormal
; or Pseudo-Denormal
; --------------------
mov eax, dword ptr [ebx+0]
lea ebx, Real10Buf ; local 10 bytes
; --------------------------------
; the sign is alredy in the buffer
; --------------------------------
add dx, 1
mov [ebx+0], eax
mov [ebx+4], ecx
mov word ptr [ebx+8], dx
jmp _start
_ECXsign: and ecx, 80000000h
jnz short _start
jmp _erro1
; -------------------
; It is NAN
; -------------------
_isNAN: or eax, eax
jnz _erro1
; ---------------------
; eax= 0
; ecx must be 80000000h
; to be infinity
; ---------------------
xor ecx, 80000000h
jnz _erro1
; --------------
; It is infinity
; --------------
jmp _isinfinity
; ---------------------
; start load the real 10
; ---------------------
_start: fld tbyte ptr [ebx] ; st(0) = X
ENDM
Hi Dave,
Quote from: dedndave on April 25, 2013, 01:00:35 AM
what's it called ?
"lemniscate"
yes, that's the lemniscate; a very interesting curve.
Gunther
Quote from: dedndave on April 25, 2013, 01:00:35 AM
what's it called ?
"lemniscate"
you'd think i would have known that :(
ASCII = 0ECh, if you have the right font
in console mode, it displays correctly
but, if i redirect it to a text file, it is the letter "i" :redface:
i don't like that, because it's too close to the lower case "iota", which is used for (-1)1/2
(http://media.techtarget.com/WhatIs/images/lemniscate.gif)
(http://mathworld.wolfram.com/images/eps-gif/LemniscateToricSection_800.gif)
:biggrin:
i guess you like geometric figures ! :greensml:
Quote from: RuiLoureiro on April 25, 2013, 01:10:22 AM
i guess you like geometric fugures ! :greensml:
oh, i do !
especially conic sections :P
oh - and boobs, of course (.)(.)
Rui, the only thing i would mention is.....
the REAL10 invalid values will never be generated by the FPU
however, NaN's (including indefinites) can be generated by the FPU
:redface:
hi Rui,
well, i have decimal digits - i just need to work on rounding and scientific format :P
0000_00000000_00000000: 00000000 00000002 +0
8000_00000000_00000000: 00000000 00000002 -0
0000_00000000_00000001: 00000000 00002CE7 364519953188247460252
0000_7FFFFFFF_FFFFFFFF: 00000000 00002CFA 336210314311209350589
0000_80000000_00000000: 00000000 00002CFA 336210314311209350626
0000_FFFFFFFF_FFFFFFFF: 00000000 00002CFA 672420628622418701216
0001_00000000_00000000: 00000006 00000007 Invalid
7FFE_7FFFFFFF_FFFFFFFF: 00000006 00000007 Invalid
0001_80000000_00000000: 00000000 00002CFA 336210314311209350626
4000_C90FDAA2_2168C235: 00000000 0000003F 314159265358979323851
7FFE_FFFFFFFF_FFFFFFFF: 00000000 00001345 118973149535723176502
7FFF_00000000_00000000: 00000006 00000007 Invalid
7FFF_7FFFFFFF_FFFFFFFF: 00000006 00000007 Invalid
7FFF_80000000_00000000: 00000001 00000002 +∞
FFFF_80000000_00000000: 00000001 00000002 -∞
7FFF_80000000_00000001: 00000005 00000004 SNaN
7FFF_BFFFFFFF_FFFFFFFF: 00000005 00000004 SNaN
7FFF_C0000000_00000000: 00000003 0000000F Indefinite QNaN
7FFF_C0000000_00000001: 00000004 00000004 QNaN
7FFF_FFFFFFFF_FFFFFFFF: 00000004 00000004 QNaN
00000000: 00000000 00000002 +0
80000000: 00000000 00000002 -0
00000001: 00000000 00000069 140129846432481707092
007FFFFF: 00000000 00000070 117549421069244107548
00800000: 00000000 00000070 117549435082228750796
BF800000: 00000000 00000018 100000000000000000000
7F7FFFFF: 00000000 00000027 340282346638528859811
7F800000: 00000001 00000002 +∞
FF800000: 00000001 00000002 -∞
7F800001: 00000002 00000003 NaN
7FFFFFFF: 00000002 00000003 NaN
00000000_00000000: 00000000 00000002 +0
80000000_00000000: 00000000 00000002 -0
00000000_00000001: 00000000 000002EF 494065645841246544176
000FFFFF_FFFFFFFF: 00000000 000002FF 222507385850720088902
00100000_00000000: 00000000 000002FF 222507385850720138309
BFF00000_00000000: 00000000 00000035 100000000000000000000
7FEFFFFF_FFFFFFFF: 00000000 00000135 179769313486231570814
7FF00000_00000000: 00000001 00000002 +∞
FFF00000_00000000: 00000001 00000002 -∞
7FF00000_00000001: 00000002 00000003 NaN
7FFFFFFF_FFFFFFFF: 00000002 00000003 NaN
after the hex real:, there are 2 dwords in hex
the first one is the status returned in EAX
the second one is the string length returned in ECX
although, i have truncated them all to 21 digits for testing
EDX points to the string