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
Posted on 2003-04-05 15:41:43 by 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:
Posted on 2003-04-05 18:24:11 by 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
Posted on 2003-04-06 00:50:21 by NaN
NaN,

Why not use the FPU?
Posted on 2003-04-06 01:53:07 by iblis
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 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
Posted on 2003-04-06 11:24:29 by 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:
Posted on 2003-04-07 16:45:39 by 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
;*******************************************

; 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
Posted on 2003-04-07 20:03:16 by Raymond