Hi all,
. Sometimes some friends here ask me where is the
ASM file ? Here we have the
converters from
real4 to string and from
string to real4,
without using the slow BCD method or ...
. Well, in this post i give
ConverterDD.inc <<<< replaced by ConverterDF.inc which contain the
ASM ConvertString4D procedure,
the
ASM ConvertFloat4DD procedure, constants
and macros.
. ConvertFloat converts to a string with a «dd ?» behind the address
. ConvertFloat4DD convert a dword real4 variable
into a string. In the text file CnvRealDD.txt
i try to explain something about that.
. I give also the ASM ConvertString4D and
a text file Converter4.txt
where i explain something about that.
. TestCnvDD12.exe shows conversions of some values
. TestCnvDD13.exe shows timing table of
some converters
. Please, could you run TestCnvDD13.exe
and show the results here ?
Thanks
Rui Loureiro
EDIT: please
replace $DECIMALPLACES_REAL4 equ 7
by
$DECIMALPLACES_REAL4 equ
6 and ADD this:
$OR_TRUNCATE$ equ 0C00h EDIT: i replaced ConvertFloat4DD by
ConvertFloat4DF----------------------------------------------------
Converting from real4 to string using FPU
----------------------------------------------------
Well, because there are people that want to try to write
his own converter or they are trying to learn,
i will try to remember some basic concepts.
This is just to answer some questions like
«why you do this ?», «why you do that ?» ...
RuiLoureiro
Quote
---------------------------------------------------------
A. Writing a real number in scientific notation
---------------------------------------------------------
A1. A number X= 1345.6789 written in scientific notation stands for:
X= 1.3456789 * 10^3
(move the point 3 places right to get the original and remove the power)
A number Y= 0.0013456789 written in scientific notation stands for:
Y= 1.3456789 * 10^-3
(move the point 3 places left to get the original and remove the power)
A2. Any number, in scientific notation, is written like this:
d.xxxxxxx * 10^n (it may start with a sign)
if n is positive: move the decimal point n places forward
if n is negative: move the decimal point n places backward
after moving we remove the power factor
to move backward, first add '0' behind (0000000000000d.xxxxxxx* 10^n)
dont forget this: any number inside FPU is in scientific notation
or floating point notation.
It has one integer digit plus dp decimal digits
The first digit is the first significant digit
and the others also, they dont run away from there.
------------------------------------------------------
B. scientific notation and dp decimal places
-------------------------------------------------------
Whenever we write a real number in scientific notation
we write it with:
. 1 integer digit ( ip not null) and
. dp decimal paces
Given a number X= 12345.67890123456789
we have:
X= 1.2345 6789 0123 4567 89 * 10^4
ip=1 and dp=18
Now, if we remove the last 11 digits we get
X= 1.2345 678 * 10^4
ip=1 and dp=7
Now, if we add 2 digits we get
X= 1.2345 678 90 * 10^4
ip=1 and dp=9
Note that, in scientific notation, ip is a contant 1
and dp is an important variable.
--------------------------------------------------------------------
C. Converting a real number X to an integer number I
with id integer digits
--------------------------------------------------------------------
Given a number X= 12345.67890123456789
we have:
X= 1.2345 6789 0123 4567 89 * 10^4
ip=1 and dp=18
. If we want an integer I with id digits
we want id= dp+1 =>
dp= id-1
. If we want an integer with id= 8 digits
it is the same to say we want dp=7
So we want this:
Y= 1.2345 678 * 10^4
(after '.' we write 7 digits)
dont forget this: any number inside FPU is in scientific notation
It has one integer digit plus dp decimal digits
-----------------------------------------------------------------------------
D. Converting any real X number written in scientific notation
into Y with exactly dp decimal places (Y not equal X)
-----------------------------------------------------------------------------
Given
X= d.xxxxxxx * 10^exponent (any integer exponent)
we need:
1) to remove (10^exponent) factor
which we do multiplying by
10^-exponent
to get
Xi= d.xxxxxxx * 10^exponent * 10^-exponent
( 10^exponent * 10^-exponent= 1)
= d.xxxxxxx
2) now, we have not the power factor
(and Xi is not equal X but has the same digits)
So, we need to move the point dp places right.
So, we need to multiply Y by 10^dp (dp is a positive integer)
Y= d.xxxxxxx * 10^dp (scientific notation with dp decimal places)
which is ( Y = dxxxxxxx. )
Point 1) and 2) means that we need to multiply X by
10^-exponent * 10^dp = 10^(dp-exponent)
If we do
--------------------------------
expscale = dp - exponent
--------------------------------
the rule is: we need to multiply X by 10^expscale
Y = X * 10^expscale
where
expscale = dp - exponent
This number Y has the same digits as X and (dp+1) total integer digits
For instance,
. if we want 7 decimal places, dp=7 we have
expscale = 7-exponent
Y = X * 10^expscale
and it has 8 integer digits.
. if we want 18 decimal places, dp=18 we have
expscale = 18-exponent
Y = X * 10^expscale
and it has 19 integer digits.
note: given a X number inside FPU we suppose we may do this
operations without error. If error, we cannot.
-----------------------------------------------------------------------------
E. Converting any real X number written in scientific notation
into an integer I with exactly id integer digits
------------------------------------------------------------------------------
As we have seen before
dp = id -1
and ------------------------
Y = X * 10^expscale where expscale = dp - exponent
------------------------
So, we need only to convert Y to an integer I.
FPU instruction fistp do this for us, we dont need to do nothing more.
In both following examples we want dp= 5 decimal places
EXAMPLE 1
--------------
X = 1.235 * 10^3 and dp=5 => expscale=5-3=2
Y = 1.235 * 10^3 * 10^2
= 1.235 * 10^5
= 123500.0
fistp should give I=123500
total number of digits should be = 6
exponent should be = 3 => print 4 integer digits
" 1 point
" (6-4) decimal digits
EXAMPLE 2
--------------
X = 1.235 * 10^-2 and dp=5 => expscale=5+2=7
Y = 1.235 * 10^-2 * 10^7
= 1.235 * 10^5
= 123500.0
fistp should give I=123500
total number of digits should be = 6
exponent should be = -2
so |exponent|= 2
|exponent|-1 = 1
=> print '0.'
print 1 '0'
" 4 decimal digits (to get 5 dp)
note: To get the exponent, we calculate log10(X) and return the
integer part or characteristic. See it below.
-----------------------------------
F. FPU and integer numbers
-----------------------------------
note: log is log10 (base 10), log2(X) (base 2)
Whenever we load an integer number from memory to FPU st(0) it is
converted to a real10 format
fild dword ptr Integer32 ; loads the Integer32 to a real10 format st(0)
Whenever we want to store into memory the value st(0), it is rounded to an integer32
fistp dword ptr Integer32 ; converts the real10 format st(0) to Integer32
frndint rounds st(0) to a corresponding integer and stores it in the same st(0)
note that we cannot load an integer from a register
To do it we should do this, for instance
push eax or
fild dword ptr [esp] mov Integer32, eax
add esp, 4 fild Integer32
-----------------------------------------
G. logarithm of base 10 function
dp, id and exponent
-----------------------------------------
note: to get the exponent we get the characteristic of log10(X)
which we get truncating the log10(X) (not rounding)
-------------------------------------------
CASE 1: the exponent is positive or null
-------------------------------------------
example 1
number X dp id log10(X) exponent
---------- ---- ---- ---------------- -----------
1.0 0 1 -> log(10^0) = 0 0
10.0 1 2 -> log(10^1) = 1 1
100.0 2 3 -> log(10^2) = 2 2
1000.0 3 4 -> log(10^3) = 3 3
100000... n n+1 -> log(10^n) = n n
---------------------------------------------------------------------------
rule 1: the number of integer digits is exponent+1 (=dp+1)
---------------------------------------------------------------------------
example 2
number X dp id log10(X) exponent
---------- ---- ---- --------------------------- -------------
1200.0 3 4 -> log(1.2*10^3) = 3.079181246047625 3
1999.9 3 4 -> log(1.999999*10^3) = 3.301029778516686 3
9999.9 3 4 -> log(9.999999*10^3) = 3.99999995657055 3
10000.0 4 5 -> log(1.0 10^4) = 4.0 4
..............................................................................
9999.9999 3 4 -> log(9.999999999999999*10^3) = 4.0 4 <---- except
If we truncate the log10(X) to an integer the exponent is = dp
So, the number X has
exponent+1 = dp+1 =id integer digits.
But there is a case where the exponent is 4 and dp=3.
Or
exponent = dp +1
that case is X=9.9999999999999 * 10^dp
but when we round it to integer we get this: round (9999.9)= 10000 = 10^4
and we have exponent= 4,
So,
-----------------------------------------------------------------
the number of integer digits is exponent+1 (rule 1)
-----------------------------------------------------------------
note: when we start the problem, we say we want to get dp decimal places
and the number of integer digits is id= dp+1.
At the end, we may get id-1.
But there, we dont use dp but the exponent
and
-----------------------------------
the rule 1: id = exponent+1
-----------------------------------
and because we know the total number of digits
------------------------------------
the decimal places is total-id
------------------------------------
------------------------------------
CASE 2: the exponent is negative
------------------------------------
id = number of digits in the buffer after converting
X to an integer with dp=7
exponent = characteristic of ( log10(X) ) from FPU
example 1
number X log10(X) id exponent
---------- ------------------- ---- ------------
0.1 -> log(10^-1) = -1 8 0 <--> exponent=exponent -1
0.01 -> log(10^-2) = -2 8 -2
0.001 -> log(10^-3) = -3 7 -2 <--> exponent=exponent -1 (id=dp)
0.0001 -> log(10^-4) = -4 8 -4
0.00001 -> log(10^-5) = -5 8 -5
0.000001 -> log(10^-6) = -6 8 -6
0.0000001 -> log(10^-7) = -7 7 -6 <--> exponent=exponent -1 (id=dp)
0.00000001 -> log(10^-8) = -8 8 -8
0.000000001 -> log(10^-9) = -9 8 -9
After correcting the exponent, (because id=dp or exponent=0)
|exponent|-1 is the number of '0' we should set after '0.'
For exponent = -4 => |exponent|-1 = 3 => 0. 000 1
example 2
corrected
number X log10(X) id exponent exponent
---------- ------------------- ---- ----------- ----------
0.2 -> log(2 10^-1) = 0 8 0 -1
0.02 -> log(2 10^-2) = -1 7 -1 -2
0.002 -> log(2 10^-3) = -2 7 -2 -3
0.0002 -> log(2 10^-4) = -3 7 -3 -4
0.00002 -> log(2 10^-5) = -4 7 -4 -5
0.000002 -> log(2 10^-6) = -5 7 -5 -6
0.0000002 -> log(2 10^-7) = -6 7 -6 -7
0.00000002 -> log(2 10^-8) = -7 7 -7 -8
0.000000002 -> log(2 10^-9) = -8 7 -8 -9
example 3
corrected
number X log10(X) id exponent exponent
---------- ------------------- ---- ----------- ----------
0.d -> log(5 10^-1) = 0 8 0 -1
0.0d -> log(5 10^-2) = -1 7 -1 -2
0.00d -> log(5 10^-3) = -2 7 -2 -3
0.000d -> log(5 10^-4) = -3 7 -3 -4
0.0000d -> log(5 10^-5) = -4 7 -4 -5
0.00000d -> log(5 10^-6) = -5 7 -5 -6
0.000000d -> log(5 10^-7) = -6 7 -6 -7
0.0000000d -> log(5 10^-8) = -7 7 -7 -8
0.00000000d -> log(5 10^-9) = -8 7 -8 -9
«d» is 2, 3, 4, 5, 6, 7, 8 or 9
example 4
corrected
number X log10(X) id exponent exponent
---------- ------------------- ---- ----------- ----------
0.9 -> log(9 10^-1) = 0 8 0 -1
0.09 -> log(9 10^-2) = -1 7 -1 -2
0.009 -> log(9 10^-3) = -2 7 -2 -3
0.0009 -> log(9 10^-4) = -3 7 -3 -4
0.00009 -> log(9 10^-5) = -4 7 -4 -5
0.000009 -> log(9 10^-6) = -5 7 -5 -6
0.0000009 -> log(9 10^-7) = -6 7 -6 -7
0.00000009 -> log(9 10^-8) = -7 7 -7 -8
0.000000009 -> log(9 10^-9) = -8 7 -8 -9
After correcting the exponent, (because id=dp or exponent=0)
|exponent|-1 is the number of '0' we should set after '0.'
For exponent = -4 => |exponent|-1 = 3 => 0. 000 1
--------------------------------------------------------------------------------------
rule 2: the number of zeroes after '0.' is |exponent|-1 (corrected exponent)
---------------------------------------------------------------------------------------
note 1: we correct expscale only if the logarithm is negative and exponent =0.
So, in this case, we get dp digits only and not dp+1.
In all other cases exponent is not corrected before getting the integer.
0.001 = 10^-3 the exponent is =-2 => expscale=7+2=9
10^-3 * 10^9 = 10^6=1000000 instead of 10^7
EDIT:
ConverterDD was replaced by
ConverterDF (some bugs/fails was corrected: test for -0.0 and PowerTable: 1 is 1.0 and 10 is 10.0)
Now we may use
ConvertFloat4DF or
ConvertReal4DF
Works fine, Rui :t
0.1
0.0099999
0.001
0.0000999
0.0000099
0.0000001
0.0000001
9.9999999E-09
9.9999997E-10
Hi Jochen,
works very fine! :icon14:
Please, read the text file or the post text
0.1
0.01
0.001
0.0001
0.00001
0.000001
0.0000001
1.0E-08
1.0E-09
*** STOP - ConvertFloat4DF ***
0.2
0.02
0.002
0.0002
0.00002
0.000002
0.0000002
2.0E-08
2.0E-09
*** STOP - ConvertFloat4DF ***
0.3
0.03
0.003
0.0003
0.00003
0.000003
0.0000003
3.0E-08
3.0E-09
*** STOP - ConvertFloat4DF ***
0.4
0.04
0.004
0.0004
0.00004
0.000004
0.0000004
4.0E-08
4.0E-09
*** STOP - ConvertFloat4DF ***
0.5
0.05
0.005
0.0005
0.00005
0.000005
0.0000005
5.0E-08
5.0E-09
*** STOP - ConvertFloat4DF ***
0.6
0.06
0.006
0.0006
0.00006
0.000006
0.0000006
6.0E-08
6.0E-09
*** STOP - ConvertFloat4DF ***
0.6999999
0.07
0.007
0.0007
0.00007
0.000007
0.0000007
7.0E-08
7.0E-09
*** STOP - ConvertFloat4DF ***
0.8
0.08
0.008
0.0008
0.00008
0.000008
0.0000008
8.0E-08
8.0E-09
*** STOP - ConvertFloat4DF ***
0.8999999
0.09
0.009
0.0009
0.00009
0.000009
0.0000009
9.0E-08
9.0E-09
*** STOP - ConvertFloat4DF ***
-1.2345678
-12.345678
-123.45678
-1234.5677
-12345.678
-123456.78
-1234567.8
-12345678
*** STOP - ConvertFloat4DF ***
-12.0
-120.0
-1200.0
-12000.0
-120000.0
-1200000.0
-12000000
-1.2E+08
*** STOP - ConvertFloat4DF ***
-9.8999996
-99.900002
-999.90002
-9999.9004
-99999.898
-999999.88
-10000000
-1.0E+08
*** STOP - ConvertFloat4DF --- E N D ---***
Quote
---------------------------------------------------------
H. Some important values and functions
----------------------------------------------------------
log10(d*10^n)= log10(d)+log10(10^n) (n is any integer)
= log10(d)+n
if 0 < x < 10
=>
0 < log10(x) < 1
log(1.0)= 0
log(2.0)= 0.3
log(3.0)= 0.5
log(4.0)= 0.6
log(5.0)= 0.7
log(6.0)= 0.78
log(7.0)= 0.85
log(8.0)= 0.9
log(9.0)= 0.954
if x < 1
=> log10(x) is negative
log10(X) = log10(2) * log2(X)
fldlg2 = log10(2) ; load to st(0) log10(2)
fyl2x = st(1) * log2[st(0)] ; result in st(0) and pop new st(0) is old st(1)
--------------------
calculating log10(|X|)
--------------------
fld X ; X in st(1)
fldlg2
fld st(1)
fabs ; |X|
fyl2x ; log10(X) in st(0)
---------------------------
truncate the characteristic
to get the exponent
---------------------------
------------------
moving to exponent
------------------
fist exponent
-----------------
Is it negative ?
-----------------
test it and remove st(0) so the new
st(0) is exactly X we need it to
multiply by 10^expscale
-----------------------------------------------------------------
I. One idea to convert a real4 number X into a string
with exacly dp decimal places
-----------------------------------------------------------------
note: if the number is not in a memory variable
pass it to a memory variable first because
FPU cannot load it from registers.
Starting point:
We need to define the constants/variables:
String_Buffer_Length = 10 (for instance)
dp = 7 (number of decimal places => 8 integer digits)
(if we want to define the ni=number of integer digits
we do dp=ni-1)
exponent = ? (=dword -we need to get it from X)
expscale = ? (=dword -we need to define it later)
integer = ? (=dword -to save the integer with ni integer digits)
string = ? ( a buffer for String_Buffer_Length digits)
I1. Load the number into eax and examine it.
If it is a number goto step I2;
I2. Load the memory variable into FPU st(0)
make a copy and get the exponent value to exponent
and define
expscale = dp - exponent
I3. At this point we know dp, exponent, expscale and we have X in st(0)
Load 10^expscale or calculate it and multiply by X
st(1) ; X
st(0) ; 10^expscale
fmul ; st(0)= Z = X *10^expscale
I4. At this point we need to store st(0) into integer
fistp integer
I5. If not error
mov eax, integer
and convert eax into string from the last position to a position
of the first digit and get the number of digits (ebx for instance).
At this point we know the string and
ebx = number of digits in the buffer
I6. Now we must decide if we format it:
1) only in scientific notation;
2) in regular notation or scientific notation.
For instance we decide:
regular notation: if the exponent>=0 is less than or equal dp
if the exponent<0 and |exponent| is less than or equal 3
scientific notation: if not regular notation
I7. To format, we have 3 cases
1) the exponent<0 and |exponent| is less than or equal 3
exponent |exponent|-1
-------- -------------
-1 0 -> 0.dabcefg (dp decimal digits)
-2 1 -> 0.0dabcef (dp decimal digits)
-3 2 -> 0.00dabce (dp decimal digits)
so, after moving '0.' we should move
|exponent|-1 digits '0'
and
[dp - (|exponent|-1)] digits
2) the exponent>=0 is less than or equal dp
. we should move exponent+1 integer digits
. move '.'
. move ebx-(exponent+1) digits
3) scientific notation
. we should move first digit
. move '.'
. move edx digits
. move exponent part
----------------------------------
J. Format string in assembly
----------------------------------
note: esi points to string buffer
edi points to output string
----------------------------------------------
J.1 Format in regular notation - exponent < 0
ecx= |exponent| edx=decimal places
----------------------------------------------
mov word ptr [edi], '.0'
add edi, 2
; ------------------------------
; If exponent = -1 it is 0.ddddd
; If exponent = -2 it is 0.0dddd
; and so on
; ------------------------------
sub ecx, 1
jz short _movedecimal
sub edx, ecx
jnz short @F
mov edx, 1
; -------------------------
; insert 0
; -------------------------
@@: mov byte ptr [edi], '0'
add edi, 1
sub ecx, 1
jnz short @B
_movedecimal: movzx eax, byte ptr [esi]
mov byte ptr [edi], al
add edi, 1
add esi, 1
sub edx, 1
jnz short _movedecimal
jz short _finish
------------------------------------------------
J.2 Format in regular notation - exponent >=0
ebx = total number of digits, ecx= exponent
------------------------------------------------
add ecx, 1 ; ecx= number of integer digits
sub ebx, ecx ; ebx= number of decimal digits
;
@@: movzx eax, byte ptr [esi]
mov byte ptr [edi], al
add edi, 1
add esi, 1
sub ecx, 1
jnz short @B
;
cmp ebx, 0
jle _finish
mov byte ptr [edi], '.'
add edi, 1
;
@@: movzx eax, byte ptr [esi]
mov byte ptr [edi], al
add edi, 1
add esi, 1
;
sub ebx, 1
jnz short @B
jmp short _finish
-----------------------------------
J.3 Format in scientific notation
-----------------------------------
_isscientific: cmp edx, ebx
jb short @F
sub edx, 1
@@: movzx eax, byte ptr [esi]
mov ah, '.'
add esi, 1
;
mov word ptr [edi], ax
add edi, 2
@@: movzx eax, byte ptr [esi]
mov byte ptr [edi], al
;
add edi, 1
add esi, 1
sub edx, 1
jnz short @B
; ------------------
; Move exponent part
; ------------------
_finish:
RuiLoureiro
definition of an integer value log10 can be done without any fyl2x -- try to use integer multiplication of the order on the magic integer constant 4D10h = log10 (2) * 65536
This method is used in the crt_sprintf function.
Mikl__
I dont know magic numbers. What we may replace ?
does it take less cycles ?
Quote from: jj2007 on April 19, 2013, 06:18:53 AM
Works fine, Rui :t
0.1
0.0099999
0.001
0.0000999
0.0000099
0.0000001
0.0000001
9.9999999E-09
9.9999997E-10
Jochen,
Sorry, but i posted
ConvertFloat4DD that makes some errors
now
i post it again with a new file.
The problem is with 0.1, 0.01, 0.001, 0.0001 etc
If you read section F, CASE 2 (first post color RED), you find the problem
and one solution. We use characteristic(log10(X))=exponent
to get expscale without correcting exponent (except case 0) (only in DF not in this DD).
After this, if the case is 0.1, 0.01, 0.001, 0.0001 etc
and id=dp we correct exponent and the problem is solved.
I tryed many other solutions without success. If we use
expscale=dp it doesnt give a good solution (and it s not
correct but somebody do this). If the exponent
is negative and we correct the values it doesnt give a good
solution also.
The main problem seems to be this: if x=0.01=10^-2 for instance
we have not a log10 function that gives integer(log(x))=-2.
On the paper we solve it well, but with FPU its not easy.EDIT: please
add this constant to file
ConverterDD.inc $OR_TRUNCATE$ equ 0C00h ; code it for truncating
please
replace $DECIMALPLACES_REAL4 equ 7
by
$DECIMALPLACES_REAL4 equ
6 Quote
***** Time table *****
437 cycles, ConvertFloat4DF, direct
472 cycles, ConvertFloat4DD, direct
876 cycles, ConvertFloat4BD, BCD
1058 cycles, ConvertFloat4ZX, BCD
1092 cycles, ConvertFloat4Z, BCD
1262 cycles, ConvertFloat4BX, BCD
3011 cycles, ConvertFloat4, BCD
********** END **********
ConvertFloat4DD values:
-1 = exponent
8 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.1
-3 = exponent
10 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.01
-3 = exponent
10 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.001
-5 = exponent
12 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0001
-6 = exponent
13 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.00001
-7 = exponent
14 = expscale
7 = edx decimal places
9 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
1.0E-06
-7 = exponent
14 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0000001
*** STOP - ConvertFloat4DD ***
-9 = exponent
16 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
1.0E-08
-10 = exponent
17 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
1.0E-09
*** STOP - ConvertFloat4DD ***
-1 = exponent
8 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.2
-2 = exponent
9 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.02
-3 = exponent
10 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.002
-4 = exponent
11 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0001999
-5 = exponent
12 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0000199
-6 = exponent
13 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.000002
-7 = exponent
14 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0000002
-8 = exponent
15 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
2.0E-08
-9 = exponent
16 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
1.9999999E-09
*** STOP - ConvertFloat4DD ***
-1 = exponent
8 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.3
-2 = exponent
9 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0299999
-3 = exponent
10 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.003
-4 = exponent
11 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0003
-5 = exponent
12 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0000299
-6 = exponent
13 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.000003
-7 = exponent
14 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0000003
-8 = exponent
15 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
2.9999999E-08
-9 = exponent
16 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
3.0E-09
*** STOP - ConvertFloat4DD ***
-1 = exponent
8 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.4
-2 = exponent
9 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0399999
-3 = exponent
10 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.004
-4 = exponent
11 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0003999
-5 = exponent
12 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0000399
-6 = exponent
13 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.000004
-7 = exponent
14 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0000004
-8 = exponent
15 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
4.0E-08
-9 = exponent
16 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
3.9999999E-09
*** STOP - ConvertFloat4DD ***
-1 = exponent
8 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.5
-2 = exponent
9 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.05
-3 = exponent
10 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0049999
-4 = exponent
11 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0005
-5 = exponent
12 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0000499
-6 = exponent
13 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0000049
-7 = exponent
14 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0000005
-8 = exponent
15 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
5.0000001E-08
-9 = exponent
16 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
5.0E-09
*** STOP - ConvertFloat4DD ***
-1 = exponent
8 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.6
-2 = exponent
9 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0599999
-3 = exponent
10 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.006
-4 = exponent
11 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0006
-5 = exponent
12 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0000599
-6 = exponent
13 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.000006
-7 = exponent
14 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0000006
-8 = exponent
15 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
5.9999998E-08
-9 = exponent
16 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
6.0000001E-09
*** STOP - ConvertFloat4DD ***
-1 = exponent
8 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.6999999
-2 = exponent
9 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.07
-3 = exponent
10 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.007
-4 = exponent
11 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0006999
-5 = exponent
12 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.00007
-6 = exponent
13 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.000007
-7 = exponent
14 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0000006
-8 = exponent
15 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
6.9999999E-08
-9 = exponent
16 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
7.0000001E-09
*** STOP - ConvertFloat4DD ***
-1 = exponent
8 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.8
-2 = exponent
9 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0799999
-3 = exponent
10 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.008
-4 = exponent
11 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0007999
-5 = exponent
12 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0000799
-6 = exponent
13 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.000008
-7 = exponent
14 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0000008
-8 = exponent
15 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
8.0E-08
-9 = exponent
16 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
7.9999998E-09
*** STOP - ConvertFloat4DD ***
-1 = exponent
8 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.8999999
-2 = exponent
9 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.09
-3 = exponent
10 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0089999
-4 = exponent
11 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0008999
-5 = exponent
12 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.00009
-6 = exponent
13 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.000009
-7 = exponent
14 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
0.0000008
-8 = exponent
15 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
9.0E-08
-9 = exponent
16 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
8.9999999E-09
*** STOP - ConvertFloat4DD ***
0 = exponent
7 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-1.2345678
1 = exponent
6 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-12.345678
2 = exponent
5 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-123.45678
3 = exponent
4 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-1234.5677
4 = exponent
3 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-12345.678
5 = exponent
2 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-123456.78
6 = exponent
1 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-1234567.8
7 = exponent
0 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-12345678
*** STOP - ConvertFloat4DD ***
1 = exponent
6 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-12.0
2 = exponent
5 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-120.0
3 = exponent
4 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-1200.0
4 = exponent
3 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-12000.0
5 = exponent
2 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-120000.0
6 = exponent
1 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-1200000.0
7 = exponent
0 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-12000000
8 = exponent
-1 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-1.2E+08
*** STOP - ConvertFloat4DD ***
0 = exponent
7 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-9.8999996
1 = exponent
6 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-99.900002
2 = exponent
5 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-999.90002
3 = exponent
4 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-9999.9004
4 = exponent
3 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-99999.898
5 = exponent
2 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-999999.88
7 = exponent
0 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-10000000
8 = exponent
-1 = expscale
7 = edx decimal places
8 = ebx total digits
--- TOTAL and DECIMAL PLACES ---
-1.0E+08
*** STOP - ConvertFloat4DD --- E N D ---***
hi Rui
"magic numbers" aren't really magic - lol
but, the MUL and IMUL instructions are much faster than DIV
so, if the divisor is a constant, we can multiply by (the inverse of the divisor) x (2^n)
here's a simple example...
;divide by 10,000
;ECX = 87654321
mov eax,0D1B71759h ;3,518,437,209 = 2^45/10,000
mul ecx
shr edx,13
imul eax,edx,10000
sub ecx,eax
;ECX = remainder (4321)
;EDX = quotient (8765)
notice that we used 2^45 as our power-of-2 multiplier
after the MUL, we use the 32-bit register displacement of EDX:EAX for 32 of these
and SHR by 13 to get the rest (32+13=45)
then, IMUL and SUB are used to calculate the remainder
qWord has a great program for calculating the magic numbers - let me find it......
http://www.masmforum.com/archive2012/6717_MagicNumber64.zip (http://www.masmforum.com/archive2012/6717_MagicNumber64.zip)
i might add that qWord, drizz, Jochen and others have done some rather exotic extensions on this
i used a lot of help from drizz to write my ling long kai fang routines :t
:biggrin:
Hi Dave,
1. read my last post again, please
2. Its very fine ! But i tryed to get log2(X) for 32 bits
and its not there, it runs away ! Do you know
where is it resting ? :t
More: i read what qWord did and very good
what this u64_log2 does ? Do you know Dave ?
u64_log2 proc uses eax ecx edi esi lp_m64_Dest:DWORD,lp_qWord:DWORD
well,
.data
_lp_qWord dq 10.2
_lp_m64_Dest dq ?
invoke u64_log2, addr _lp_m64_Dest, addr lp_qWord
what kind of result in _lp_m64_Dest ?
where did you get the u64_log2 function ?
i don't see it posted :redface:
ohhhh - found it - let me play with it for a few minutes :P
it appears to work on 64-bit unsigned integers
it preforms the function:
l = log2(t)+1
where:
l = _lp_m64_Dest
t = lp_qWord
it uses the BSR instruction to find the first bit set
used to normalize, i guess
:biggrin:
Here is the better
ConvertFloat4DF converter
to replace
ConvertFloat4DD.
The text i wrote here is about this
DF converter, but the general questions is
for all of this type. You may improve it !
All convertions seems to be perfect.
We need
only to set dp=6 digits and not 7 (=> id=8).
Quote
0.1
0.01
0.001
0.0001
0.00001
0.000001
1.0E-07
1.0E-08
1.0E-09
*** STOP - ConvertFloat4DF ***
0.1
0.01
0.001
0.0001
0.00001
0.000001
1.0E-07
1.0E-08
1.0E-09
*** STOP - ConvertFloat4DR ***
1152 cycles, ConvertFloat4ZX, _Real4_2
3063 cycles, ConvertFloat4, _Real4_2
1186 cycles, ConvertFloat4Z, _Real4_2
860 cycles, ConvertFloat4BD, _Real4_2
1253 cycles, ConvertFloat4BX, _Real4_2
418 cycles, ConvertFloat4DF, _Real4_2
331 cycles, ConvertFloat4DR, _Real4_2
*** Press any key to get the time table ***
***** Time table *****
331 cycles, ConvertFloat4DR, direct
418 cycles, ConvertFloat4DF, direct
860 cycles, ConvertFloat4BD, BCD
1152 cycles, ConvertFloat4ZX, BCD
1186 cycles, ConvertFloat4Z, BCD
1253 cycles, ConvertFloat4BX, BCD
3063 cycles, ConvertFloat4, BCD
********** END *********
Here some conversions made by
ConvertFloat4DF
0.1
0.01
0.001
0.0001
0.00001
0.000001
1.0E-07
1.0E-08
1.0E-09
*** STOP - ConvertFloat4DF ***
0.2
0.02
0.002
0.0002
0.00002
0.000002
2.0E-07
2.0E-08
2.0E-09
*** STOP - ConvertFloat4DF ***
0.3
0.03
0.003
0.0003
0.00003
0.000003
3.0E-07
3.0E-08
3.0E-09
*** STOP - ConvertFloat4DF ***
0.4
0.04
0.004
0.0004
0.00004
0.000004
4.0E-07
4.0E-08
4.0E-09
*** STOP - ConvertFloat4DF ***
0.5
0.05
0.005
0.0005
0.00005
0.000005
5.0E-07
5.0E-08
5.0E-09
*** STOP - ConvertFloat4DF ***
0.6
0.06
0.006
0.0006
0.00006
0.000006
6.0E-07
6.0E-08
6.0E-09
*** STOP - ConvertFloat4DF ***
0.7
0.07
0.007
0.0007
0.00007
0.000007
7.0E-07
7.0E-08
7.0E-09
*** STOP - ConvertFloat4DF ***
0.8
0.08
0.008
0.0008
0.00008
0.000008
8.0E-07
8.0E-08
8.0E-09
*** STOP - ConvertFloat4DF ***
0.9
0.09
0.009
0.0009
0.00009
0.000009
9.0E-07
9.0E-08
9.0E-09
*** STOP - ConvertFloat4DF ***
-1.234568
-12.34568
-123.4568
-1234.568
-12345.68
-123456.8
-1234568
-1.234568E+07
*** STOP - ConvertFloat4DF ***
-12.0
-120.0
-1200.0
-12000.0
-120000.0
-1200000
-1.2E+07
-1.2E+08
*** STOP - ConvertFloat4DF ***
-99.0
-999.0
-9999.0
-99999.0
-999999
-1000000
-1.0E+07
-1.0E+08
*** STOP - ConvertFloat4DF --- E N D ---***
I improved
ConvertFloat4DF.
This is the new version
Use TestCnvDD12_DF.exe to see
some results
-------------------------------------------
Project a converter real4 to string-------------------------------------------
Quote
X = d.xxxxx * 10^exponent
dp = decimal places
id = integer digits (real4 max=7)
= dp+1 (exponent>=0)
1. Define dp from 2 to 6
2. Get exponent taking the integer part
of log10(X) <--------------- Procedure 1
3. Define expscale = dp - exponent
4. Calculate X * 10^expscale and
get the integer part I
5. Convert I to a string of digits
and get nid = number of integer
digits
6. If nid=dp correct the exponent
exponent = exponent -1
7. Format the string
-------------------------------
Before correction we get
using Procedure 1
-------------------------------
exponent dp nid
------------------ integer digits ---
1. 10^0 1.0 0 6 7
2. 10^0 2.0 0 6 7 in all cases
3. 10^0 3.0 0 6 7 is
4. 10^0 4.0 1 6 6
5. 10^0 5.0 1 6 6 exponent+1
6. 10^0 6.0 1 6 6
7. 10^0 7.0 1 6 6
8. 10^0 8.0 1 6 6
9. 10^0 9.0 1 6 6
--------------------------decimal '0' ------
1. 10^-1 0.1 -1 6 7
2. 10^-1 0.2 -1 6 7 in all cases
3. 10^-1 0.3 -1 6 7 is
4. 10^-1 0.4 0 6 6
5. 10^-1 0.5 0 6 6 |exponent|-1
6. 10^-1 0.6 0 6 6
7. 10^-1 0.7 0 6 6
8. 10^-1 0.8 0 6 6
9. 10^-1 0.9 0 6 6
Procedure 1 to get the exponent
------------------------------------------
fld dword ptr [ebx]
fldlg2
fld st(1)
fabs
fyl2x
SETTRUNCATE oldcw, truncw
fistp exponent
fldcw oldcw
----------------------------------------
0.1
0.01
0.001
0.0001
0.00001
0.000001
1.0E-07
1.0E-08
1.0E-09
*** STOP - ConvertFloat4DF ***
0.1
0.01
0.001
0.0001
0.00001
0.000001
1.0E-07
1.0E-08
1.0E-09
*** STOP - ConvertFloat4DR ***
1150 cycles, ConvertFloat4ZX, _Real4_2
3061 cycles, ConvertFloat4, _Real4_2
1185 cycles, ConvertFloat4Z, _Real4_2
855 cycles, ConvertFloat4BD, _Real4_2
1252 cycles, ConvertFloat4BX, _Real4_2
409 cycles, ConvertFloat4DF, _Real4_2
323 cycles, ConvertFloat4DR, _Real4_2
*** Press any key to get the time table ***
***** Time table *****
323 cycles, ConvertFloat4DR, direct
409 cycles, ConvertFloat4DF, direct
855 cycles, ConvertFloat4BD, BCD
1150 cycles, ConvertFloat4ZX, BCD
1185 cycles, ConvertFloat4Z, BCD
1252 cycles, ConvertFloat4BX, BCD
3061 cycles, ConvertFloat4, BCD
********** END **********
Hello again
Well, to complete the explanation i gave so far,
i need to say that the previous point 6
« 6. If nid= dp correct the exponent
exponent = exponent -1
»
should/may be replaced by an equation that i will try
to explain
As we said before in section E
«
--------------------------------------------------------------
E. Converting any real X number written in scientific notation
into an integer I with exactly id integer digits
--------------------------------------------------------------
As we have seen before
dp = id -1
and --------------------------------
Y = X * 10^expscale where expscale = dp - exponent
--------------------------------
So, we need only to convert Y to an integer I.
»
we get I=integer [X * 10^expscale].
So, to reverse the operation, we need to multiply I
by -expscale, but this time, using the id we got.
Replacing dp in the previous equation, we have
expscale = dp - exponent= id-1 - exponent
----------------------------------
=> exponent = id-1-expscale (id=integer digits we got)
----------------------------------
; ------------------------------------------
; ebx= number of integer digits in I
; ------------------------------------------
mov eax, ebx
sub eax, expscale
sub eax, 1
mov exponent, eax
-------------------------------
that code replace this:
mov eax, exponent
cmp edx, ebx
jne short @F
; --------------------------
; Correct the exponent
; --------------------------
sub eax, 1
mov exponent, eax
@@:
-------------------------------------------------
To be honest, when i started this question,
the problem was to write assembly using FPU
not to solve equations.
But the log function took me to this way and
we had to solve it.
When we read procedures to do this, my
impression is that we need to do some "arakiri".
The last generation dont like to think because
"google it and here it is" and they have not
time to understand it deeply, i think.
------------------------------------------------
Good luck :t
Rui Loureiro
Quote from: RuiLoureiro on April 22, 2013, 03:49:31 AMBut the log function took me to this way and
we had to solve it.
When we read procedures to do this, my
impression is that we need to do some "arakiri".
If you are referring to u64_log2, it does exactly what it is designed for, even if the naming convention is miserable (like some other things in that project). If you are interested in a replacement for the FPU log2 function, you might try it with an table based approximation.
BTW: arakiri -> hara-kiri?
Quote from: qWord on April 22, 2013, 04:17:04 PM
Quote from: RuiLoureiro on April 22, 2013, 03:49:31 AM
If you are referring to u64_log2, it does exactly what it is designed for, even if the naming convention is miserable (like some other things in that project). If you are interested in a replacement for the FPU log2 function, you might try it with an table based approximation.
BTW: arakiri -> hara-kiri?
:biggrin:
Hello qWord,
"
arakiri" is a kind of sport we do when
we read some procedures ... :greensml:
but it may be what we want !
I read yours, good, no problems! :t
I need to replace log2(X) in 32 bites not 64
but it should be simple i dont know if it
is possible
"hara-kiri" :badgrin:
that is a simple function, Rui
for 32-bits, not even sure i would put it in a PROC - maybe a macro
you just want to use the BSR instruction :t
Quote from: dedndave on April 23, 2013, 05:26:20 AM
"hara-kiri" :badgrin:
it is what you do, Dave; i do arakiri, a kind of hara_kiri ! :P
not me :biggrin:
my wife won't let me :(
Here are some timings to convert
Real10 to string for
19,
18,
10 digits
note: CT -compress table
Quote
19 digits
3.141592653589793238 <---- pi 19 digits
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
*** STOP - ConvertFloat10DF ***
3.141592653589793238
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
*** STOP - ConvertFloat10DR ***
3.141592653589793238
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
*** STOP - ConvertFloat10DX ***
3.141592653589793238
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
*** STOP - ConvertFloat10DY ***
2384 cycles, ConvertFloat10ZX, _Real10_2
3706 cycles, ConvertFloat10, _Real10_2
2380 cycles, ConvertFloat10Z, _Real10_2
2272 cycles, ConvertFloat10DF, _Real10_2
2169 cycles, ConvertFloat10DR, _Real10_2
2602 cycles, ConvertFloat10BX, _Real10_2
2681 cycles, ConvertFloat10BF, _Real10_2
2647 cycles, ConvertFloat10BY, _Real10_2
2128 cycles, ConvertFloat10DY, _Real10_2
2146 cycles, ConvertFloat10DX, _Real10_2
2400 cycles, ConvertFloat10CT, _Real10_2
*** Press any key to get the time table ***
***** Time table *****
2128 cycles, ConvertFloat10DY, direct, esp
2146 cycles, ConvertFloat10DX, direct, esp
2169 cycles, ConvertFloat10DR, direct, ebp
2272 cycles, ConvertFloat10DF, direct, ebp
2380 cycles, ConvertFloat10Z, BCD
2384 cycles, ConvertFloat10ZX, BCD
2400 cycles, ConvertFloat10CT, BCD, esp, CT
2602 cycles, ConvertFloat10BX, BCD
2647 cycles, ConvertFloat10BY, BCD, esp
2681 cycles, ConvertFloat10BF, BCD
3706 cycles, ConvertFloat10, BCD, Save FPU
********** END **********
; ##########################################
Quote
18 digits
3.14159265358979324 <---- pi 18 digits
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
*** STOP - ConvertFloat10DF ***
3.14159265358979324
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
*** STOP - ConvertFloat10DR ***
3.14159265358979324
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
*** STOP - ConvertFloat10DX ***
3.14159265358979324
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
*** STOP - ConvertFloat10DY ***
1067 cycles, ConvertFloat10ZX, _Real10_2
2958 cycles, ConvertFloat10, _Real10_2
1083 cycles, ConvertFloat10Z, _Real10_2
2154 cycles, ConvertFloat10DF, _Real10_2
2021 cycles, ConvertFloat10DR, _Real10_2
863 cycles, ConvertFloat10BX, _Real10_2
855 cycles, ConvertFloat10BF, _Real10_2
896 cycles, ConvertFloat10BY, _Real10_2
1909 cycles, ConvertFloat10DY, _Real10_2
1910 cycles, ConvertFloat10DX, _Real10_2
883 cycles, ConvertFloat10CT, _Real10_2
*** Press any key to get the time table ***
***** Time table *****
855 cycles, ConvertFloat10BF, BCD
863 cycles, ConvertFloat10BX, BCD
883 cycles, ConvertFloat10CT, BCD, esp, CT
896 cycles, ConvertFloat10BY, BCD, esp
1067 cycles, ConvertFloat10ZX, BCD
1083 cycles, ConvertFloat10Z, BCD
1909 cycles, ConvertFloat10DY, direct, esp
1910 cycles, ConvertFloat10DX, direct, esp
2021 cycles, ConvertFloat10DR, direct, ebp
2154 cycles, ConvertFloat10DF, direct, ebp
2958 cycles, ConvertFloat10, BCD, Save FPU
********** END **********
; #########################################
Quote
10 digits
3.141592654 <---- pi 10 digits
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
*** STOP - ConvertFloat10DF ***
3.141592654
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
*** STOP - ConvertFloat10DR ***
3.141592654
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
*** STOP - ConvertFloat10DX ***
3.141592654
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
*** STOP - ConvertFloat10DY ***
1132 cycles, ConvertFloat10ZX, _Real10_2
3015 cycles, ConvertFloat10, _Real10_2
1146 cycles, ConvertFloat10Z, _Real10_2
638 cycles, ConvertFloat10DF, _Real10_2
505 cycles, ConvertFloat10DR, _Real10_2
759 cycles, ConvertFloat10BX, _Real10_2
769 cycles, ConvertFloat10BF, _Real10_2
758 cycles, ConvertFloat10BY, _Real10_2
500 cycles, ConvertFloat10DY, _Real10_2
490 cycles, ConvertFloat10DX, _Real10_2
748 cycles, ConvertFloat10CT, _Real10_2
*** Press any key to get the time table ***
***** Time table *****
490 cycles, ConvertFloat10DX, direct, esp
500 cycles, ConvertFloat10DY, direct, esp
505 cycles, ConvertFloat10DR, direct, ebp
638 cycles, ConvertFloat10DF, direct, ebp
748 cycles, ConvertFloat10CT, BCD, esp, CT
758 cycles, ConvertFloat10BY, BCD, esp
759 cycles, ConvertFloat10BX, BCD
769 cycles, ConvertFloat10BF, BCD
1132 cycles, ConvertFloat10ZX, BCD
1146 cycles, ConvertFloat10Z, BCD
3015 cycles, ConvertFloat10, BCD, Save FPU
********** END **********
Sometimes, there are people that say
BCD method is slowHere we can see that
it is not true (in my P4).
*** STOP - ConvertFloat10DY ***
1168 cycles, ConvertFloat10ZX, _Real10_2
3016 cycles, ConvertFloat10, _Real10_2
1144 cycles, ConvertFloat10Z, _Real10_2
602 cycles, ConvertFloat10DF, _Real10_2
468 cycles, ConvertFloat10DR, _Real10_2
730 cycles, ConvertFloat10BX, _Real10_2
736 cycles, ConvertFloat10BF, _Real10_2
716 cycles, ConvertFloat10BY, _Real10_2
467 cycles, ConvertFloat10DY, _Real10_2
463 cycles, ConvertFloat10DX, _Real10_2
761 cycles, ConvertFloat10CT, _Real10_2
*** Press any key to get the time table ***
Quote
***** Time table *****
463 cycles, ConvertFloat10DX, direct, fxam, fxtract, esp - 10 digits
467 cycles, ConvertFloat10DY, direct, examine, fxtract, esp - 10 digits
468 cycles, ConvertFloat10DR, direct, examine, fxtract, ebp - 10 digits
602 cycles, ConvertFloat10DF, direct, examine, fyl2x, ebp - 10 digits
716 cycles, ConvertFloat10BY, BCD, examine, fxtract, esp - 10 digits
730 cycles, ConvertFloat10BX, BCD, fxam, fxtract, ebp - 10 digits
736 cycles, ConvertFloat10BF, BCD, fxam, fxtract, esp - 10 digits
761 cycles, ConvertFloat10CT, BCD-CT, fxam, fxtract, esp - 10 digits
1144 cycles, ConvertFloat10Z, BCD -old - 10 digits
1168 cycles, ConvertFloat10ZX,BCD - old - 10 digits
3016 cycles, ConvertFloat10, BCD, Save FPU -old - 10 digits
********** END **********
; ---------------------------------------------------------------------
*** STOP - ConvertFloat10DY ***
1049 cycles, ConvertFloat10ZX, _Real10_2
2933 cycles, ConvertFloat10, _Real10_2
1057 cycles, ConvertFloat10Z, _Real10_2
1408 cycles, ConvertFloat10DF, _Real10_2
1283 cycles, ConvertFloat10DR, _Real10_2
774 cycles, ConvertFloat10BX, _Real10_2
762 cycles, ConvertFloat10BF, _Real10_2
761 cycles, ConvertFloat10BY, _Real10_2
1457 cycles, ConvertFloat10DY, _Real10_2
1296 cycles, ConvertFloat10DX, _Real10_2
784 cycles, ConvertFloat10CT, _Real10_2
*** Press any key to get the time table ***
Quote
***** Time table *****
761 cycles, ConvertFloat10BY, BCD, examine, fxtract, esp - 15 digits
762 cycles, ConvertFloat10BF, BCD, fxam, fxtract, esp - 15 digits
774 cycles, ConvertFloat10BX, BCD, fxam, fxtract, ebp - 15 digits
784 cycles, ConvertFloat10CT, BCD-CT, fxam, fxtract, esp - 15 digits <- compresstable
1049 cycles, ConvertFloat10ZX, BCD - old - 15 digits
1057 cycles, ConvertFloat10Z, BCD -old - 15 digits
1283 cycles, ConvertFloat10DR, direct, examine, fxtract, ebp - 15 digits
1296 cycles, ConvertFloat10DX, direct, fxam, fxtract, esp - 15 digits
1408 cycles, ConvertFloat10DF, direct, examine, fyl2x, ebp - 15 digits
1457 cycles, ConvertFloat10DY, direct, examine, fxtract, esp - 15 digits
2933 cycles, ConvertFloat10, BCD, Save FPU -old - 15 digits
********** END **********
; ---------------------------------------------------------------------
*** STOP - ConvertFloat10DY ***
1161 cycles, ConvertFloat10ZX, _Real10_2
3043 cycles, ConvertFloat10, _Real10_2
1219 cycles, ConvertFloat10Z, _Real10_2
1729 cycles, ConvertFloat10DF, _Real10_2
1639 cycles, ConvertFloat10DR, _Real10_2
820 cycles, ConvertFloat10BX, _Real10_2
812 cycles, ConvertFloat10BF, _Real10_2
792 cycles, ConvertFloat10BY, _Real10_2
1636 cycles, ConvertFloat10DY, _Real10_2
1609 cycles, ConvertFloat10DX, _Real10_2
881 cycles, ConvertFloat10CT, _Real10_2
*** Press any key to get the time table ***
Quote
***** Time table *****
792 cycles, ConvertFloat10BY, BCD, examine, fxtract, esp - 17 digits
812 cycles, ConvertFloat10BF, BCD, fxam, fxtract, esp - 17 digits
820 cycles, ConvertFloat10BX, BCD, fxam, fxtract, ebp - 17 digits
881 cycles, ConvertFloat10CT, BCD-CT, fxam, fxtract, esp - 17 digits
1161 cycles, ConvertFloat10ZX, BCD - old - 17 digits
1219 cycles, ConvertFloat10Z, BCD -old - 17 digits
1609 cycles, ConvertFloat10DX, direct, fxam, fxtract, esp - 17 digits
1636 cycles, ConvertFloat10DY, direct, examine, fxtract, esp - 17 digits
1639 cycles, ConvertFloat10DR, direct, examine, fxtract, ebp - 17 digits
1729 cycles, ConvertFloat10DF, direct, examine, fyl2x, ebp - 17 digits
3043 cycles, ConvertFloat10, BCD, Save FPU -old - 17 digits
********** END **********
; ---------------------------------------------------------------------
*** STOP - ConvertFloat10DY ***
2258 cycles, ConvertFloat10DF, _Real10_2
2144 cycles, ConvertFloat10DR, _Real10_2
2157 cycles, ConvertFloat10DY, _Real10_2
2135 cycles, ConvertFloat10DX, _Real10_2
*** Press any key to get the time table ***
Quote
We cannot use BCD for 19 digits
***** Time table *****
2135 cycles, ConvertFloat10DX, direct, fxam, fxtract, esp - 19 digits
2144 cycles, ConvertFloat10DR, direct, examine, fxtract, ebp - 19 digits
2157 cycles, ConvertFloat10DY, direct, examine, fxtract, esp - 19 digits
2258 cycles, ConvertFloat10DF, direct, examine, fyl2x, ebp - 19 digits
********** END **********
BCD probably is slow if you want to multiply or divide long strings - lol
but, for adding and subtracting, it's quite fast :t
a good bignum library is probably faster for large values, though - fewer memory accesses
Quote from: dedndave on April 26, 2013, 04:36:53 AM
BCD probably is slow if you want to multiply or divide long strings - lol
but, for adding and subtracting, it's quite fast :t
a good bignum library is probably faster for large values, though - fewer memory accesses
Dave,
the last results show that if we want to convert
a
real10 to string with 15-17-18 digits, the best is
BCD. But if we want only 10, the best is converting
the integer (direct).
Do you know what i am saying with BCD ? It is nothing to do
with multiply or divide: use fbstp tbyte ...
that's because you can get a 10-decimal-digit binary into a dword register, if it's under 4294967296 :P
by the way, Ray has done some cool stuff with BCD, if you didn't already know...
http://www.ray.masmcode.com/BCDtut.html (http://www.ray.masmcode.com/BCDtut.html)
Quote from: dedndave on April 26, 2013, 04:45:35 AM
that's because you can get a 10-decimal-digit binary into a dword register, if it's under 4294967296 :P
Yes, of course ! But BCD has nothing to do with multiply/divide
We simple use fbstp tbyte _packedBCD and we need to unpack
it to string no need to multiply,divide,add, subtract.
I use compresstable also but it is not better.
Well, it seems that converting EDX:EAX to string is not fast as
fbstp + unpack it. Well,
in 32 bit !!!!!
The other things about that stuff it is not useful for me
About your other post, i need to test your results. I need time.
there are some very fast 64-bit routines (32-bit code)
Paul Dixon wrote one that uses a look-up table that is nearly the fastest, i think
but - the table is rather large - lol
for a non-LUT version, probably drizz has the best code
you can search the old forum for routines
Quote from: dedndave on April 26, 2013, 05:16:12 AM
there are some very fast 64-bit routines (32-bit code)
Paul Dixon wrote one that uses a look-up table that is nearly the fastest, i think
but - the table is rather large - lol
for a non-LUT version, probably drizz has the best code
you can search the old forum for routines
It is good to know. Nevertheless the cycles i got
is already good to me. Dont forget i am using the
old routines in The calculator and it solves the
expressions and show, very fast. I think less 400
or more cycles. For now i want to finish this work.
May be later i will think to improve it more. :t
one thing i learned today about floating point to string conversion.....
the hard parts are handling the special values and rounding - lol
those sound easy, right ?
floating point conversion was the easy part :lol:
Dave,
About the question of processing denormalized numbers
my first quick conclusion is this: it should not be
processed or it needs a particular processing.
In your previous post you said: to process Denormal
(exponent=0000) we simply inc exponent etc.
But pay attention: using the method i am using, not
the way you are working. Each method have its own
limitations.
Of course, first, we must and you must understand
the method to understand where is the problem.
Meanwhile, i think, the unnormalized numbers are
numbers near the zero beyond the limit (exponent
near -4932 etc.) if i am correct. (?)
If we have X=a.bcd... * 10^-4931, for instance,
and if we want to get an integer with 16 digits
we need to multiply X by
10^(15+4931)=10^4936
and we get infinity and then we get invalid operation
when we try to multiply. The limit is 10^4932.
This limit means this (for normal processing):
exponent= -(4932-dp) (dp=decimal places)
For 18 digits, dp=17 => exponent= -4915 is the limit
What it means ? For instance, it means that if after
some FPU operations we get X=a.bcd... * 10^-4916 and
then we want to convert this X to string it must
give error because the procedure cannot calculate
more than 10^4932.
Dave, did you understand or did i make some error ?
So, if i am correct and the unnormalized numbers
are numbers near the zero beyond the limit, it means
we may not pay attention to them (procedure limitations).
I hope you study this question before giving an answer.
the smallest normal in REAL10 format is 0001_80000000_00000000
for REAL10, the integer bit (bit 63) is explicit, and is 1 for all normals
the next lower value is the largest denormal, 0000_7FFFFFFF_FFFFFFFF
it depends on how your code is written, i suppose
if you are using the FPU to evaluate reals, you might multiply it by 10^N, then adjust the exponent when done
in my code, i convert the values so that the integer bit is bit 0, instead of bit 63
that is simple - i just subtract 63 from the exponent :P
that makes it easy to evaluate denormals
for some other method, that may not work so well - you have to choose what works :t
in my routine, i convert 0000_7FFFFFFF_FFFFFFFF to 0001_7FFFFFFF_FFFFFFFF
with the shifted exponent, it evaluates correctly using the same code as normals
Quote from: dedndave on April 26, 2013, 09:26:01 PM
in my routine, i convert 0000_7FFFFFFF_FFFFFFFF to 0001_7FFFFFFF_FFFFFFFF
with the shifted exponent, it evaluates correctly using the same code as normals
Ok, i think i found the solution and will explain it
but what you get ? What is the decimal value for
0001_7FFFFFFF_FFFFFFFF ?
EDIT:
In the other post you have
Quote
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
So it seems it is an INVALID range (red)
and a valid (green)
may be you want to say not 0001_7FFFFFFF_FFFFFFFF
but 0001_FFFFFFFF_FFFFFFFF, no ?
I saw it just now!
you have to increment the exponent AFTER you make the "invalid test"
got mine working - i need to do more testing and cleanup before i post
0000_00000000_00000000: 00000000 00000002 +0
8000_00000000_00000000: 00000000 00000002 -0
0000_00000000_00000001: 00000000 0000001D +3.64519953188247460253e-4951
0000_7FFFFFFF_FFFFFFFF: 00000000 0000001C +3.3621031431120935059e-4932
0000_80000000_00000000: 00000000 0000001D +3.36210314311209350626e-4932
0000_FFFFFFFF_FFFFFFFF: 00000000 0000001D +6.72420628622418701216e-4932
0001_00000000_00000000: 00000006 00000007 Invalid
7FFE_7FFFFFFF_FFFFFFFF: 00000006 00000007 Invalid
0001_80000000_00000000: 00000000 0000001D +3.36210314311209350626e-4932
4000_C90FDAA2_2168C235: 00000000 00000017 +3.14159265358979323851
7FFE_FFFFFFFF_FFFFFFFF: 00000000 0000001D +1.18973149535723176502e+4932
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 0000000F +1.40129846e-45
007FFFFF: 00000000 0000000F +1.17549421e-38
00800000: 00000000 0000000F +1.17549435e-38
BF800000: 00000000 00000002 -1
7F7FFFFF: 00000000 0000000F +3.40282347e+38
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 00000018 +4.9406564584124654e-324
000FFFFF_FFFFFFFF: 00000000 00000018 +2.2250738585072009e-308
00100000_00000000: 00000000 00000018 +2.2250738585072014e-308
BFF00000_00000000: 00000000 00000002 -1
7FEFFFFF_FFFFFFFF: 00000000 00000018 +1.7976931348623157e+308
7FF00000_00000000: 00000001 00000002 +∞
FFF00000_00000000: 00000001 00000002 -∞
7FF00000_00000001: 00000002 00000003 NaN
7FFFFFFF_FFFFFFFF: 00000002 00000003 NaN
or, if you like more digits...
0000_00000000_00000000: 00000000 00000002 +0
8000_00000000_00000000: 00000000 00000002 -0
0000_00000000_00000001: 00000000 00000025 +3.6451995318824746025284059336e-4951
0000_7FFFFFFF_FFFFFFFF: 00000000 00000025 +3.3621031431120935058981578641e-4932
0000_80000000_00000000: 00000000 00000025 +3.3621031431120935062626778173e-4932
0000_FFFFFFFF_FFFFFFFF: 00000000 00000025 +6.7242062862241870121608356815e-4932
0001_00000000_00000000: 00000006 00000007 Invalid
7FFE_7FFFFFFF_FFFFFFFF: 00000006 00000007 Invalid
0001_80000000_00000000: 00000000 00000025 +3.3621031431120935062626778173e-4932
4000_C90FDAA2_2168C235: 00000000 0000001F +3.1415926535897932385128089594
7FFE_FFFFFFFF_FFFFFFFF: 00000000 00000024 +1.189731495357231765021263853e+4932
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 00000033 +1.40129846432481707092372958328991613128026194e-45
007FFFFF: 00000000 00000033 +1.17549421069244107548702944484928734882705243e-38
00800000: 00000000 00000033 +1.17549435082228750796873653722224567781866556e-38
BF800000: 00000000 00000002 -1
7F7FFFFF: 00000000 0000002C +3.4028234663852885981170418348451692544e+38
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 0000002A +4.9406564584124654417656879286822137e-324
000FFFFF_FFFFFFFF: 00000000 0000002A +2.2250738585072008890245868760858599e-308
00100000_00000000: 00000000 0000002A +2.2250738585072013830902327173324041e-308
BFF00000_00000000: 00000000 00000002 -1
7FEFFFFF_FFFFFFFF: 00000000 0000002A +1.7976931348623157081452742373170436e+308
7FF00000_00000000: 00000001 00000002 +∞
FFF00000_00000000: 00000001 00000002 -∞
7FF00000_00000001: 00000002 00000003 NaN
7FFFFFFF_FFFFFFFF: 00000002 00000003 NaN
more digits available upon request :P
Here are my results with 19 digits, 18 decimal places
I am converting the qword integer to digits, not BCD.
I used Olly to see some steps about Denormal
0000_80000000_00000000 = 3.36210314311209351E-4932
0000_FFFFFFFF_FFFFFFFF = 6.72420628622418702E-4932
0000_00000000_00000001 =ERROR <-- FPU doesnt load it, gives error (fld tbyte ptr ... => error)
0000_FFFFFFFF_FFFFFFFF =ERROR <-- " " " "
7FFF_80000000_00000000 =+INFINITY
FFFF_80000000_00000000 =-INFINITY
7FFE_FFFFFFFF_FFFFFFFF = 1.189731495357231998E+4932
FFFE_FFFFFFFF_FFFFFFFF =-1.189731495357231998E+4932
Here our results
I dont know why, but the LimitReal10
are not the same.
I will try another way to see if
it gives the same result.
;------------------------------------------
;8000_0000_0000_0000 to FFFF_FFFF_FFFF_FFFF Signed Pseudo-Denormal
;------------------------------------------
;0000_80000000_00000000: +3.36210314311209350626e-4932
_DemormalI2 dd 00000000h ; 3.36210314311209351 E-4932 -
Pseudo-Denormal dd 80000000h
dw 0
;0000_FFFFFFFF_FFFFFFFF: +6.72420628622418701216e-4932
_DemormalE2 dd 0FFFFFFFFh ; 6.72420628622418702 E-4932 -
Pseudo-Denormal dd 0FFFFFFFFh
dw 0
;7FFE_FFFFFFFF_FFFFFFFF: +1.18973149535723176502e+4932
_LimitReal10_1 dd 0FFFFFFFFh ; 1.189731495357231998 E+4932
dd 0FFFFFFFFh
dw 7FFEh
;FFFE_FFFFFFFF_FFFFFFFF: +1.18973149535723176502e+4932
_LimitReal10_2 dd 0FFFFFFFFh ; -1.189731495357231998 E+4932
dd 0FFFFFFFFh
dw 0FFFEh
Quote
more digits available upon request
I am the wrong target. Write it
to that people that get only 21 digits
and dont say how they get it !!! :bgrin:
lol - well, i am writing this to be used a different way
i am sure yours are much faster than mine :P
i wanted a tool that would allow me to see the digits beyond usable resolution
now, if i want to know how much difference there is by adding or subtracting 1 LSB, i can
I have no way to do it in another way, but
it is a FPU rounding question because when
i use 17 decimal places (18 digits) it gives 77 not 998.
It's all, Dave :t
:biggrin:
Ohhh 77 is what you get !!! :biggrin:
EDIT:
well, i will post one version of real10 to string
Here one complete example from one proc that
uses BCD - and compress table - 18 digits
(i wrote 11 procedures)
0000_80000000_00000000 = 3.3621031431120935E-4932
0000_FFFFFFFF_FFFFFFFF = 6.724206286224187E-4932
0000_00000000_00000001 =ERROR
0000_FFFFFFFF_FFFFFFFF =ERROR
7FFF_80000000_00000000 =+INFINITY
FFFF_80000000_00000000 =-INFINITY
7FFE_FFFFFFFF_FFFFFFFF = 1.18973149535723177E+4932
FFFE_FFFFFFFF_FFFFFFFF =-1.18973149535723177E+4932
*** STOP - ConvertFloat10CT end test digits ***
0
1.0
2.0
3.0
4.0
5.0
6.0
7.0
8.0
9.0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
*** STOP - ConvertFloat10CT end test digits ***
-1.1
-11.1
-111.1
-1111.1
-11111.1
-111111.1
-1111111.1
-11111111.1
-111111111.1
-1111111111.1
-11111111111.1
-111111111111.1
-1111111111111.1
-11111111111111.1
-111111111111111.1
-1111111111111111.1
-11111111111111111.1
-111111111111111111
-2.2
-22.2
-222.2
-2222.2
-22222.2
-222222.2
-2222222.2
-22222222.2
-222222222.2
-2222222222.2
-22222222222.2
-222222222222.2
-2222222222222.2
-22222222222222.2
-222222222222222.2
-2222222222222222.2
-22222222222222222.2
-222222222222222222
-3.3
-33.3
-333.3
-3333.3
-33333.3
-333333.3
-3333333.3
-33333333.3
-333333333.3
-3333333333.3
-33333333333.3
-333333333333.3
-3333333333333.3
-33333333333333.3
-333333333333333.3
-3333333333333333.3
-33333333333333333.3
-333333333333333333
*** STOP - ConvertFloat10CT ***
-4.4
-44.4
-444.4
-4444.4
-44444.4
-444444.4
-4444444.4
-44444444.4
-444444444.4
-4444444444.4
-44444444444.4
-444444444444.4
-4444444444444.4
-44444444444444.4
-444444444444444.4
-4444444444444444.4
-44444444444444444
-444444444444444444
-5.5
-55.5
-555.5
-5555.5
-55555.5
-555555.5
-5555555.5
-55555555.5
-555555555.5
-5555555555.5
-55555555555.5
-555555555555.5
-5555555555555.5
-55555555555555.5
-555555555555555.5
-5555555555555555.5
-55555555555555556
-555555555555555556
-6.6
-66.6
-666.6
-6666.6
-66666.6
-666666.6
-6666666.6
-66666666.6
-666666666.6
-6666666666.6
-66666666666.6
-666666666666.6
-6666666666666.6
-66666666666666.6
-666666666666666.6
-6666666666666666.6
-66666666666666667
-6.6666666666666667E+17
-7.7
-77.7
-777.7
-7777.7
-77777.7
-777777.7
-7777777.7
-77777777.7
-777777777.7
-7777777777.7
-77777777777.7
-777777777777.7
-7777777777777.7
-77777777777777.7
-777777777777777.7
-7777777777777777.7
-77777777777777778
-7.7777777777777778E+17
*** STOP - ConvertFloat10CT ***
-8.8
-88.8
-888.8
-8888.8
-88888.8
-888888.8
-8888888.8
-88888888.8
-888888888.8
-8888888888.8
-88888888888.8
-888888888888.8
-8888888888888.8
-88888888888888.8
-888888888888888.8
-8888888888888888.8
-88888888888888889
-8.8888888888888889E+17
-9.9
-99.9
-999.9
-9999.9
-99999.9
-999999.9
-9999999.9
-99999999.9
-999999999.9
-9999999999.9
-99999999999.9
-999999999999.9
-9999999999999.9
-99999999999999.9
-999999999999999.9
-9999999999999999.9
-100000000000000000
-1.0E+18
*** STOP - ConvertFloat10CT ***
0.1
0.01
0.001
0.0001
0.00001
0.000001
0.0000001
0.00000001
0.000000001
0.0000000001
0.00000000001
0.000000000001
0.0000000000001
0.00000000000001
0.000000000000001
0.0000000000000001
1.0E-17
1.0E-18
*** STOP - ConvertFloat10CT ***
0.2
0.02
0.002
0.0002
0.00002
0.000002
0.0000002
0.00000002
0.000000002
0.0000000002
0.00000000002
0.000000000002
0.0000000000002
0.00000000000002
0.000000000000002
0.0000000000000002
2.0E-17
2.0E-18
*** STOP - ConvertFloat10CT ***
0.3
0.03
0.003
0.0003
0.00003
0.000003
0.0000003
0.00000003
0.000000003
0.0000000003
0.00000000003
0.000000000003
0.0000000000003
0.00000000000003
0.000000000000003
0.0000000000000003
3.0E-17
3.0E-18
*** STOP - ConvertFloat10CT ***
0.4
0.04
0.004
0.0004
0.00004
0.000004
0.0000004
0.00000004
0.000000004
0.0000000004
0.00000000004
0.000000000004
0.0000000000004
0.00000000000004
0.000000000000004
0.0000000000000004
4.0E-17
4.0E-18
*** STOP - ConvertFloat10CT ***
0.5
0.05
0.005
0.0005
0.00005
0.000005
0.0000005
0.00000005
0.000000005
0.0000000005
0.00000000005
0.000000000005
0.0000000000005
0.00000000000005
0.000000000000005
5.0E-16
5.0E-17
5.0E-18
*** STOP - ConvertFloat10CT ***
0.6
0.06
0.006
0.0006
0.00006
0.000006
0.0000006
0.00000006
0.000000006
0.0000000006
0.00000000006
0.000000000006
0.0000000000006
0.00000000000006
0.000000000000006
6.0E-16
6.0E-17
6.0E-18
*** STOP - ConvertFloat10CT ***
0.7
0.07
0.007
0.0007
0.00007
0.000007
0.0000007
0.00000007
0.000000007
0.0000000007
0.00000000007
0.000000000007
0.0000000000007
0.00000000000007
0.000000000000007
7.0E-16
7.0E-17
7.0E-18
*** STOP - ConvertFloat10CT ***
0.8
0.08
0.008
0.0008
0.00008
0.000008
0.0000008
0.00000008
0.000000008
0.0000000008
0.00000000008
0.000000000008
0.0000000000008
0.00000000000008
0.000000000000008
8.0E-16
8.0E-17
8.0E-18
*** STOP - ConvertFloat10CT ***
0.9
0.09
0.009
0.0009
0.00009
0.000009
0.0000009
0.00000009
0.000000009
0.0000000009
0.00000000009
0.000000000009
0.0000000000009
0.00000000000009
0.000000000000009
9.0E-16
9.0E-17
9.0E-18
*** STOP - ConvertFloat10CT ***
-1.23456789123456
-12.3456789123456
-123.456789123456
-1234.56789123456
-12345.6789123456
-123456.789123456
-1234567.89123456
-12345678.9123456
-12345678.9123456
-123456789.123456
-1234567891.123456
-12345678912.123456
-123456789123.123456
-1234567891234.12346
-12345678912345.1235
-123456789123456.123
-1234567891234567.12
-12345678912345678.1
-123456789123456789
*** STOP - ConvertFloat10CT --- E N D ---***
Here another - direct - 18 digits
0000_80000000_00000000 =3.3621031431120935E-4932
0000_FFFFFFFF_FFFFFFFF =6.724206286224187E-4932
0000_00000000_00000001 =ERROR
0000_FFFFFFFF_FFFFFFFF =ERROR
7FFF_80000000_00000000 =+INFINITY
FFFF_80000000_00000000 =-INFINITY
7FFE_FFFFFFFF_FFFFFFFF =1.18973149535723177E+4932
FFFE_FFFFFFFF_FFFFFFFF =1.18973149535723177E+4932
*** STOP - ConvertFloat10DX end test digits ***
0
1.0
2.0
3.0
4.0
5.0
6.0
7.0
8.0
9.0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
*** STOP - ConvertFloat10DX end test digits ***
1.1
11.1
111.1
1111.1
11111.1
111111.1
1111111.1
11111111.1
111111111.1
1111111111.1
11111111111.1
111111111111.1
1111111111111.1
11111111111111.1
111111111111111.1
1111111111111111.1
11111111111111111.1
1.11111111111111111E+17
2.2
22.2
222.2
2222.2
22222.2
222222.2
2222222.2
22222222.2
222222222.2
2222222222.2
22222222222.2
222222222222.2
2222222222222.2
22222222222222.2
222222222222222.2
2222222222222222.2
22222222222222222.2
2.22222222222222222E+17
3.3
33.3
333.3
3333.3
33333.3
333333.3
3333333.3
33333333.3
333333333.3
3333333333.3
33333333333.3
333333333333.3
3333333333333.3
33333333333333.3
333333333333333.3
3333333333333333.3
33333333333333333.3
3.33333333333333333E+17
*** STOP - ConvertFloat10DX ***
4.4
44.4
444.4
4444.4
44444.4
444444.4
4444444.4
44444444.4
444444444.4
4444444444.4
44444444444.4
444444444444.4
4444444444444.4
44444444444444.4
444444444444444.4
4444444444444444.4
44444444444444444
4.44444444444444444E+17
5.5
55.5
555.5
5555.5
55555.5
555555.5
5555555.5
55555555.5
555555555.5
5555555555.5
55555555555.5
555555555555.5
5555555555555.5
55555555555555.5
555555555555555.5
5555555555555555.5
55555555555555556
5.55555555555555556E+17
6.6
66.6
666.6
6666.6
66666.6
666666.6
6666666.6
66666666.6
666666666.6
6666666666.6
66666666666.6
666666666666.6
6666666666666.6
66666666666666.6
666666666666666.6
6666666666666666.6
66666666666666667
6.6666666666666667E+17
7.7
77.7
777.7
7777.7
77777.7
777777.7
7777777.7
77777777.7
777777777.7
7777777777.7
77777777777.7
777777777777.7
7777777777777.7
77777777777777.7
777777777777777.7
7777777777777777.7
77777777777777778
7.7777777777777778E+17
*** STOP - ConvertFloat10DX ***
8.8
88.8
888.8
8888.8
88888.8
888888.8
8888888.8
88888888.8
888888888.8
8888888888.8
88888888888.8
888888888888.8
8888888888888.8
88888888888888.8
888888888888888.8
8888888888888888.8
88888888888888889
8.8888888888888889E+17
9.9
99.9
999.9
9999.9
99999.9
999999.9
9999999.9
99999999.9
999999999.9
9999999999.9
99999999999.9
999999999999.9
9999999999999.9
99999999999999.9
999999999999999.9
9999999999999999.9
1.0E+17
1.0E+18
*** STOP - ConvertFloat10DX ***
0.1
0.01
0.001
0.0001
0.00001
0.000001
0.0000001
0.00000001
0.000000001
0.0000000001
0.00000000001
0.000000000001
0.0000000000001
0.00000000000001
0.000000000000001
0.0000000000000001
0.00000000000000001
1.0E-18
*** STOP - ConvertFloat10DX ***
0.2
0.02
0.002
0.0002
0.00002
0.000002
0.0000002
0.00000002
0.000000002
0.0000000002
0.00000000002
0.000000000002
0.0000000000002
0.00000000000002
0.000000000000002
0.0000000000000002
0.00000000000000002
2.0E-18
*** STOP - ConvertFloat10DX ***
0.3
0.03
0.003
0.0003
0.00003
0.000003
0.0000003
0.00000003
0.000000003
0.0000000003
0.00000000003
0.000000000003
0.0000000000003
0.00000000000003
0.000000000000003
0.0000000000000003
0.00000000000000003
3.0E-18
*** STOP - ConvertFloat10DX ***
0.4
0.04
0.004
0.0004
0.00004
0.000004
0.0000004
0.00000004
0.000000004
0.0000000004
0.00000000004
0.000000000004
0.0000000000004
0.00000000000004
0.000000000000004
0.0000000000000004
0.00000000000000004
4.0E-18
*** STOP - ConvertFloat10DX ***
0.5
0.05
0.005
0.0005
0.00005
0.000005
0.0000005
0.00000005
0.000000005
0.0000000005
0.00000000005
0.000000000005
0.0000000000005
0.00000000000005
0.000000000000005
0.0000000000000005
0.00000000000000005
5.0E-18
*** STOP - ConvertFloat10DX ***
0.6
0.06
0.006
0.0006
0.00006
0.000006
0.0000006
0.00000006
0.000000006
0.0000000006
0.00000000006
0.000000000006
0.0000000000006
0.00000000000006
0.000000000000006
0.0000000000000006
0.00000000000000006
6.0E-18
*** STOP - ConvertFloat10DX ***
0.7
0.07
0.007
0.0007
0.00007
0.000007
0.0000007
0.00000007
0.000000007
0.0000000007
0.00000000007
0.000000000007
0.0000000000007
0.00000000000007
0.000000000000007
0.0000000000000007
0.00000000000000007
7.0E-18
*** STOP - ConvertFloat10DX ***
0.8
0.08
0.008
0.0008
0.00008
0.000008
0.0000008
0.00000008
0.000000008
0.0000000008
0.00000000008
0.000000000008
0.0000000000008
0.00000000000008
0.000000000000008
0.0000000000000008
0.00000000000000008
8.0E-18
*** STOP - ConvertFloat10DX ***
0.9
0.09
0.009
0.0009
0.00009
0.000009
0.0000009
0.00000009
0.000000009
0.0000000009
0.00000000009
0.000000000009
0.0000000000009
0.00000000000009
0.000000000000009
0.0000000000000009
0.00000000000000009
9.0E-18
*** STOP - ConvertFloat10DX ***
1.23456789123456
12.3456789123456
123.456789123456
1234.56789123456
12345.6789123456
123456.789123456
1234567.89123456
12345678.9123456
12345678.9123456
123456789.123456
1234567891.123456
12345678912.123456
123456789123.123456
1234567891234.12346
12345678912345.1235
123456789123456.123
1234567891234567.12
12345678912345678.1
1.23456789123456789E+17
*** STOP - ConvertFloat10DX --- E N D ---***
i am a little suprised that the FPU won't load those values
however, there is a work around
for pseudo-denormals (bit 63 = 1), you can increment the exponent and evaluate it - those are easy
0000_FFFFFFFF_FFFFFFFF = 0001_FFFFFFFF_FFFFFFFF
for denormals (bit 63 = 0), you can left shift the fraction until bit 63 is 1, keeping track of the count
increment the exponent and load it, then divide by 2^(shift count) in the FPU and evaluate the result
sounds good, in theory, anyways :P
otherwise, your values look pretty good :t
the routine is finished, although, i want to write a little app that allows command-line hex reals
anyways, this is the test program - i thought you might like to play with it
let me know if you find errors, please - you can be my beta guy :P
Seems to work fine, Dave :t
I wish I'd had had this valuable resource when I designed Str$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1186) - it would have made many things easier. Great job, young friend :icon14:
thanks, Jochen :t
the one i had back then shifted the ascii string left or right - very slow
but - all you had to do was ask :P
i am working on a little command-line tool that allows hex entry on the command line
it will also allow 2 switches - one to do steps x-(1 lsb), x, x+(1 lsb), one to do full precision
i will probably post that one in the ling long kai fang thread
maybe when i get better - not feeling well - i may go to the hospital :(
Dave,
Quote from: dedndave on April 27, 2013, 04:52:51 PM
maybe when i get better - not feeling well - i may go to the hospital :(
that's bad news, old friend. What's wrong?
Gunther
Quote from: dedndave on April 27, 2013, 04:52:51 PM
maybe when i get better - not feeling well - i may go to the hospital :(
I hope you feel better very soon, Dave :t
Hi Dave,
Get well soon.
Good luck,
Steve
thanks, guys :t
i went to the hospital - turned out to be a minor stomach problem :P
you won't get rid of me, that easily - lol
Hi Dave,
Quote from: dedndave on April 27, 2013, 10:33:33 PM
thanks, guys :t
i went to the hospital - turned out to be a minor stomach problem :P
that sounds like blessing in disguise. I hope you've a good medical insurance.
Gunther
Quote from: dedndave on April 27, 2013, 10:33:33 PM
i went to the hospital - turned out to be a minor stomach problem :P
Confess that you just wanted a gentle belly massage by some cute gal :biggrin:
ok, i admit it - lol
she was nice, albeit a bit young for me :P
Well, Dave, it seems you returned well, its what we want :t
Dave, good to hear that it's nothing serious. :t
thanks, Rui and Marinus :t
guess it's not my turn, yet - lol
i have more code to write
Dave,
The main thing is: You have not lost your sense of humor.
Gunther
Hi all,
I replaced ConverterDD by ConverterDF to correct some bugs/fails (see first post)
Now we may use ConvertFloat4DF or ConvertReal4DF.
Good luck :t