mirror of
https://github.com/dschmenk/PLASMA.git
synced 2026-03-12 01:41:40 +00:00
249 lines
5.6 KiB
Plaintext
249 lines
5.6 KiB
Plaintext
//
|
|
// 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
|
|
sane:saveZP()
|
|
return sane:restoreZP(sane:op2FP(FFEXT|FOD2B, ext, @decrec))
|
|
end
|
|
//
|
|
// Convert extended FP to string using , return string
|
|
//
|
|
export def ext2str(ext, str, intdigits, fracdigits, format)
|
|
byte d, i, sigdigits, numdigits
|
|
word dp, tens
|
|
byte decform[t_decformat]
|
|
byte decrec[t_decrecord]
|
|
|
|
numdigits = intdigits + fracdigits
|
|
decform:style = format & $01
|
|
decform:digits = decform:style ?? fracdigits :: numdigits
|
|
sane:saveZP()
|
|
sane:restoreZP(sane:op3FP(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'
|
|
while decrec.sig < fracdigits
|
|
decrec.sig++
|
|
decrec.sig[decrec.sig] = '0'
|
|
loop
|
|
decrec:exp = -decrec.sig
|
|
fin
|
|
dp = decrec.sig + decrec:exp
|
|
sigdigits = decrec.sig
|
|
if decrec:exp < 0 and format & $02
|
|
//
|
|
// Strip off trailing fractional zeros
|
|
//
|
|
while sigdigits > dp and decrec.sig[sigdigits] == '0'
|
|
sigdigits--
|
|
decrec:exp++
|
|
loop
|
|
fin
|
|
if -decrec:exp > numdigits or sigdigits + decrec:exp >= (decform:style ?? intdigits :: numdigits) or format & $04
|
|
//
|
|
// Convert to exponential format
|
|
//
|
|
^(str+2) = decrec.sig.1
|
|
^(str+3) = '.'
|
|
i = 3
|
|
for d = 0 to fracdigits
|
|
i++
|
|
^(str+i) = decrec.sig.2[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
|