mirror of
https://github.com/dschmenk/PLASMA.git
synced 2025-02-10 10:30:58 +00:00
FP <-> string library
This commit is contained in:
parent
f9447602b6
commit
129f2bf601
10
src/inc/fpstr.plh
Normal file
10
src/inc/fpstr.plh
Normal file
@ -0,0 +1,10 @@
|
||||
import fpstr
|
||||
//
|
||||
// Parse string into decrecord, return SANE conversion output
|
||||
//
|
||||
predef str2ext(str, ext)#1
|
||||
//
|
||||
// Convert extended FP to string using , return string
|
||||
//
|
||||
predef ext2str(ext, str, numdigits, expformat)#1
|
||||
end
|
239
src/libsrc/fpstr.pla
Normal file
239
src/libsrc/fpstr.pla
Normal file
@ -0,0 +1,239 @@
|
||||
//
|
||||
// SANE Extended FP to String conversion library
|
||||
//
|
||||
include "inc/cmdsys.plh"
|
||||
include "inc/sane.plh"
|
||||
//
|
||||
// Structures for DEC2BIN, BIN2DEC
|
||||
//
|
||||
struc t_decrecord
|
||||
word sgn
|
||||
word exp
|
||||
byte sig[29]
|
||||
end
|
||||
struc t_decformat
|
||||
word style
|
||||
word digits
|
||||
end
|
||||
//
|
||||
// Parse string into decrecord, return SANE conversion output
|
||||
//
|
||||
export def str2ext(str, ext)
|
||||
byte i, s, d
|
||||
byte decrec[t_decrecord]
|
||||
word sgnadj, expadj
|
||||
|
||||
decrec:sgn = 0
|
||||
decrec:exp = 0
|
||||
decrec.sig = 0
|
||||
s = 1
|
||||
i = 1
|
||||
//
|
||||
// Skip whitespace
|
||||
//
|
||||
while ^(str+i) <= ' ' and i <= ^str; i++; loop
|
||||
//
|
||||
// Check for sign
|
||||
//
|
||||
if ^(str+i) == '-'
|
||||
decrec:sgn = 1
|
||||
i++
|
||||
elsif ^(str+i) == '+'
|
||||
i++
|
||||
fin
|
||||
//
|
||||
// Skip leading zeros
|
||||
//
|
||||
while i <= ^str and ^(str+i) == '0'
|
||||
i++
|
||||
loop
|
||||
//
|
||||
// Parse number
|
||||
//
|
||||
while i <= ^str
|
||||
d = toupper(^(str+i))
|
||||
if d >= '0' and d <= '9'
|
||||
//
|
||||
// Parse digit
|
||||
//
|
||||
decrec.sig[s] = ^(str+i)
|
||||
decrec:sig++
|
||||
s++
|
||||
elsif d == '.'
|
||||
//
|
||||
// Parse decimal point
|
||||
//
|
||||
i++
|
||||
while i <= ^str
|
||||
d = toupper(^(str+i))
|
||||
if d >= '0' and d <= '9'
|
||||
decrec.sig[s] = ^(str+i)
|
||||
decrec.sig++
|
||||
decrec:exp--
|
||||
s++
|
||||
elsif d == 'E'
|
||||
i--
|
||||
break
|
||||
else
|
||||
i = ^str
|
||||
fin
|
||||
i++
|
||||
loop
|
||||
elsif d == 'E'
|
||||
//
|
||||
// Parse exponent
|
||||
//
|
||||
i++
|
||||
expadj = 0
|
||||
sgnadj = 1
|
||||
if ^(str+i) == '-'
|
||||
sgnadj = -1
|
||||
i++
|
||||
elsif ^(str+i) == '+'
|
||||
i++
|
||||
fin
|
||||
while i <= ^str
|
||||
d = ^(str+i)
|
||||
i++
|
||||
if d >= '0' and d <= '9'
|
||||
expadj = expadj * 10 + (d - '0')
|
||||
else
|
||||
i = ^str
|
||||
fin
|
||||
loop
|
||||
decrec:exp = decrec:exp + (sgnadj * expadj)
|
||||
else
|
||||
i = ^str
|
||||
fin
|
||||
i++
|
||||
loop
|
||||
//
|
||||
// Strip leading zeros from sig
|
||||
//
|
||||
while decrec.sig > 1 and decrec.sig.1 == '0'
|
||||
decrec.sig--
|
||||
if decrec:exp < 0
|
||||
decrec:exp--
|
||||
fin
|
||||
memcpy(@decrec.sig.1, @decrec.sig.2, decrec.sig)
|
||||
loop
|
||||
//
|
||||
// Check for zero
|
||||
//
|
||||
if !decrec.sig
|
||||
decrec.sig = 1
|
||||
decrec.sig.1 = '0'
|
||||
fin
|
||||
return sane:fpOp2(FFEXT|FOD2B, ext, @decrec)
|
||||
end
|
||||
//
|
||||
// Convert extended FP to string using , return string
|
||||
//
|
||||
export def ext2str(ext, str, numdigits, expformat)
|
||||
byte d, i, sigdigits
|
||||
word dp, tens
|
||||
byte decform[t_decformat]
|
||||
byte decrec[t_decrecord]
|
||||
|
||||
decform:style = 0
|
||||
decform:digits = numdigits
|
||||
sane:fpOp3(FFEXT|FOB2D, @decrec, ext, @decform)
|
||||
^(str+1) = decrec.sgn ?? '-' :: ' '
|
||||
if decrec.sig.1 == 'I'
|
||||
^(str+2) = 'I'
|
||||
^(str+3) = 'n'
|
||||
^(str+4) = 'f'
|
||||
^str = 4
|
||||
return str
|
||||
fin
|
||||
if decrec.sig.1 == 'N'
|
||||
^(str+2) = 'N'
|
||||
^(str+3) = 'a'
|
||||
^(str+4) = 'N'
|
||||
^str = 4
|
||||
return str
|
||||
fin
|
||||
if decrec.sig.1 == '0'
|
||||
decrec:exp = -decrec.sig
|
||||
fin
|
||||
dp = decrec.sig + decrec:exp
|
||||
sigdigits = decrec.sig
|
||||
if decrec:exp < 0
|
||||
//
|
||||
// Strip off trailing fractional zeros
|
||||
//
|
||||
while sigdigits > dp and decrec.sig[sigdigits] == '0'
|
||||
sigdigits--
|
||||
loop
|
||||
fin
|
||||
if (decrec:exp + (decrec.sig - sigdigits)) < -numdigits or decrec:exp > 0 or expformat
|
||||
//
|
||||
// Convert to exponential format
|
||||
//
|
||||
^(str+2) = decrec.sig.1
|
||||
^(str+3) = '.'
|
||||
i = 3
|
||||
for d = 2 to decrec.sig
|
||||
i++
|
||||
^(str+i) = decrec.sig[d]
|
||||
next
|
||||
//
|
||||
// Copy over all significant digits
|
||||
//
|
||||
if ^(str+i) == '.'; i--; fin
|
||||
i++
|
||||
^(str+i) = 'E'
|
||||
i++
|
||||
dp--
|
||||
if dp < 0
|
||||
^(str+i) = '-'
|
||||
dp = -dp
|
||||
else
|
||||
^(str+i) = '+'
|
||||
if dp == 0
|
||||
i++
|
||||
^(str+i) = '0'
|
||||
fin
|
||||
fin
|
||||
//
|
||||
// Pretty output the exponent (preceding zero for values less than 10)
|
||||
d = 0
|
||||
tens = 10000
|
||||
while dp
|
||||
d = d or tens <= 10
|
||||
if dp >= tens or d
|
||||
d = 1
|
||||
i++
|
||||
^(str+i) = (dp / tens) + '0'
|
||||
fin
|
||||
dp = dp % tens
|
||||
tens = tens / 10
|
||||
if !tens; break; fin
|
||||
loop
|
||||
else
|
||||
//
|
||||
// Convert as floating point
|
||||
//
|
||||
i = 1
|
||||
if dp <= 0
|
||||
*(str+2) = '0'|('.'<<8)
|
||||
i = 3
|
||||
while dp < 0
|
||||
dp++
|
||||
i++
|
||||
^(str+i) = '0'
|
||||
loop
|
||||
fin
|
||||
for d = 1 to sigdigits
|
||||
i++
|
||||
^(str+i) = decrec.sig[d]
|
||||
if d == dp
|
||||
i++
|
||||
^(str+i) = '.'
|
||||
fin
|
||||
next
|
||||
if ^(str+i) == '.'; i--; fin
|
||||
fin
|
||||
^str = i
|
||||
return str
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user