I found I wanted to convert a floating-point value to a string, and back, without any loss of precision, if possible. This is what I came up with.
OPTION STRICT DEF NTOS$(N#) VAR S$=STR$(N#) VAR S0$="+",S1$="+",E%=0,NN#,N1%,N2% IF S$[0]=="-" THEN S0$="-" S$=RIGHT$(S$,LEN(S$)-1) N#=-N# ENDIF IF N#==0 THEN RETURN S0$+"0" ELSEIF INSTR("in",S$[0])>=0 THEN RETURN S0$+S$[0] ENDIF IF N#<1 S1$="-" NN#=N#*256 WHILE NN#<2 INC E%,8 N#=NN# NN#=N#*256 WEND NN#=N#*2 WHILE NN#<2 INC E% N#=NN# NN#=N#*2 WEND DEC N# N#=N#*POW(2,28) N1%=FLOOR(N#) DEC N#,N1% N2%=N#*POW(2,24) RETURN S0$+S1$+FORMAT$("%03X%07X%06X",E%,N1%,N2%) ELSE NN#=N#/256 WHILE NN#>=1 INC E%,8 N#=NN# NN#=N#/256 WEND NN#=N#/2 WHILE NN#>=1 INC E% N#=NN# NN#=N#/2 WEND DEC N# N#=N#*POW(2,28) N1%=FLOOR(N#) DEC N#,N1% N2%=N#*POW(2,24) RETURN S0$+S1$+FORMAT$("%03X%07X%06X",E%,N1%,N2%) ENDIF END DEF NYBBLE#(N$) RETURN ASC(N$)-48-7*(ASC(N$)>=58) END DEF STON#(S$) VAR S0$=S$[0],RESULT#=0,I%,E% S$=RIGHT$(S$,LEN(S$)-1) IF S%=="0" GOTO @ZERO ON INSTR("in",S$[0]) GOTO @INF,@NAN @NUM RESULT#=1 FOR I%=4 TO 16 RESULT#=RESULT#*16+NYBBLE#(S$[I%]) NEXT I% E%=NYBBLE#(S$[1])*256+NYBBLE#(S$[2])*16+NYBBLE#(S$[3]) IF S$[0]=="-" THEN E%=-E% RESULT#=RESULT#/POW(2,52) RESULT#=RESULT#*POW(2,E%) GOTO @END @INF RESULT#=1E200*1E200 GOTO @END @NAN RESULT#=1E200*1E200 DEC RESULT#,RESULT# GOTO @END @ZERO @END IF S0$=="-" THEN RESULT#=-RESULT# RETURN RESULT# ENDSome edge cases I have tested with:
VAR INF#=1E200*1E200 ' infinity VAR INF_N#=-INF# ' negative infinity VAR NAN#=INF#-INF# ' not-a-number VAR NAN_N#=-NAN# ' negative not-a-number VAR E#=POW(2,-1022) ' smallest positive number that can be represented VAR O#=1+POW(2,-52) ' smallest number greater than 1 that can be represented VAR E1#=E#*O# ' smallest number greater than E# that can be represented VAR T#=2-POW(2,-52) ' greatest number less than 2 that can be represented VAR M2#=POW(2,1023) ' greatest power of 2 that can be represented VAR M#=M2#*T# ' greatest number that can be represented VAR Z#=0 ' zero VAR Z_N#=-Z# ' negative zeroIt's not high-quality code. I may come back and make a neater version. If anyone discovers a value that turns out different after being passed through NTOS$ then STON#, please let me know. NAN does not 'equal' itself, for any other floating point value V# my hope is that STON#(NTOS$(V#))==V# - let me know if you find a counterexample.