The MASM Forum

General => The Campus => Topic started by: RuiLoureiro on April 15, 2013, 04:35:25 AM

Title: Converting string to real4
Post by: RuiLoureiro on April 15, 2013, 04:35:25 AM
    Hi all,

    . Sometimes some friends here ask me where is the
      ASM file.
(Hi Dave ! Hi qWord !)
     
    . Well, in this post i give ConvertString4D.inc
      which contains the ASM ConvertString4D procedure,
      constants and macros, and a text file Converter4.txt
      where i explain something about that. (See Converter4.zip below)

    . ConvertString4D procedure is a proc that converts
      a null terminated string into a real4 dword variable.
      The string may be written like this one:

         "-123.4567E-1"  or the same as "  - 000 1 2 3  . 45 67 E - 0001"

      It takes 119 cycles more or less in my P4.
            (qWord, in your i7 119 may give 40, no ?)

    . TestCnvDD9.exe shows conversions of 10 strings
      by all converters
     
    . Please, could you run TestCnvDD10.exe
      and show the results here ?
      Thanks
      Rui

NOTE: ConvertString4Y0 doesnt convert a string like this:
           "- 123" or "-001236789" or "-1.234 E5" (spaces and more than 8 integers)

    About each converter
    --------------------

                    load   stack   intermediate    save    conversion
                           access    buffer     FPU & CPU    method       obs.
------------------------------------------------------------------------------
1  ConvertString4BZ 1 byte   ebp        yes          no         BCD       (1,3)       

2  ConvertString4BX 1 byte   ebp        yes          yes        BCD       (1,3)

3  ConvertString4BY 1 byte   esp        yes          no         BCD       (1,3)

4  ConvertString4B  1 byte   esp        yes          yes        BCD       (1,3)

5  ConvertString4BW 1 byte   ebp         no          no         BCD       (1,3)

6  ConvertString4BF 1 byte   esp         no          no         BCD       (1,3)
-------------------------------------------------------------------------------
7  ConvertString4Y0 1 byte   ebp         no          no        direct     (1)

8  ConvertString4Y  1 byte   ebp         no          no        direct     (2)

9  ConvertString4YM 1 byte   ebp         no          no        direct     (2)

10 ConvertString4YF 1 byte   esp         no          no        direct     (2)
--------------------------------------------------------------------------------
11 ConvertString4T  1 byte   ebp         yes         no        xlatb      (2)

12 ConvertString4TX 1  "     esp         yes         no        xlatb      (2)

13 ConvertString4TY 1 byte   esp         yes         no       code table  (2)

14 ConvertString4TW 1  "     esp         yes         no           "       (2) 

15 ConvertString4T4 4  "     esp         yes         no           "       (2)
--------------------------------------------------------------------------------
16 ConvertString4D  1  "     ebp          no         no        direct     (2)

17 ConvertString4DS 1  "     ebp          no         yes       direct     (2)   
---------------------------------------------------------------------------------
obs. (1) no spaces/no zeroes
     (2) remove spaces/zeroes
     (3) rcl strings sampled from right to left
     (4) all use tables of qwords to get the power of 10: 10^n or 10^-n


file: TestCnvDD9.exe

It is to show the results in P4 XP sp3
converting 10 different strings
--------------------------------------

ConvertString4TW
1234.567

ConvertString4T4
1234.567

ConvertString4D
1234.567

ConvertString4DS
1234.567

*** STOP RclStr04 +1234.567 ***
converting _RclStr05 +1234E+12

ConvertString4B
1.2339999E+15

ConvertString4BX
1.2339999E+15

ConvertString4BZ
1.2339999E+15

ConvertString4BY
1.2339999E+15

ConvertString4BW
1.2339999E+15

ConvertString4BF
1.2339999E+15

ConvertString4Y0
1.2339999E+15

ConvertString4Y
1.2339999E+15

ConvertString4YM
1.2339999E+15

ConvertString4YF
1.2339999E+15

ConvertString4T
1.2339999E+15

ConvertString4TX
1.2339999E+15

ConvertString4TY
1.2339999E+15

ConvertString4TW
1.2339999E+15

ConvertString4T4
1.2339999E+15

ConvertString4D
1.2339999E+15

ConvertString4DS
1.2339999E+15

*** STOP RclStr05 +1234E+12 ***
converting _RclStr06 .567E+12

ConvertString4B
1 ERROR eax
ConvertString4BX
1 ERROR eax
ConvertString4BZ
1 ERROR eax
ConvertString4BY
1 ERROR eax
ConvertString4BW
1 ERROR eax
ConvertString4BF
1 ERROR eax
ConvertString4Y0
5.6699997E+11

ConvertString4Y
5.6699997E+11

ConvertString4YM
5.6699997E+11

ConvertString4YF
5.6699997E+11

ConvertString4T
5.6699997E+11

ConvertString4TX
5.6699997E+11

ConvertString4TY
5.6699997E+11

ConvertString4TW
5.6699997E+11

ConvertString4T4
5.6699997E+11

ConvertString4D
5.6699997E+11

ConvertString4DS
5.6699997E+11

*** STOP RclStr06 .567E+12 ***
converting _RclStr07 +1234.567E+12

ConvertString4B
1.234567E+15

ConvertString4BX
1.234567E+15

ConvertString4BZ
1.234567E+15

ConvertString4BY
1.234567E+15

ConvertString4BW
1.234567E+15

ConvertString4BF
1.234567E+15

ConvertString4Y0
1.234567E+15

ConvertString4Y
1.234567E+15

ConvertString4YM
1.234567E+15

ConvertString4YF
1.234567E+15

ConvertString4T
1.234567E+15

ConvertString4TX
1.234567E+15

ConvertString4TY
1.234567E+15

ConvertString4TW
1.234567E+15

ConvertString4T4
1.234567E+15

ConvertString4D
1.234567E+15

ConvertString4DS
1.234567E+15

*** STOP RclStr07 +1234.567E+12 ***
converting _RclStr08 +000000 012 34.56 7 E + 000012

ConvertString4B
3 ERROR eax
ConvertString4BX
3 ERROR eax
ConvertString4BZ
3 ERROR eax
ConvertString4BY
3 ERROR eax
ConvertString4BW
3 ERROR eax
ConvertString4BF
1 ERROR eax
ConvertString4Y0
1 ERROR eax
ConvertString4Y
1.234567E+15

ConvertString4YM
1.234567E+15

ConvertString4YF
1.234567E+15

ConvertString4T
1.234567E+15

ConvertString4TX
1.234567E+15

ConvertString4TY
1.234567E+15

ConvertString4TW
1.234567E+15

ConvertString4T4
1.234567E+15

ConvertString4D
1.234567E+15

ConvertString4DS
1.234567E+15

*** STOP RclStr08 +000000 012 34.56 7 E + 000012 ***
converting _RclStr09 +1.234E+45

ConvertString4B
8 ERROR eax
ConvertString4BX
8 ERROR eax
ConvertString4BZ
8 ERROR eax
ConvertString4BY
8 ERROR eax
ConvertString4BW
8 ERROR eax
ConvertString4BF
8 ERROR eax
ConvertString4Y0
8 ERROR eax
ConvertString4Y
8 ERROR eax
ConvertString4YM
8 ERROR eax
ConvertString4YF
8 ERROR eax
ConvertString4T
8 ERROR eax
ConvertString4TX
8 ERROR eax
ConvertString4TY
8 ERROR eax
ConvertString4TW
8 ERROR eax
ConvertString4T4
8 ERROR eax
ConvertString4D
8 ERROR eax
ConvertString4DS
8 ERROR eax
*** STOP RclStr09 +1.234E+45 ***
converting _RclStr10 +1.234E-45

ConvertString4B
8 ERROR eax
ConvertString4BX
8 ERROR eax
ConvertString4BZ
8 ERROR eax
ConvertString4BY
8 ERROR eax
ConvertString4BW
8 ERROR eax
ConvertString4BF
8 ERROR eax
ConvertString4Y0
7 ERROR eax
ConvertString4Y
1.4012985E-45

ConvertString4YM
1.4012985E-45

ConvertString4YF
1.4012985E-45

ConvertString4T
1.4012985E-45

ConvertString4TX
1.4012985E-45

ConvertString4TY
1.4012985E-45

ConvertString4TW
1.4012985E-45

ConvertString4T4
1.4012985E-45

ConvertString4D
1.4012985E-45

ConvertString4DS
1.4012985E-45

*** STOP RclStr10 +1.234E-45 and END ***



file: TestCnvDD10.exe

My results in P4 XP sp3
-----------------------
Quote
converting _RclStr04 +1234.567

2665 cycles, ConvertString4, _RclStr04

2642 cycles, ConvertString4BX, _RclStr04

566 cycles, ConvertString4BZ, _RclStr04

528 cycles, ConvertString4BY, _RclStr04

452 cycles, ConvertString4BW, _RclStr04

455 cycles, ConvertString4BF, _RclStr04

107 cycles, ConvertString4Y0, _RclStr04

127 cycles, ConvertString4Y, _RclStr04

138 cycles, ConvertString4YM, _RclStr04

122 cycles, ConvertString4YF, _RclStr04

231 cycles, ConvertString4T, _RclStr04

177 cycles, ConvertString4TX, _RclStr04

169 cycles, ConvertString4TY, _RclStr04

151 cycles, ConvertString4TW, _RclStr04

211 cycles, ConvertString4T4, _RclStr04

119 cycles, ConvertString4D, _RclStr04

2218 cycles, ConvertString4DS, _RclStr04

*** STOP and END ***

***** Time table *****

107  cycles, ConvertString4Y0, direct - no spaces, no zeroes
119  cycles, ConvertString4D, direct
122  cycles, ConvertString4YF, direct
127  cycles, ConvertString4Y, direct
138  cycles, ConvertString4YM, direct
151  cycles, ConvertString4TW, code table
169  cycles, ConvertString4TY, code table
177  cycles, ConvertString4TX, xlatb
211  cycles, ConvertString4T4, code table
231  cycles, ConvertString4T, xlatb
452  cycles, ConvertString4BW, BCD
455  cycles, ConvertString4BF, BCD
528  cycles, ConvertString4BY, BCD
566  cycles, ConvertString4BZ, BCD
2218  cycles, ConvertString4DS, direct, save FPU
2642  cycles, ConvertString4BX, BCD, save FPU
2665  cycles, ConvertString4B, BCD, save FPU
********** END **********
Title: Re: Converting string to real4
Post by: Gunther on April 15, 2013, 05:05:59 AM
Hi RuiLoureiro

here are my results with an i7 (Windows 64 bit):

Quote
converting _RclStr04 +1234.567

677 cycles, ConvertString4, _RclStr04

636 cycles, ConvertString4BX, _RclStr04

208 cycles, ConvertString4BZ, _RclStr04

198 cycles, ConvertString4BY, _RclStr04

195 cycles, ConvertString4BW, _RclStr04

182 cycles, ConvertString4BF, _RclStr04

44 cycles, ConvertString4Y0, _RclStr04

50 cycles, ConvertString4Y, _RclStr04

46 cycles, ConvertString4YM, _RclStr04

51 cycles, ConvertString4YF, _RclStr04

84 cycles, ConvertString4T, _RclStr04

66 cycles, ConvertString4TX, _RclStr04

57 cycles, ConvertString4TY, _RclStr04

62 cycles, ConvertString4TW, _RclStr04

67 cycles, ConvertString4T4, _RclStr04

49 cycles, ConvertString4D, _RclStr04

483 cycles, ConvertString4DS, _RclStr04

*** STOP and END ***

***** Time table *****

44  cycles, ConvertString4Y0, direct - no spaces, no zeroes
46  cycles, ConvertString4YM, direct
49  cycles, ConvertString4D, direct
50  cycles, ConvertString4Y, direct
51  cycles, ConvertString4YF, direct
57  cycles, ConvertString4TY, code table
62  cycles, ConvertString4TW, code table
66  cycles, ConvertString4TX, xlatb
67  cycles, ConvertString4T4, code table
84  cycles, ConvertString4T, xlatb
182  cycles, ConvertString4BF, BCD
195  cycles, ConvertString4BW, BCD
198  cycles, ConvertString4BY, BCD
208  cycles, ConvertString4BZ, BCD
483  cycles, ConvertString4D, direct, save FPU
636  cycles, ConvertString4BX, BCD, save FPU
677  cycles, ConvertString4B, BCD, save FPU
********** END **********

Gunther
Title: Re: Converting string to real4
Post by: RuiLoureiro on April 15, 2013, 05:27:34 AM
Hi Gunther
                   Thanks !  :icon14:

----------------------------------------------------
Converting from string to real4 using FPU
----------------------------------------------------

    We know it is an old story that many of us know well.
    Nevertheless, there are people that want to try to write
    his own converter or they are trying to learn.
    For this reason, i will try to remember some basic concepts
    based on a general example, to be simple. This is just to
    answer some questions like «why you do this ?»,
    «why you do that ?» ...

Quote
       ----------------       
    A. introduction
       ----------------

        If our string is defined as _string db "-1234.567E+12",0
                                 or _string db "-1234.567e+12",0

        In general, we have only the symbols: '0' to '9', '+', '-', '.', 'E' and 'e'

        In general, we have 3 parts:

                    1. integer  part: -1234 ( from starting point to '.' )
                    2. decimal  part:  567  ( after '.' to 'E'           )
                    3. exponent part: +12   ( after 'E' to 0             )

        This -1234.567E+12  means this:  -1234.567 * 10^+12
       
        But    -1234.567 = -(1234 + 0.567)
         
        or               =  -1234 - 0.567  = -1234 - 567 * 10^-3
       
                         = (-1234) + (-567) * (10^-3)  (to use + instead of -)
       
             ( 0.567 = 567 * 10^-3      where 3 is the number of decimal places = ndd ).

        note: if we have an expression 10^-n, then -n means «go backward n digits»
              if we have an expression 10^+n, then +n means «go forward  n digits»


        Finally, we have the complete expression

        -1234.567E+12= -1234.567 * 10^+12 = [(-1234) + (-567 * 10^-4)] * 10^+12

                                          =  (ecx + edi * 10^-ebx) * 10^edx
        where:
                ecx = integer part
                edi = decimal part (has the same sign as the integer part)
                ebx = number of decimal places (is allways a positive value)
                edx = exponent

       -------------------------------------------------------
    B. floating point notation or scientific notation
       -------------------------------------------------------

       siiiiii.dddddddEsxxxx      where s = sign +/-         e or E = 10^ factor
                                        i = integer  digit
                                        d = decimal  digit
                                        x = exponent digit

       means or stands for:  siiiiii.ddddddd * 10^sxxxx  (well, 's' is one 's' not the same!)

       we have 3 things:
                            1. integer  part = siiiiii
                            2. decimal  part = sddddddd  (the sign is implied)
                            3  exponent part = sxxxx    => power part = 10^sxxxx


        all different cases
        ----------------------

        case 1:   1234       -> start with integer
       
        case 2:   .567       -> start with decimal (point)

        case 3:   E+12       -> start with power. this case should be error
                                because e+10 may be 2.718281828459045+10=12.718281828459045
                                and not scientific notation

        case 4: 1234.567     -> integer plus decimal

        case 5: 1234E+12     -> integer plus power

        case 6: .567E+12     -> decimal plus power

        case 7: 1234.567E+12 -> integer plus decimal plus power

        other cases: 1.234E+45 or 1.234E-45  (overflow/underflow)
       
       ------------------------------
    C.    spaces or not spaces
       ------------------------------

        Is there another meaning for -123.45 6782 than the same as -123.456782 ?
        or
        Is there another meaning for -1 23.45 67 82 than the same as -123.456782 ?

        I like to write with spaces and i dont like to get error from a converter
        if i use spaces. The converter should remove it.


       --------------------------------------
    D.   one idea to parse the string
       --------------------------------------

        note: if we want to use FPU, we should define 3 local variables
              For instance, integerDD, decimalDD, exponentDD (all dwords)
              because we cannot pass values in registers to FPU

        1. find the sign (and save it if it is negative)
       
        2. a) IntegerPart
              -----------------
             
              a1) get the character to AL and subtract 30h

              . If carry set, we have 3/4 cases: 
                                               . -2  is '.'  -> go to DecimalPart
                                               . -16 is space  (if we want)
                                               . -48 is 0    => endinteger
                                               . unacceptable character
              . cmp al, 9
                jbe isdigit     -> save it or do what you want


              .  now, it must be:
                                . 21 is 'E'     -> go to ExponentPart
                                . 53 is 'e'
                                . unacceptable character

           b) DecimalPart
              ----------------

              b1) get the character to AL and subtract 30h

              . If carry set, we have 2/3 cases: 
                                               . -16 is space  (if we want)
                                               . -48 is 0    => enddecimal
                                               . unacceptable character
              . cmp al, 9
                jbe isdigit     -> save it or do what you want


              .  now, it must be:
                                . 21 is 'E'     -> go to ExponentPart
                                . 53 is 'e'
                                . unacceptable character

           c) ExponentPart
              ------------------

              c1) find the sign (and save it if it is negative)
             
              c2) get the character to AL and subtract 30h

              . If carry set, we have 2/3 cases: 
                                               . -16 is space  (if we want)
                                               . -48 is 0    => endexponent
                                               . unacceptable character
              . cmp al, 9
                jbe isdigit     -> save it or do what you want


              .  now it must be:
                                . unacceptable character
           

        endinteger: we must have at least 1 integer or integer = 0 or error
        ----------
         
        enddecimal: we must have at least 1 integer or integer = 0 or error
        ----------
       
        endexponent: we must have at least 1 integer or 1 decimal or error       
        -----------               (.E should be error)
                     neg the value if negative


        3. now, we have the values of each part in integerDD, decimalDD, exponentDD

            3.1 change the sign of integerDD and decimalDD if there is sign
           
            3.2 load the values into FPU and compute the expression

                      fild    integerDD                   
                      fild    decimalDD
                     
                      multiply by 10^-ndd (ndd=number of decimal digits)

                      multiply by 10^exponentDD

        4. store the result
           (and test if there is an error if you want. The result may be infinity!)

       -----------------------------------------
    D1. one solution to remove spaces
       ------------------------------------------
       
            When we start, we test if space (al=20h) and then the sign.
           
            Whenever we start IntegerPart or DecimalPart or ExponentPart
            we test if space (al=20h.)

            If we are in IntegerPart or ExponentPart, then we test sign
            and then we test space or zeros (may be -000555).

       ---------------------------
    D2.    removing zeroes
       ---------------------------

            In cases like 000000123.25E00032 the integer part has not 9 digits but 3 
            So, while it is '0', get another and dont go to the next step.

       ---------------------------
    D3.         errors
       ---------------------------

        We have 3 types of erros:

            1. user erros

                a) expression error
               
                b) unacceptable character
               
                c) more than 8 integer digits
               
                d) more than 7 decimal digits
               
                e) more than 2 exponet digits

            2. programming errors

                a) undefined pointers

            3. FPU errors
           
                a) invalid operation

                b) overflow/underflow

                c) Indefinite or NAN number


       -------------------------------------------
       D.4  To multiply by 10 and add eax
       -------------------------------------------

            solution 1: lea  edx, [edx+edx*4]
                        lea  edx, [eax+edx*2]

            solution 2: imul edx, 10
                        add  edx, eax
            ...
           
       ---------------------------
    E.      Real4 format
       ---------------------------

            offset: +0                 +16        +22         +31
                    ---------------------------------------------
                    |f23               |          f1|e0     e7|S|
                    ---------------------------------------------

        a)  S bit 31 = sign -> 0 = positive, 1= negative

            to test sign bit:     «test eax, 80000000H»   or  «and eax, 80000000H»

        b) 8 exponent bits: bits e0-e7 , from offset 23 to 30

            to extract exponent bits:      «and eax, 7F800000H» 
           
                                        or «shl eax, 23»
                                           «and eax, 0FFh»

                                exponent bits
                                -------------
               exponent  < 0  ->   < 7Fh
            if exponent  = 0  ->   = 7Fh=127   (real expoent=0 => exponent bits=7Fh)
               exponent  > 0  ->   > 7Fh

            if expoent bits = FFh => NAN

            if NAN and fraction bits= 0 => INFINITY (S=0 => +infinity S=1 => -infinity)

            if NAN and fraction bits= 1 => INDEFINITE


        c) 23 fraction bits: bits f1 - f23, from offset 0 to 22

            to extract fraction bits:      «and eax, 07FFFFFH»

        -------------------------------
    F.   test real4 format in EAX
        -------------------------------
        move a dword from memory to eax.
        If it is in st(0), move it to memory
       
        output:
       
            stc:   is Indefinite or NAN

            clc:   is a number (not infinity)

        TestReal4       proc
       
                        or      eax, eax
                        jz      short @F
                                               
                        shr     eax, 23      ; exponent and sign in AX; AH=sign AL=exponent
                        cmp     al, 0FFh
                        je      short _isNan
                       
                        ; ---------------
                        ; is real4 number
                        ; ---------------
                @@:     clc
                        ret
                        ; --------------------------------
                        ; is INFINITY or INDEFINITY or NAN
                        ; --------------------------------
            _isNan:     stc
                        ret                       
        TestReal4       endp

        --------------------------------------
        examine 1 real4 format in EAX
        --------------------------------------
        move a dword from memory to eax
        If it is in st(0), move it to memory
       
        output:
       
            stc:   is Indefinite or NAN

            clc:    EAX = 0     is 0
                        = 1     is +INFINITY
                        = 2     is -INFINITY
                        = 3     is POSITIVE
                        = 4     is NEGATIVE

        Examine1Real4   proc
       
                        or      eax, eax
                        jnz     short @F
                       
                        ; -------------
                        ; is 0 -> EAX=0
                        ; -------------
                        clc
                        ret
                       
            @@:     mov     edx, eax
                        shr     edx, 23  ;exponent and sign in DX; DH=sign DL=exponent
                        and     eax, 07FFFFFH   ; fraction in EAX
                        ;
                        cmp     dl, 0FFh
                        je      short _isNan
                       
                        ; ---------------
                        ; is real4 number
                        ; ---------------
                        mov     eax, 3
                        shr     dh, 1
                        jnc     short _isRealP
                        ; -----------
                        ; is negative
                        ; -----------
                        add     eax, 1
                        ; -----------
                        ; is positive
                        ; -----------
        _isRealP:       clc
                        ret

        _isNan:         or      eax, eax
                        jz      short _isInfinity
                   
                        ; --------------------
                        ; is indefinite or NAN
                        ; --------------------
                        stc
                        ret

        _isInfinity:    mov     eax, 3
                        shr     dh, 1
                        jnc     short _isInfinityP

                        ; ------------
                        ; is -infinity
                        ; ------------
                        add     eax, 1

                        ; ------------
                        ; is +infinity
                        ; ------------
        _isInfinityP:   stc
                        ret
        Examine1Real4   endp

        -------------------------------------
        examine 2 real4 format in EAX
        --------------------------------------
        move a dword from memory to eax
        If it is in st(0), move it to memory
       
        output:
       
            stc:   is Indefinite or NAN

            clc:    EAX = 0     is a number
                        = 1     is INFINITY

        Examine2Real4   proc
       
                        or      eax, eax
                        jnz     short @F
                       
                        ; -------------
                        ; is 0 -> EAX=0
                        ; -------------
            _isNumber:  xor     eax, eax
                        clc
                        ret
                       
            @@:     mov     edx, eax
                        shr     edx, 23    ; exponent and sign in DX; DH=sign DL=exponent
                        and     eax, 07FFFFFH   ; fraction in EAX
                        ;
                        cmp     dl, 0FFh
                        jne     short _isNumber
                       
                        or      eax, eax
                        jz      short _isInfinity
                   
                        ; --------------------
                        ; is indefinite or NAN
                        ; --------------------
                        stc
                        ret

        _isInfinity:    mov     eax, 1
                        clc
                        ret
        Examine2Real4   endp
Title: Re: Converting string to real4
Post by: Gunther on April 15, 2013, 05:47:11 AM
Hi RuiLoureiro,

good explanation and a good refresher.  :t

Gunther
Title: Re: Converting string to real4
Post by: GoneFishing on April 15, 2013, 07:59:41 PM
Hi RuiLoureiro!
Here are tests for Celeron D:
TestCnvDD9:
ConvertString4YF
1234.0

ConvertString4T
1234.0

ConvertString4TX
1234.0

ConvertString4TY
1234.0

ConvertString4TW
1234.0

ConvertString4T4
1234.0

ConvertString4D
1234.0

ConvertString4DS
1234.0

*** STOP RclStr01 +1234 ***
converting _RclStr02 .567

ConvertString4B
1 ERROR eax
ConvertString4BX
1 ERROR eax
ConvertString4BZ
1 ERROR eax
ConvertString4BY
1 ERROR eax
ConvertString4BW
1 ERROR eax
ConvertString4BF
1 ERROR eax
ConvertString4Y0
0.567

ConvertString4Y
0.567

ConvertString4YM
0.567

ConvertString4YF
0.567

ConvertString4T
0.567

ConvertString4TX
0.567

ConvertString4TY
0.567

ConvertString4TW
0.567

ConvertString4T4
0.567

ConvertString4D
0.567

ConvertString4DS
0.567

*** STOP RclStr02 .567 ***
converting _RclStr03 E+12

ConvertString4B
1 ERROR eax
ConvertString4BX
1 ERROR eax
ConvertString4BZ
1 ERROR eax
ConvertString4BY
1 ERROR eax
ConvertString4BW
1 ERROR eax
ConvertString4BF
1 ERROR eax
ConvertString4Y0
1 ERROR eax
ConvertString4Y
1 ERROR eax
ConvertString4YM
1 ERROR eax
ConvertString4YF
1 ERROR eax
ConvertString4T
1 ERROR eax
ConvertString4TX
1 ERROR eax
ConvertString4TY
1 ERROR eax
ConvertString4TW
1 ERROR eax
ConvertString4T4
1 ERROR eax
ConvertString4D
1 ERROR eax
ConvertString4DS
1 ERROR eax
*** STOP RclStr03 E+12 ***
converting _RclStr04 +1234.567

ConvertString4B
1234.567

ConvertString4BX
1234.567

ConvertString4BZ
1234.567

ConvertString4BY
1234.567

ConvertString4BW
1234.567

ConvertString4BF
1234.567

ConvertString4Y0
1234.567

ConvertString4Y
1234.567

ConvertString4YM
1234.567

ConvertString4YF
1234.567

ConvertString4T
1234.567

ConvertString4TX
1234.567

ConvertString4TY
1234.567

ConvertString4TW
1234.567

ConvertString4T4
1234.567

ConvertString4D
1234.567

ConvertString4DS
1234.567

*** STOP RclStr04 +1234.567 ***
converting _RclStr05 +1234E+12

ConvertString4B
1.2339999E+15

ConvertString4BX
1.2339999E+15

ConvertString4BZ
1.2339999E+15

ConvertString4BY
1.2339999E+15

ConvertString4BW
1.2339999E+15

ConvertString4BF
1.2339999E+15

ConvertString4Y0
1.2339999E+15

ConvertString4Y
1.2339999E+15

ConvertString4YM
1.2339999E+15

ConvertString4YF
1.2339999E+15

ConvertString4T
1.2339999E+15

ConvertString4TX
1.2339999E+15

ConvertString4TY
1.2339999E+15

ConvertString4TW
1.2339999E+15

ConvertString4T4
1.2339999E+15

ConvertString4D
1.2339999E+15

ConvertString4DS
1.2339999E+15

*** STOP RclStr05 +1234E+12 ***
converting _RclStr06 .567E+12

ConvertString4B
1 ERROR eax
ConvertString4BX
1 ERROR eax
ConvertString4BZ
1 ERROR eax
ConvertString4BY
1 ERROR eax
ConvertString4BW
1 ERROR eax
ConvertString4BF
1 ERROR eax
ConvertString4Y0
5.6699997E+11

ConvertString4Y
5.6699997E+11

ConvertString4YM
5.6699997E+11

ConvertString4YF
5.6699997E+11

ConvertString4T
5.6699997E+11

ConvertString4TX
5.6699997E+11

ConvertString4TY
5.6699997E+11

ConvertString4TW
5.6699997E+11

ConvertString4T4
5.6699997E+11

ConvertString4D
5.6699997E+11

ConvertString4DS
5.6699997E+11

*** STOP RclStr06 .567E+12 ***
converting _RclStr07 +1234.567E+12

ConvertString4B
1.234567E+15

ConvertString4BX
1.234567E+15

ConvertString4BZ
1.234567E+15

ConvertString4BY
1.234567E+15

ConvertString4BW
1.234567E+15

ConvertString4BF
1.234567E+15

ConvertString4Y0
1.234567E+15

ConvertString4Y
1.234567E+15

ConvertString4YM
1.234567E+15

ConvertString4YF
1.234567E+15

ConvertString4T
1.234567E+15

ConvertString4TX
1.234567E+15

ConvertString4TY
1.234567E+15

ConvertString4TW
1.234567E+15

ConvertString4T4
1.234567E+15

ConvertString4D
1.234567E+15

ConvertString4DS
1.234567E+15

*** STOP RclStr07 +1234.567E+12 ***
converting _RclStr08 +000000 012 34.56 7 E + 000012

ConvertString4B
3 ERROR eax
ConvertString4BX
3 ERROR eax
ConvertString4BZ
3 ERROR eax
ConvertString4BY
3 ERROR eax
ConvertString4BW
3 ERROR eax
ConvertString4BF
1 ERROR eax
ConvertString4Y0
1 ERROR eax
ConvertString4Y
1.234567E+15

ConvertString4YM
1.234567E+15

ConvertString4YF
1.234567E+15

ConvertString4T
1.234567E+15

ConvertString4TX
1.234567E+15

ConvertString4TY
1.234567E+15

ConvertString4TW
1.234567E+15

ConvertString4T4
1.234567E+15

ConvertString4D
1.234567E+15

ConvertString4DS
1.234567E+15

*** STOP RclStr08 +000000 012 34.56 7 E + 000012 ***
converting _RclStr09 +1.234E+45

ConvertString4B
8 ERROR eax
ConvertString4BX
8 ERROR eax
ConvertString4BZ
8 ERROR eax
ConvertString4BY
8 ERROR eax
ConvertString4BW
8 ERROR eax
ConvertString4BF
8 ERROR eax
ConvertString4Y0
8 ERROR eax
ConvertString4Y
8 ERROR eax
ConvertString4YM
8 ERROR eax
ConvertString4YF
8 ERROR eax
ConvertString4T
8 ERROR eax
ConvertString4TX
8 ERROR eax
ConvertString4TY
8 ERROR eax
ConvertString4TW
8 ERROR eax
ConvertString4T4
8 ERROR eax
ConvertString4D
8 ERROR eax
ConvertString4DS
8 ERROR eax
*** STOP RclStr09 +1.234E+45 ***
converting _RclStr10 +1.234E-45

ConvertString4B
8 ERROR eax
ConvertString4BX
8 ERROR eax
ConvertString4BZ
8 ERROR eax
ConvertString4BY
8 ERROR eax
ConvertString4BW
8 ERROR eax
ConvertString4BF
8 ERROR eax
ConvertString4Y0
7 ERROR eax
ConvertString4Y
1.4012985E-45

ConvertString4YM
1.4012985E-45

ConvertString4YF
1.4012985E-45

ConvertString4T
1.4012985E-45

ConvertString4TX
1.4012985E-45

ConvertString4TY
1.4012985E-45

ConvertString4TW
1.4012985E-45

ConvertString4T4
1.4012985E-45

ConvertString4D
1.4012985E-45

ConvertString4DS
1.4012985E-45

*** STOP RclStr10 +1.234E-45 and END ***


TestCncDD10:
Quoteconverting _RclStr04 +1234.567

2566 cycles, ConvertString4, _RclStr04

2662 cycles, ConvertString4BX, _RclStr04

603 cycles, ConvertString4BZ, _RclStr04

561 cycles, ConvertString4BY, _RclStr04

446 cycles, ConvertString4BW, _RclStr04

465 cycles, ConvertString4BF, _RclStr04

113 cycles, ConvertString4Y0, _RclStr04

128 cycles, ConvertString4Y, _RclStr04

135 cycles, ConvertString4YM, _RclStr04

125 cycles, ConvertString4YF, _RclStr04

239 cycles, ConvertString4T, _RclStr04

181 cycles, ConvertString4TX, _RclStr04

174 cycles, ConvertString4TY, _RclStr04

157 cycles, ConvertString4TW, _RclStr04

218 cycles, ConvertString4T4, _RclStr04

115 cycles, ConvertString4D, _RclStr04

2221 cycles, ConvertString4DS, _RclStr04

*** STOP and END ***

***** Time table *****

113  cycles, ConvertString4Y0, direct - no spaces, no zeroes
115  cycles, ConvertString4D, direct
125  cycles, ConvertString4YF, direct
128  cycles, ConvertString4Y, direct
135  cycles, ConvertString4YM, direct
157  cycles, ConvertString4TW, code table
174  cycles, ConvertString4TY, code table
181  cycles, ConvertString4TX, xlatb
218  cycles, ConvertString4T4, code table
239  cycles, ConvertString4T, xlatb
446  cycles, ConvertString4BW, BCD
465  cycles, ConvertString4BF, BCD
561  cycles, ConvertString4BY, BCD
603  cycles, ConvertString4BZ, BCD
2221  cycles, ConvertString4D, direct, save FPU
2566  cycles, ConvertString4B, BCD, save FPU
2662  cycles, ConvertString4BX, BCD, save FPU
********** END **********

Thanks for your explanations on floating point basics . That's just what I want to understand (I'm among those trying to learn)
:t
Title: Re: Converting string to real4
Post by: dedndave on April 16, 2013, 12:47:51 AM
going from a real to a string is fun
going from a string to a real is hard work   :t

i was wondering - without me reading 15 more miles of documentation
do the fraction bits have any meaning for NaN's ?

EDIT - i see they can carry a "payload"
not much in the way of a description, though - lol
other than it may be some sort of ordinal indicating where the problem originated
Title: Re: Converting string to real4
Post by: RuiLoureiro on April 20, 2013, 05:05:00 AM
Quote from: Gunther on April 15, 2013, 05:47:11 AM
Hi RuiLoureiro,

good explanation and a good refresher.  :t

Gunther

:biggrin:
                 Thanks  Gunther :t
Title: Re: Converting string to real4
Post by: RuiLoureiro on April 20, 2013, 05:10:51 AM
Quote from: vertograd on April 15, 2013, 07:59:41 PM
Hi RuiLoureiro!
...
Thanks for your explanations on floating point basics . That's just what I want to understand (I'm among those trying to learn)
:t

Hi vertograd  :t
                          I dont like to do things without some explanations
                          i was a teacher so...
                          And i try to be clear, but sometimes ... we dont know
                          Thanks
                          more: this converter was the best i did
Title: Re: Converting string to real4
Post by: RuiLoureiro on April 20, 2013, 06:22:19 AM
Quote from: dedndave on April 16, 2013, 12:47:51 AM
going from a real to a string is fun
going from a string to a real is hard work   :t

i was wondering - without me reading 15 more miles of documentation
do the fraction bits have any meaning for NaN's ?

Dave,
                            i dont know. I think that FPU set it to NAN when it fails to
                            do some operation and set fraction to 0 if beyond the limit.
                            We need to know the details about the hardware, thing
                            that i have no time now to follow.
Title: Re: Converting string to real4
Post by: dedndave on April 20, 2013, 07:19:12 AM
the special case values for REAL4 and REAL8 are pretty simple   :biggrin:
a few more caveats when you do REAL10
Title: Re: Converting string to real4
Post by: RuiLoureiro on April 20, 2013, 11:54:24 PM
Quote from: dedndave on April 20, 2013, 07:19:12 AM
the special case values for REAL4 and REAL8 are pretty simple   :biggrin:
a few more caveats when you do REAL10
What ? the calculator works with real10, i dont know any problems  :biggrin:
Title: Re: Converting string to real4
Post by: dedndave on April 21, 2013, 01:23:04 AM
my mistake, Rui   :redface:

i guess going from Ascii Decimal to REAL, you don't encounter all the caveats
it either fits or it doesn't - lol
and if it doesn't fit, you can assign the largest or smalllest value that does fit   :biggrin:

i was thinking about going from REAL to Ascii Decimal
the REAL4 and REAL8 formats are a little simpler than REAL10

REAL4/REAL8
Exponent   Fraction   Meaning

   0          0       Signed Zero
   0        <> 0      Signed Denormal
Other       Any      Signed Normal
All 1's       0       Signed Infinity
All 1's     <> 0      NaN


REAL10
  Exponent                     Significand                  Meaning

    0000       0000_0000_0000_0000                          Signed Zero
               0000_0000_0000_0001 to 7FFF_FFFF_FFFF_FFFF   Signed Denormal
               8000_0000_0000_0000 to FFFF_FFFF_FFFF_FFFF   Signed Pseudo-Denormal

0001 to 7FFE   0000_0000_0000_0000 to 7FFF_FFFF_FFFF_FFFF   Invalid
               8000_0000_0000_0000 to FFFF_FFFF_FFFF_FFFF   Signed Normal

    7FFF       0000_0000_0000_0000 to 7FFF_FFFF_FFFF_FFFF   Invalid
               8000_0000_0000_0000                          Signed Infinity
               8000_0000_0000_0001 to BFFF_FFFF_FFFF_FFFF   Signaling NaN
               C000_0000_0000_0000                          Indefinite Quiet NaN
               C000_0000_0000_0001 to FFFF_FFFF_FFFF_FFFF   Quiet NaN
Title: Re: Converting string to real4
Post by: RuiLoureiro on April 21, 2013, 05:13:46 AM
Good to know, Dave !  :t
One of these days i will use that info
Title: Re: Converting string to real4
Post by: RuiLoureiro on April 24, 2013, 04:27:58 AM
Quote
REAL10
  Exponent                     Significand                  Meaning

    0000       0000_0000_0000_0000                          Signed Zero
               0000_0000_0000_0001 to 7FFF_FFFF_FFFF_FFFF   Signed Denormal
               8000_0000_0000_0000 to FFFF_FFFF_FFFF_FFFF   Signed Pseudo-Denormal

0001 to 7FFE   0000_0000_0000_0000 to 7FFF_FFFF_FFFF_FFFF   Invalid
               8000_0000_0000_0000 to FFFF_FFFF_FFFF_FFFF   Signed Normal

    7FFF       0000_0000_0000_0000 to 7FFF_FFFF_FFFF_FFFF   Invalid
               8000_0000_0000_0000                  Signed Infinity
               8000_0000_0000_0001 to BFFF_FFFF_FFFF_FFFF   Signaling NaN
               C000_0000_0000_0000                          Indefinite Quiet NaN
               C000_0000_0000_0001 to FFFF_FFFF_FFFF_FFFF   Quiet NaN
Dave,
          when exponent is 7FFF

is this -Infinity ?
8000_0000_0000_0000                  Signed Infinity
so this is +Infinity, no ?
0000_0000_0000_0000                  Signed Infinity

So, where is the bit 79 = sign bit ?
If the S+exponent = 7FFFh -> sign = +
                              = FFFFh -> sign = -
Where is the problem ?
Title: Re: Converting string to real4
Post by: dedndave on April 24, 2013, 04:35:00 AM
the problem is, you are looking at info for the REAL10 format
there are 10 bytes, or 5 words - you are looking at 4 words   :P
the first column shows the exponent, bits 78 to 64
the second column shows the significand, bits 63 to 0

+infinity = 7FFF_8000_0000_0000_0000
-infinity = FFFF_8000_0000_0000_0000
Title: Re: Converting string to real4
Post by: RuiLoureiro on April 24, 2013, 04:46:08 AM
Quote from: dedndave on April 24, 2013, 04:35:00 AM
the problem is, you are looking at info for the REAL10 format
there are 10 bytes, or 5 words - you are looking at 4 words   :P
the first column shows the exponent, bits 78 to 64
the second column shows the significand, bits 63 to 0

+infinity = 7FFF_8000_0000_0000_0000
-infinity = FFFF_8000_0000_0000_0000

Ohh yes it is
                    ; --------------------------
                    ;     examine real 10
                    ; --------------------------
Quote
                    mov      eax, dword ptr [ebx+0]
                    mov      ecx, dword ptr [ebx+4]
                   
                    mov      dx,  word ptr [ebx+8]
                    shl        dx, 1                                ; move sign -> carry
                    cmp      dx, 0FFFEH
                    je         short _isNAN                    ; All = 1
                    ;
                    ;
                    ;
                    and     ecx, 80000000h
                    jnz     short _start
                    jz      _iszero

                    ; -------------------
                    ;    It is NAN
                    ; -------------------
        _isNAN: or      eax, eax
                    jnz     _erro1                  <--------- NAN

                    xor     ecx, 80000000h
                    jnz     _erro1                  <--------- NAN

                    mov     dx,  word ptr [ebx+8]

                    mov     al, '+'
   
                    and     dx, 8000H                   
                    jz      _isinfinity     ; is +infinity

                    ;------------
                    ; is -infinity
                    ; ------------
                    mov     al, '-'                   
                    jmp     _isinfinity   ; is -infinity
                                       
                    ; --------------------
                    ;    test for sign
                    ; --------------------
        _start:  mov     dx, word ptr [ebx+8]
Title: Re: Converting string to real4
Post by: dedndave on April 24, 2013, 04:54:40 AM
REAL10
  Exponent                     Significand                  Meaning

    0000       0000_0000_0000_0000                          Signed Zero
               0000_0000_0000_0001 to 7FFF_FFFF_FFFF_FFFF   Signed Denormal
               8000_0000_0000_0000 to FFFF_FFFF_FFFF_FFFF   Signed Pseudo-Denormal

0001 to 7FFE   0000_0000_0000_0000 to 7FFF_FFFF_FFFF_FFFF   Invalid
               8000_0000_0000_0000 to FFFF_FFFF_FFFF_FFFF   Signed Normal

    7FFF       0000_0000_0000_0000 to 7FFF_FFFF_FFFF_FFFF   Invalid
               8000_0000_0000_0000                          Signed Infinity
               8000_0000_0000_0001 to BFFF_FFFF_FFFF_FFFF   Signaling NaN
               C000_0000_0000_0000                          Indefinite Quiet NaN
               C000_0000_0000_0001 to FFFF_FFFF_FFFF_FFFF   Quiet NaN


you might find it easier to deal with the exponent like this, rather than using SHL
        movzx   edx,  word ptr [ebx+8]
        mov     ecx, dword ptr [ebx+4]
        mov     _Sign, edx                     ;a local variable to save the sign for later
        mov     eax, dword ptr [ebx+0]
        and     dx, 7FFFh
        je      Test_Exp_0_Special_Values

        cmp     dx, 7FFFh
        je      Test_Exp_7FFF_Special_Values

        test    ecx, ecx
        jns     Invalid_Value

the only special values for exponent = 0 are signed zeros
so - if the significand is not zero, increment the exponent and evaluate it the same as a normal

all values are special for exponent = 7FFF

sooner or later, you are going to want the exponent with bit 0 right-justified   :P
Title: Re: Converting string to real4
Post by: dedndave on April 24, 2013, 05:16:47 AM
the one i am writing will evaluate all reals
you pass it a pointer to the real, and a wParam
it uses an internal buffer for the string - so the caller doesn't need to make one

the high word of wParam is used to determine the type
0 = REAL10
1 = REAL4
2 = REAL8

the low word of wParam allows them to limit the number of signifigant digits

here is my outline that i am using to write the code
maybe it will help you   :t
;*****************************************************

; Operational Overview
;
;The routine is divided into the following seven sections.
;Each section begins with a detailed outline.
;
; 1. Strategy
; 2. Left-Shift Scaling (for large values)
; 3. Exponential Scaling (for small values)
; 4. Base Conversion
; 5. Scientific Formatting
; 6. Routine Exit
; 7. Special Values

;*****************************************************

;Strategy Section
;
; 1. validate wParam high word and determine type of real to be processed
;    a. type:
;       0 for real10
;       1 for real4
;       2 for real8
;    b. any other value yields an error result:
;       EAX = ERROR_INVALID_PARAMETER = 87
;       ECX = 0
;       EDX = pointer to null string
; 2. if wParam low word is 0, set the default number of digits
;    a. default maximum signifigant digits:
;       21 digits for real10
;       9 digits for real4
;       17 digits for real8
; 3. store the sign for later use (refer to the Scientific Format code section)
;    a. stored in a local variable: bit 31 clear if positive, set if negative
; 4. filter out special values (refer to the Special Values code section)
;    a. for all real types:
;       signed 0
;       signed infinity
;    b. additional special value for real4 and real8 types:
;       NaN
;    c. additional special values for real10 type:
;       Indefinite QNaN
;       QNaN
;       SNaN
;       Invalid
; 5. standardize numerical format, allowing all types to be processed the same way
;    a. sign stored in a local variable (see part 3)
;    b. exponent:
;       real10 exponent is 15 bits of the high word, sign bit removed
;       real4 exponent is 8 bits of the high word, sign bit removed, shifted right by 7
;       real8 exponent is 11 bits of the high word, sign bit removed, shifted right by 4
;    c. qword significand:
;       for real10 type, integer bit 63 is explicit
;       for real4 type, integer bit 23 is set if it is not a denormal value
;       for real8 type, integer bit 52 is set if it is not a denormal value
; 6. adjust exponent by subtracting "fraction-adjusted" bias
;    a. for denormal values, we add one to the exponent, then process as a normal
;    b. fraction-adjusted bias:
;       real10 bias is 16383, fraction-adjusted bias is 16383+63 = 16446
;       real4 bias is 127, fraction-adjusted bias is 127+23 = 150
;       real8 bias is 1023, fraction-adjusted bias is 1023+52 = 1075
; 7. branch according to exponent
;    a. if the fraction-adjusted exponent is 0, no scaling required, do base conversion
;    b. if the fraction-adjusted exponent is positive, scale by left-shifting
;    c. if the fraction-adjusted exponent is negative, scale by exponentiation

;*****************************************************
Title: Re: Converting string to real4
Post by: RuiLoureiro on April 24, 2013, 07:07:31 AM
Quote from: dedndave on April 24, 2013, 04:54:40 AM

you might find it easier to deal with the exponent like this, rather than using SHL
        movzx   edx,  word ptr [ebx+8]
        mov     ecx, dword ptr [ebx+4]
        mov     _Sign, edx                     ;a local variable to save the sign for later
        mov     eax, dword ptr [ebx+0]
        and     dx, 7FFFh
        je      Test_Exp_0_Special_Values

        cmp     dx, 7FFFh
        je      Test_Exp_7FFF_Special_Values

        test    ecx, ecx
        jns     Invalid_Value


Hummm Dave, i dont follow your argument. I remove the sign and if i may i go to
start. I read it again and i dont want to change it, for now.

Quote
the only special values for exponent = 0 are signed zeros
so - if the significand is not zero, increment the exponent and evaluate it the same as a normal
no, i dont want to follow this. What is there is what is there.
...

Quote
sooner or later, you are going to want the exponent with bit 0 right-justified   :P
no, depends and we have it in a variable
                You may replace test by or, i dont use it
Title: Re: Converting string to real4
Post by: dedndave on April 24, 2013, 08:51:03 AM
Quotethe only special values for exponent = 0 are signed zeros
so - if the significand is not zero, increment the exponent and evaluate it the same as a normal
Quoteno, i dont want to follow this. What is there is what is there.

from the computation guide...
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_math.html (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_math.html)

denormals (aka subnormals) and pseudo-denormals are stored with the exponent adjusted to 0
to make them evaluate the same as a normal, add 1 to the exponent
the 0 value is used to signal that they are not normals

REAL4 and REAL8 denormals are similar, but you do not set the implicit integer bit

(http://img12.imageshack.us/img12/6/denorms.png)

Title: Re: Converting string to real4
Post by: RuiLoureiro on April 24, 2013, 09:25:47 PM
Hi Dave,
         Yesterday i had not enough time to pay attention
         to some details. I wrote 14 procs to real10 and real8
         and tested it.
         
         Here, Table 1 is your table and
         Table 2 is what i want to do
Table 1
Quote
REAL10
  Exponent                     Significand                  Meaning

    0000   0000_0000_0000_0000                          Signed Zero
               0000_0000_0000_0001 to 7FFF_FFFF_FFFF_FFFF   Signed Denormal
               8000_0000_0000_0000 to FFFF_FFFF_FFFF_FFFF   Signed Pseudo-Denormal

0001 to 7FFE   0000_0000_0000_0000 to 7FFF_FFFF_FFFF_FFFF   Invalid
               8000_0000_0000_0000 to FFFF_FFFF_FFFF_FFFF   Signed Normal

    7FFF       0000_0000_0000_0000 to 7FFF_FFFF_FFFF_FFFF   Invalid
               8000_0000_0000_0000                          Signed Infinity
               8000_0000_0000_0001 to BFFF_FFFF_FFFF_FFFF   Signaling NaN
               C000_0000_0000_0000                          Indefinite Quiet NaN
               C000_0000_0000_0001 to FFFF_FFFF_FFFF_FFFF   Quiet NaN

Table 2
Quote
REAL10
  Exponent                     Significand                  Meaning

    0000             0000_0000_0000_0000                          ZERO
                         0000_0000_0000_0001 to 7FFF_FFFF_FFFF_FFFF   Denormal
                         8000_0000_0000_0000 to FFFF_FFFF_FFFF_FFFF   Pseudo-Denormal

0001 to 7FFE     0000_0000_0000_0000 to 7FFF_FFFF_FFFF_FFFF <-ERROR_1 (*)
                          8000_0000_0000_0000 to FFFF_FFFF_FFFF_FFFF <------- REAL10

    7FFF             0000_0000_0000_0000 to 7FFF_FFFF_FFFF_FFFF   ERROR_1
                        8000_0000_0000_0000                                           Infinity
                        8000_0000_0000_0001 to BFFF_FFFF_FFFF_FFFF   ERROR_1
                        C000_0000_0000_0000                                        ERROR_1
                        C000_0000_0000_0001 to FFFF_FFFF_FFFF_FFFF   ERROR_1
(*) particular case

        To follow it better the 10 bytes pointed by EBX are:

                        string pointed by edi
                       
                        mov     eax, [ebx+0]
                        mov     ecx, [ebx+4]
                        mov     dx,  [ebx+8]     ; s+exponent

        We have some ways to decode it. You have your own, of course.
        But my idea is to think that the number we have is a real10 number.
        It is not error, it is not infinity, it is not NAN, etc, it
        is a real10 number.

Quote
        In this way, first, we test exponent for 7FFFh.

          . If exponent=7FFFh i assume "it_is_NAN", so... we have error/infinity.
         
          . If ECX has sign bit set:

                    . If exponent <> 0  -> is real10  -> goto _start
                    . If                =  0  -> is Pseudo-Denormal
       
          . If ECX has NO sign bit set:

                    . If exponent <> 0  -> is error
                    . If                =  0  -> is Zero/Denormal
                   
            Is zero if  «or  eax,ecx» is zero.
           
---------------------------------------------------------------------------------------
        The problem is: what to do if it is Pseudo-Denormal or Denormal
        and why. If we need to change the exponent, we need a local
        variable to set the 10 bytes from where we load it to FPU.
        The problem of sign: we may set it to string immediately.
        If we use BCD we dont need the sign, but we may set it to
        string immediately, also. If it is error, we remove it,
        no problems: start at edi-1. If it is zero, also.

        I think it is correct, now.
Title: Re: Converting string to real4
Post by: dedndave on April 25, 2013, 01:00:35 AM
what's it called ?
"lemniscate"
you'd think i would have known that   :(

ASCII = 0ECh, if you have the right font
in console mode, it displays correctly
but, if i redirect it to a text file, it is the letter "i"   :redface:
i don't like that, because it's too close to the lower case "iota", which is used for (-1)1/2

(http://media.techtarget.com/WhatIs/images/lemniscate.gif)

(http://mathworld.wolfram.com/images/eps-gif/LemniscateToricSection_800.gif)
Title: Re: Converting string to real4
Post by: RuiLoureiro on April 25, 2013, 01:03:50 AM
Here 3 macros to examine real10
Is there any problem ?
I like EXAMINE3REAL10.

Quote
EXAMINE1REAL10  MACRO       ; 39 instructions

                ; --------------------------
                ;          examine
                ; --------------------------
                mov     eax, dword ptr [ebx+0]                               
                mov     ecx, dword ptr [ebx+4]
                   
                mov     dx,  word ptr [ebx+8]
                shl     dx, 1                      ; remove sign to carry
                cmp     dx, 0FFFEH                 ; <=> 7FFFh
                je      short _isNAN               ; all = 1
               
                ; --------------------
                ;   it is not NAN
                ; --------------------
                and     ecx, 80000000h
                jz      short _noECXsign
               
                ; --------------------------
                ; It must be Real10/Denormal
                ; --------------------------                 
                or      dx, dx
                jnz     short _start
                jmp     _isDenormal
               
               
    _noECXsign: or      dx, dx
                jnz     _erro1
               
                ; --------------------
                ; may be Zero/Denormal
                ; --------------------
                or      eax, ecx               
                jz      _iszero

                ; --------------------
                ;   may be Denormal
                ;  or Pseudo-Denormal
                ; --------------------
    _isDenormal:mov     eax, dword ptr [ebx+0]
                lea     ebx, Real10Buf
                ;
                mov     [ebx+0], eax
                mov     [ebx+4], ecx
                mov     dx, word ptr [ebx+8]
                mov     dl, 1
                mov     word ptr [ebx+8], dx
                jmp     _start
               
                ; -------------------
                ;    It is NAN
                ; -------------------
    _isNAN:     or      eax, eax
                jnz     _erro1
               
                ; ---------------------
                ;       eax= 0
                ; ecx must be 80000000h
                ;    to be infinity
                ; ---------------------
                xor     ecx, 80000000h
                jnz     _erro1
               
                ; --------------
                ; It is infinity
                ; -------------- 
                mov     dx,  word ptr [ebx+8]

                mov     al, '+'
   
                and     dx, 8000H                   
                jz      _isinfinity     ; is +infinity

                ;------------
                ; is -infinity
                ; ------------
                mov     al, '-'                   
                jmp     _isinfinity     ; is -infinity
                                       
                ; --------------------
                ;    test for sign
                ; --------------------
    _start:     mov     al, ' '
                ;
                and     word ptr [ebx+8], 8000H   
                jz      short @F
                ;
                mov     al, '-'
               
        @@:     mov     byte ptr [edi], al
                add     edi, 1
                   
                ; ---------------------
                ; start load the real 10
                ; ---------------------
                fld      tbyte ptr [ebx]    ; st(0) = X     
ENDM
; --------------------------------------------------------------
another one

Quote
EXAMINE2REAL10  MACRO       ; 37 instructions
                ; --------------------------
                ;          examine
                ; --------------------------
                mov     eax, dword ptr [ebx+0]                               
                mov     ecx, dword ptr [ebx+4]
                   
                mov     dx,  word ptr [ebx+8]
                shl     dx, 1                      ; remove sign -> carry
                cmp     dx, 0FFFEH
                je      short _isNAN               ; all = 1

                or      dx, dx
                jnz     short _ECXsign
                               
                ; --------------------
                ; may be Zero/Denormal
                ; --------------------
                or      eax, ecx               
                jz      _iszero
               
                ; --------------------
                ;    is Denormal
                ; or Pseudo-Denormal
                ; --------------------
                mov     eax, dword ptr [ebx+0]
                lea     ebx, Real10Buf
                ;
                mov     [ebx+0], eax
                mov     [ebx+4], ecx
                mov     dx, word ptr [ebx+8]
                mov     dl, 1
                mov     word ptr [ebx+8], dx               
                jmp     _start
               
    _ECXsign:   and     ecx, 80000000h
                jnz     short _start
                jmp     _erro1
   
                ; -------------------
                ;    It is NAN
                ; -------------------
    _isNAN:     or      eax, eax
                jnz     _erro1
               
                ; ---------------------
                ;       eax= 0
                ; ecx must be 80000000h
                ;    to be infinity
                ; ---------------------
                xor     ecx, 80000000h
                jnz     _erro1
               
                ; --------------
                ; It is infinity
                ; -------------- 
                mov     dx,  word ptr [ebx+8]

                mov     al, '+'
   
                and     dx, 8000H                   
                jz      _isinfinity     ; is +infinity

                ;------------
                ; is -infinity
                ; ------------
                mov     al, '-'                   
                jmp     _isinfinity     ; is -infinity
                                       
                ; --------------------
                ;    test for sign
                ; --------------------
    _start:     mov     al, ' '
                ;
                and     word ptr [ebx+8], 8000H   
                jz      short @F
                ;
                mov     al, '-'
               
        @@:     mov     byte ptr [edi], al
                add     edi, 1
                   
                ; ---------------------
                ; start load the real 10
                ; ---------------------
                fld      tbyte ptr [ebx]    ; st(0) = X     
ENDM
; ------------------------------------------------------------
another one

Quote
EXAMINE3REAL10  MACRO       ; 31 instructions
                ; --------------------------
                ;          examine
                ; --------------------------
                mov     ecx, dword ptr [ebx+4]

                mov     al, 20h                   
                mov     dx,  word ptr [ebx+8]
                shl     dx, 1                      ; remove sign -> carry
                jnc     short @F
                mov     al, '-'
                ;
        @@:     mov     byte ptr [edi], al
                add     edi, 1
               
                mov     eax, dword ptr [ebx+0]
               
                cmp     dx, 0FFFEH
                je      short _isNAN               ; all = 1

                or      dx, dx
                jnz     short _ECXsign
                               
                ; --------------------
                ; may be Zero/Denormal
                ; --------------------
                or      eax, ecx               
                jz      _iszero
               
                ; --------------------
                ;    is Denormal
                ; or Pseudo-Denormal
                ; --------------------
                mov     eax, dword ptr [ebx+0]
                lea     ebx, Real10Buf          ; local 10 bytes

                ; --------------------------------
                ; the sign is alredy in the buffer
                ; --------------------------------
                add     dx, 1
                mov     [ebx+0], eax
                mov     [ebx+4], ecx
                mov     word ptr [ebx+8], dx
                jmp     _start
               
    _ECXsign:   and     ecx, 80000000h
                jnz     short _start
                jmp     _erro1
   
                ; -------------------
                ;    It is NAN
                ; -------------------
    _isNAN:     or      eax, eax
                jnz     _erro1
               
                ; ---------------------
                ;       eax= 0
                ; ecx must be 80000000h
                ;    to be infinity
                ; ---------------------
                xor     ecx, 80000000h
                jnz     _erro1
               
                ; --------------
                ; It is infinity
                ; -------------- 
                jmp     _isinfinity

                ; ---------------------
                ; start load the real 10
                ; ---------------------
    _start:     fld      tbyte ptr [ebx]    ; st(0) = X
ENDM
Title: Re: Converting string to real4
Post by: Gunther on April 25, 2013, 01:08:55 AM
Hi Dave,

Quote from: dedndave on April 25, 2013, 01:00:35 AM
what's it called ?
"lemniscate"

yes, that's the lemniscate; a very interesting curve.

Gunther
Title: Re: Converting string to real4
Post by: RuiLoureiro on April 25, 2013, 01:10:22 AM
Quote from: dedndave on April 25, 2013, 01:00:35 AM
what's it called ?
"lemniscate"
you'd think i would have known that   :(

ASCII = 0ECh, if you have the right font
in console mode, it displays correctly
but, if i redirect it to a text file, it is the letter "i"   :redface:
i don't like that, because it's too close to the lower case "iota", which is used for (-1)1/2

(http://media.techtarget.com/WhatIs/images/lemniscate.gif)

(http://mathworld.wolfram.com/images/eps-gif/LemniscateToricSection_800.gif)
:biggrin:
                     i guess you like geometric figures ! :greensml:
Title: Re: Converting string to real4
Post by: dedndave on April 25, 2013, 01:15:56 AM
Quote from: RuiLoureiro on April 25, 2013, 01:10:22 AM
i guess you like geometric fugures ! :greensml:

oh, i do !
especially conic sections   :P
oh - and boobs, of course (.)(.)
Title: Re: Converting string to real4
Post by: dedndave on April 25, 2013, 01:18:40 AM
Rui, the only thing i would mention is.....

the REAL10 invalid values will never be generated by the FPU
however, NaN's (including indefinites) can be generated by the FPU
Title: Re: Converting string to real4
Post by: RuiLoureiro on April 25, 2013, 05:36:51 AM
Quote from: dedndave on April 25, 2013, 01:15:56 AM
Quote from: RuiLoureiro on April 25, 2013, 01:10:22 AM
...
Title: Re: Converting string to real4
Post by: dedndave on April 25, 2013, 08:59:45 AM
 :redface:
Title: Re: Converting string to real4
Post by: dedndave on April 26, 2013, 03:03:55 AM
hi Rui,

well, i have decimal digits - i just need to work on rounding and scientific format   :P
0000_00000000_00000000: 00000000 00000002 +0
8000_00000000_00000000: 00000000 00000002 -0
0000_00000000_00000001: 00000000 00002CE7 364519953188247460252
0000_7FFFFFFF_FFFFFFFF: 00000000 00002CFA 336210314311209350589
0000_80000000_00000000: 00000000 00002CFA 336210314311209350626
0000_FFFFFFFF_FFFFFFFF: 00000000 00002CFA 672420628622418701216
0001_00000000_00000000: 00000006 00000007 Invalid
7FFE_7FFFFFFF_FFFFFFFF: 00000006 00000007 Invalid
0001_80000000_00000000: 00000000 00002CFA 336210314311209350626
4000_C90FDAA2_2168C235: 00000000 0000003F 314159265358979323851
7FFE_FFFFFFFF_FFFFFFFF: 00000000 00001345 118973149535723176502
7FFF_00000000_00000000: 00000006 00000007 Invalid
7FFF_7FFFFFFF_FFFFFFFF: 00000006 00000007 Invalid
7FFF_80000000_00000000: 00000001 00000002 +∞
FFFF_80000000_00000000: 00000001 00000002 -∞
7FFF_80000000_00000001: 00000005 00000004 SNaN
7FFF_BFFFFFFF_FFFFFFFF: 00000005 00000004 SNaN
7FFF_C0000000_00000000: 00000003 0000000F Indefinite QNaN
7FFF_C0000000_00000001: 00000004 00000004 QNaN
7FFF_FFFFFFFF_FFFFFFFF: 00000004 00000004 QNaN

00000000: 00000000 00000002 +0
80000000: 00000000 00000002 -0
00000001: 00000000 00000069 140129846432481707092
007FFFFF: 00000000 00000070 117549421069244107548
00800000: 00000000 00000070 117549435082228750796
BF800000: 00000000 00000018 100000000000000000000
7F7FFFFF: 00000000 00000027 340282346638528859811
7F800000: 00000001 00000002 +∞
FF800000: 00000001 00000002 -∞
7F800001: 00000002 00000003 NaN
7FFFFFFF: 00000002 00000003 NaN

00000000_00000000: 00000000 00000002 +0
80000000_00000000: 00000000 00000002 -0
00000000_00000001: 00000000 000002EF 494065645841246544176
000FFFFF_FFFFFFFF: 00000000 000002FF 222507385850720088902
00100000_00000000: 00000000 000002FF 222507385850720138309
BFF00000_00000000: 00000000 00000035 100000000000000000000
7FEFFFFF_FFFFFFFF: 00000000 00000135 179769313486231570814
7FF00000_00000000: 00000001 00000002 +∞
FFF00000_00000000: 00000001 00000002 -∞
7FF00000_00000001: 00000002 00000003 NaN
7FFFFFFF_FFFFFFFF: 00000002 00000003 NaN


after the hex real:, there are 2 dwords in hex
the first one is the status returned in EAX
the second one is the string length returned in ECX
although, i have truncated them all to 21 digits for testing
EDX points to the string