Author Topic: Converting real4 to string  (Read 18351 times)

RuiLoureiro

  • Member
  • ****
  • Posts: 786
Converting real4 to string
« on: April 19, 2013, 05:50:44 AM »
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
« Last Edit: May 02, 2018, 02:29:15 AM by RuiLoureiro »

jj2007

  • Member
  • *****
  • Posts: 8617
  • Assembler is fun ;-)
    • MasmBasic
Re: Converting real4 to string
« Reply #1 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

RuiLoureiro

  • Member
  • ****
  • Posts: 786
Re: Converting real4 to string
« Reply #2 on: April 19, 2013, 06:29:38 AM »
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 ---***

RuiLoureiro

  • Member
  • ****
  • Posts: 786
Re: Converting real4 to string
« Reply #3 on: April 19, 2013, 06:42:02 AM »
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:

Mikl__

  • Member
  • ****
  • Posts: 681
Re: Converting real4 to string
« Reply #4 on: April 19, 2013, 02:51:39 PM »
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.

RuiLoureiro

  • Member
  • ****
  • Posts: 786
Re: Converting real4 to string
« Reply #5 on: April 20, 2013, 02:40:15 AM »
Mikl__
         I dont know magic numbers. What we may replace ?
         does it take less cycles ?

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:
Code: [Select]

-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 ---***
« Last Edit: April 20, 2013, 10:46:13 PM by RuiLoureiro »

dedndave

  • Member
  • *****
  • Posts: 8806
  • Still using Abacus 2.0
    • DednDave
Re: Converting real4 to string
« Reply #6 on: April 20, 2013, 03:33:56 AM »
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...
Code: [Select]
;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

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

RuiLoureiro

  • Member
  • ****
  • Posts: 786
Re: Converting real4 to string
« Reply #7 on: April 20, 2013, 04:55:34 AM »
 :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 ?
« Last Edit: April 20, 2013, 06:48:51 AM by RuiLoureiro »

dedndave

  • Member
  • *****
  • Posts: 8806
  • Still using Abacus 2.0
    • DednDave
Re: Converting real4 to string
« Reply #8 on: April 20, 2013, 07:25:41 AM »
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

dedndave

  • Member
  • *****
  • Posts: 8806
  • Still using Abacus 2.0
    • DednDave
Re: Converting real4 to string
« Reply #9 on: April 20, 2013, 07:38:09 AM »
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

RuiLoureiro

  • Member
  • ****
  • Posts: 786
Re: Converting real4 to string
« Reply #10 on: April 20, 2013, 11:41:24 PM »
 :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
Code: [Select]
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 ---***
 

« Last Edit: April 21, 2013, 05:08:49 AM by RuiLoureiro »

RuiLoureiro

  • Member
  • ****
  • Posts: 786
Re: Converting real4 to string
« Reply #11 on: April 21, 2013, 11:23:07 PM »
 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 **********
« Last Edit: April 22, 2013, 02:28:09 AM by RuiLoureiro »

RuiLoureiro

  • Member
  • ****
  • Posts: 786
Re: Converting real4 to string
« Reply #12 on: April 22, 2013, 03:49:31 AM »
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
« Last Edit: April 22, 2013, 06:30:32 AM by RuiLoureiro »

qWord

  • Member
  • *****
  • Posts: 1473
  • The base type of a type is the type itself
    • SmplMath macros
Re: Converting real4 to string
« Reply #13 on: April 22, 2013, 04:17:04 PM »
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".
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?
MREAL macros - when you need floating point arithmetic while assembling!

RuiLoureiro

  • Member
  • ****
  • Posts: 786
Re: Converting real4 to string
« Reply #14 on: April 23, 2013, 05:12:56 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