Does anyone know or have a routine/algo that converst ascii to double?

I can code my own version, but im hung up on translating the fraction into binary..

ie) 0.75 -> 0.1100

Because 1 * 0.5 + 1 * 0.25 = 0.75

But devising an algorithm has been challenging to say the least.

I've seen an example that does this:

0.75 * 2 = 1.5 (bit 1 = 1; sub 1 from result and do it again)

0.5 * 2 = 1.0 (bit 2 = 1; sub 1 from result and do it again)

0.0 * 2 = 0.0 (bit 3 = 0; do nothing..)

etc.

But this is still Human math.. not machine.

Any help would be appreciated..

Thanx!

:alright:

NaN

I can code my own version, but im hung up on translating the fraction into binary..

ie) 0.75 -> 0.1100

Because 1 * 0.5 + 1 * 0.25 = 0.75

But devising an algorithm has been challenging to say the least.

I've seen an example that does this:

0.75 * 2 = 1.5 (bit 1 = 1; sub 1 from result and do it again)

0.5 * 2 = 1.0 (bit 2 = 1; sub 1 from result and do it again)

0.0 * 2 = 0.0 (bit 3 = 0; do nothing..)

etc.

But this is still Human math.. not machine.

Any help would be appreciated..

Thanx!

:alright:

NaN

Well i got a routine working now.. and fairly small. But fitting bits over two DWORDS, and normalizing everything is now the issue...

The hard part is the bit stream. A double such as 23.75 has a real component (23) and a fraction (75/100). I now have an algo that will make "75" turn into binary "1100..." up to 32 bits since it fills a dedicated register in a loop.

But i may need 100 bits, it depends on how the number is conditioned and where the normalization exponent exists:

I have to now think of a good scheme that will turn 23 into normal two's:

10111 < = 23

Turn 75 into a fraction:

11 < 0.75

Append them together

10111.11

Normalize them and determine the exponent

1.011111 e4

Drop the first "1." since normalized and fit 52 bits plus a sign bit and exponent:

01111100000000000000000000000000000000000000000000

Where S=0 for positive, and Exp = 4 + 3FF = 403h (100 0000 0011)

Resulting in a final QWORD:

(0)(10000000011)(01111100000000000000000000000000000000000000000000)

MSB

Oh well.. still hacking at it..

:NaN:

The hard part is the bit stream. A double such as 23.75 has a real component (23) and a fraction (75/100). I now have an algo that will make "75" turn into binary "1100..." up to 32 bits since it fills a dedicated register in a loop.

But i may need 100 bits, it depends on how the number is conditioned and where the normalization exponent exists:

I have to now think of a good scheme that will turn 23 into normal two's:

10111 < = 23

Turn 75 into a fraction:

11 < 0.75

Append them together

10111.11

Normalize them and determine the exponent

1.011111 e4

Drop the first "1." since normalized and fit 52 bits plus a sign bit and exponent:

01111100000000000000000000000000000000000000000000

Where S=0 for positive, and Exp = 4 + 3FF = 403h (100 0000 0011)

Resulting in a final QWORD:

(0)(10000000011)(01111100000000000000000000000000000000000000000000)

MSB

Oh well.. still hacking at it..

:NaN:

Hey Bazik, I've been seachin the web all night looking for a proven algorithm (in any language) that does the IEEE double precision standard conversion. So far i have yet to find one source.

You seem to know how to find the unfindable.. you think you can hack this ;)

(Cause im not finding anything that isnt too general, or too "theory").

:alright:

NaN

You seem to know how to find the unfindable.. you think you can hack this ;)

(Cause im not finding anything that isnt too general, or too "theory").

:alright:

NaN

NaN,

Why not use the FPU?

Why not use the FPU?

NAN

If you don't have any restriction against using the FPU, you will find a string-to-float function (FpuAtoFL) in the FPU.lib library available with MASM32, with full source code. It may be of some use to you.

If your intention is to do the conversion

Raymond

If you don't have any restriction against using the FPU, you will find a string-to-float function (FpuAtoFL) in the FPU.lib library available with MASM32, with full source code. It may be of some use to you.

If your intention is to do the conversion

__without using the FPU__, you can look at the MixFromA function in the Mix.lib library available from Hutch's site, also with full source code. It uses only integer maths to get a "fixed point" binary value (16-bit signed integer portion + 16-bit fractional portion). You could easily modify the procedure to yield the IEEE floating point format since you have demonstrated your knowledge of that format.Raymond

Ya.. i somehow thought it would be simple to write my own formatting routine. But one problem layered up to the next and so on. Before i knew it im focused on solving everything one step at a time and the simple reality of "cheating" with the FPU can easily be done ( :rolleyes: ).

Thanx for bringing me back to my senses....

:NaN:

Thanx for bringing me back to my senses....

:NaN:

NaN

Couldn't resist trying it myself. I still prefer using the FPU which has much more flexibility. I gave up trying to add code to the following procedure in order to convert input given in scientific notation. I will let someone attempt that.

The following procedure has been tested on several samples and seems to be reliable. No effort has been made to optimize it.

Enjoy

Raymond

Couldn't resist trying it myself. I still prefer using the FPU which has much more flexibility. I gave up trying to add code to the following procedure in order to convert input given in scientific notation. I will let someone attempt that.

The following procedure has been tested on several samples and seems to be reliable. No effort has been made to optimize it.

Enjoy

Raymond

```
;*******************************************
```

; AtoR4

; This procedure converts a null-terminated decimal string

; to a REAL4 number using only CPU instructions (MASM syntax).

; Limitations: the integer portion must be less than 2^32,

; number of decimal digits 9 max.

; scientific notation not supported

;

; Returns EAX with 0 for success, -1 for invalid source

; and REAL4 result at destination address if successful.

;

; Raymond Filiatreault, April 2003

;

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

AtoR4 proc USES ebx esi edi lpsource:DWORD, lpdest:DWORD

LOCAL mul10 :DWORD

;----------------------------------------------------------------------

;The integer portion will be converted to binary and accumulated in EBX

;The decimal portion will be converted to binary and accumulated in ECX

;EDI will be used to retain the sign and the count of decimal digits

;ESI is used as a pointer to the source string

;

;----------------------------------------------------------------------

xor ebx,ebx

xor ecx,ecx

xor edi,edi

mov esi,lpsource

mov mul10,10

@@:

movzx eax,byte ptr [esi]

inc esi

cmp al," "

jz @B ;get rid of leading blanks

.if al == "+"

movzx eax,byte ptr [esi]

inc esi

.elseif al == "-"

stc

rcr edi,1 ;keep negative sign as most significant bit of EDI

movzx eax,byte ptr [esi]

inc esi

.endif

;********** Convert integer portion to binary ************

integer:

.if al == "."

jz decimal

.elseif al == 0

jmp finish

.elseif al >= "0" && al <= "9"

sub al,"0"

xchg eax,ebx

mul mul10

.if edx > 0

jmp error ;integer portion exceeds 2^32

.endif

add ebx,eax

.else

jmp error ;invalid character

.endif

movzx eax,byte ptr [esi]

inc esi

jmp integer

;************ Convert decimal portion to binary **************

decimal:

movzx eax,byte ptr [esi]

inc esi

.if al == 0

jmp finish

.elseif al >= "0" && al <= "9"

sub al,"0"

xchg eax,ecx

mul mul10

.if edx > 0

jmp error ;decimal portion would have more than 9 digits

.endif

add ecx,eax

.else

jmp error ;invalid character

.endif

inc edi ;bump count of decimal digits

jmp decimal

;******** Convert decimal portion to aligned binary fraction **********

finish:

mov eax,edi

shl eax,1

shr eax,1 ;to get rid of possible negative sign

.if eax > 9

jmp error ;more than 9 decimal digits

.elseif eax != 0

push ecx

mov ecx,eax

mov eax,10

@@:

dec ecx

jz @F

mul mul10

jmp @B

@@:

mov ecx,eax

pop edx

xor eax,eax

div ecx

.endif

;---------------------------------------------------------------------

; Combine the binary integer portion with the binary fraction,

; compute the biased exponent, insert the sign and join everything.

; A null integer must be treated differently than a non-null one.

;----------------------------------------------------------------------

.if ebx == 0 ;integer portion = 0?

.if eax == 0 ;decimal portion also = 0?

mov esi,lpdest

mov [esi],eax ;store 0 as the REAL4

jmp eXit ;return with success code

.endif

bsr ecx,eax ;get location of most significant "1" bit of fraction

sub ecx,32 ;->negative position of that bit from the left +1

mov edx,ecx

add edx,7fh ;gives the biased exponent

ror edx,8 ;shift the biased exponent to the upper 8 bits

shl edi,1 ;get sign bit in C flag

rcr edx,1 ;transfer it to EDX

;sign and biased exponent now in EDX

;according to IEEE format

neg ecx

shl eax,cl ;pushes out most significant "1" bit

shr eax,9 ;positions significand bits according to IEEE format

or eax,edx ;assemble REAL4

.else

bsr ecx,ebx ;get location of most significant "1" bit of integer

mov edx,ecx

add edx,7fh ;gives the biased exponent

ror edx,8 ;shift the biased exponent to the upper 8 bits

shl edi,1 ;get sign bit in C flag

rcr edx,1 ;transfer it to EDX

;sign and biased exponent now in EDX

;according to IEEE format

sub ecx,32

neg ecx

shld ebx,eax,cl ;pushes out most significant "1" bit of integer

;while pushing in most significant bits of decimal

shr ebx,9 ;positions significand bits according to IEEE format

or ebx,edx ;assemble REAL4

mov eax,ebx

.endif

mov edi,lpdest

mov [edi],eax ;store result

xor eax,eax

jmp eXit

error:

mov eax,-1

eXit:

ret

AtoR4 endp