mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
e35cfd4971
Unfortunately a few routines (minf, maxf, clampf) remain unchanged, because removing the 'f' would make them clash with a builtin function. floats.rndf -> floats.rnd floats.parse_f -> floats.parse floats.rndseedf -> floats.rndseed floats.print_f -> floats.print floats.str_f -> floats.tostr
140 lines
3.4 KiB
Lua
140 lines
3.4 KiB
Lua
%import floats
|
|
%import textio
|
|
%import string
|
|
%zeropage basicsafe
|
|
|
|
main {
|
|
|
|
; float parsing prototype (remember, there's no official kernal VAL_1 routine to do this yet...)
|
|
|
|
sub start() {
|
|
f("")
|
|
f("0")
|
|
f("-0")
|
|
f(".0")
|
|
f("-.0")
|
|
f("0.0")
|
|
f("0.1")
|
|
f("+1.1")
|
|
f("-1.1")
|
|
f("-.1")
|
|
f("-.9")
|
|
f("-99.9")
|
|
f("99.9")
|
|
f("123456789.888888")
|
|
f("123.456789123456")
|
|
f("-123.")
|
|
f("-123.456789123456")
|
|
f("123.45e20")
|
|
f("+123.45e+20")
|
|
f("123.45e-20")
|
|
f("123.45e20")
|
|
f("-123.45e+20")
|
|
f("-123.45e-20")
|
|
f(" - 1 23. 45e - 36 ")
|
|
f(" - 1 23. 4Z 5e - 20 ")
|
|
f(" - 1 23!. 4Z 5e - 20 ")
|
|
f("1.7014118345e+38") ; TODO fix overflow error
|
|
f("-1.7014118345e+38") ; TODO fix overflow error
|
|
}
|
|
|
|
sub f(str string) {
|
|
cbm.SETTIM(0,0,0)
|
|
repeat 100
|
|
float value1 = floats.parse(string)
|
|
txt.print("1=")
|
|
txt.print_uw(cbm.RDTIM16())
|
|
txt.spc()
|
|
|
|
cbm.SETTIM(0,0,0)
|
|
repeat 100
|
|
float value2 = parse(string)
|
|
txt.print("2=")
|
|
txt.print_uw(cbm.RDTIM16())
|
|
txt.nl()
|
|
|
|
floats.print(value1)
|
|
txt.spc()
|
|
txt.spc()
|
|
floats.print(value2)
|
|
txt.nl()
|
|
}
|
|
|
|
sub parse(uword stringptr) -> float {
|
|
if @(stringptr)==0
|
|
return 0.0
|
|
|
|
float result
|
|
byte exponent
|
|
bool negative
|
|
|
|
repeat {
|
|
cx16.r0L = @(stringptr)
|
|
when cx16.r0L {
|
|
0 -> goto done
|
|
'-' -> negative=true
|
|
'+', ' ' -> { /* skip */ }
|
|
else -> {
|
|
if string.isdigit(cx16.r0L) {
|
|
result *= 10
|
|
result += cx16.r0L - '0'
|
|
} else
|
|
break
|
|
}
|
|
}
|
|
stringptr++
|
|
}
|
|
|
|
if cx16.r0L=='.' {
|
|
; read decimals
|
|
repeat {
|
|
stringptr++
|
|
cx16.r0L = @(stringptr)
|
|
if cx16.r0L==' '
|
|
continue
|
|
else if string.isdigit(cx16.r0L) {
|
|
exponent--
|
|
result *= 10
|
|
result += cx16.r0L - '0'
|
|
} else
|
|
break
|
|
}
|
|
}
|
|
|
|
if cx16.r0L=='e' or cx16.r0L=='E' {
|
|
; read exponent
|
|
bool neg_exponent
|
|
byte exp_value
|
|
repeat {
|
|
stringptr++
|
|
cx16.r0L = @(stringptr)
|
|
when cx16.r0L {
|
|
0 -> break
|
|
'+', ' ' -> { /* skip */ }
|
|
'-' -> neg_exponent=true
|
|
else -> {
|
|
if string.isdigit(cx16.r0L) {
|
|
exp_value *= 10
|
|
exp_value += cx16.r0L - '0'
|
|
} else
|
|
break
|
|
}
|
|
}
|
|
}
|
|
if neg_exponent
|
|
exponent -= exp_value
|
|
else
|
|
exponent += exp_value
|
|
}
|
|
|
|
done:
|
|
if exponent
|
|
result *= floats.pow(10, exponent)
|
|
|
|
if negative
|
|
result = -result
|
|
|
|
return floats.normalize(result)
|
|
}
|
|
}
|