clean up floats, floats which become infinity and zero
This commit is contained in:
parent
ee3c461e6e
commit
e43f32b932
2 changed files with 51 additions and 43 deletions
|
@ -2,4 +2,4 @@
|
||||||
char * = "How are you"" d""o""i""ng today?\n";
|
char * = "How are you"" d""o""i""ng today?\n";
|
||||||
hi
|
hi
|
||||||
_TEST _ING _1
|
_TEST _ING _1
|
||||||
50.1e100
|
5e+307
|
||||||
|
|
|
@ -283,28 +283,9 @@ function tokenize
|
||||||
:float_no_fraction
|
:float_no_fraction
|
||||||
; construct the number integer + fraction*10^pow10
|
; construct the number integer + fraction*10^pow10
|
||||||
; first, deal with the fractional part
|
; first, deal with the fractional part
|
||||||
p = powers_of_10
|
significand = fraction
|
||||||
p += pow10 < 4
|
float_multiply_by_power_of_10(&significand, &exponent, pow10)
|
||||||
full_multiply_signed(fraction, *8p, &lower, &upper)
|
|
||||||
if upper == 0 goto fmultiply_no_upper
|
|
||||||
n = leftmost_1bit(upper)
|
|
||||||
n += 1
|
|
||||||
significand = lower > n
|
|
||||||
exponent += n
|
|
||||||
n = 64 - n
|
|
||||||
significand |= upper < n
|
|
||||||
goto fmultiply_cont
|
|
||||||
:fmultiply_no_upper
|
|
||||||
significand = lower
|
|
||||||
goto fmultiply_cont
|
|
||||||
:fmultiply_cont
|
|
||||||
p += 8
|
|
||||||
exponent += *8p
|
|
||||||
|
|
||||||
putn(significand)
|
|
||||||
putc(32)
|
|
||||||
putn_signed(exponent)
|
|
||||||
putc(10)
|
|
||||||
if integer == 0 goto float_no_integer
|
if integer == 0 goto float_no_integer
|
||||||
; now deal with the integer part
|
; now deal with the integer part
|
||||||
new_exponent = leftmost_1bit(integer)
|
new_exponent = leftmost_1bit(integer)
|
||||||
|
@ -324,7 +305,9 @@ function tokenize
|
||||||
putc(32)
|
putc(32)
|
||||||
putn_signed(exponent)
|
putn_signed(exponent)
|
||||||
putc(10)
|
putc(10)
|
||||||
significand += 15 ; ensure number rounds to the nearest representable float (this is what gcc does)
|
; make number round to the nearest representable float roughly (this is what gcc does)
|
||||||
|
; this fails for 5e-100 probably because of imprecision, but mostly works
|
||||||
|
significand += 15
|
||||||
; reduce to 53-bit significand (top bit is removed to get 52)
|
; reduce to 53-bit significand (top bit is removed to get 52)
|
||||||
significand >= 5
|
significand >= 5
|
||||||
exponent += 5
|
exponent += 5
|
||||||
|
@ -333,6 +316,9 @@ function tokenize
|
||||||
b = 1 < n
|
b = 1 < n
|
||||||
significand &= ~b
|
significand &= ~b
|
||||||
data = significand
|
data = significand
|
||||||
|
|
||||||
|
if exponent <= -1023 goto float_zero ; this number is too small in magnitude to be represented as a double. it becomes 0
|
||||||
|
if exponent >= 1024 goto float_infinity ; number too big to be represented as a double.
|
||||||
exponent += 1023 ; float format
|
exponent += 1023 ; float format
|
||||||
|
|
||||||
data |= exponent < 52
|
data |= exponent < 52
|
||||||
|
@ -351,23 +337,7 @@ function tokenize
|
||||||
; e.g. 1e100
|
; e.g. 1e100
|
||||||
pow10 = strtoi(&in, 10)
|
pow10 = strtoi(&in, 10)
|
||||||
:float_have_exponent
|
:float_have_exponent
|
||||||
p = powers_of_10
|
float_multiply_by_power_of_10(&significand, &exponent, pow10)
|
||||||
p += pow10 < 4
|
|
||||||
full_multiply_signed(significand, *8p, &lower, &upper)
|
|
||||||
if upper == 0 goto fmultiply2_no_upper
|
|
||||||
n = leftmost_1bit(upper)
|
|
||||||
n += 1
|
|
||||||
significand = lower > n
|
|
||||||
exponent += n
|
|
||||||
n = 64 - n
|
|
||||||
significand |= upper < n
|
|
||||||
goto fmultiply2_cont
|
|
||||||
:fmultiply2_no_upper
|
|
||||||
significand = lower
|
|
||||||
goto fmultiply2_cont
|
|
||||||
:fmultiply2_cont
|
|
||||||
p += 8
|
|
||||||
exponent += *8p
|
|
||||||
goto float_have_significand_and_exponent
|
goto float_have_significand_and_exponent
|
||||||
:float_exponent_plus
|
:float_exponent_plus
|
||||||
; e.g. 1e+100
|
; e.g. 1e+100
|
||||||
|
@ -381,8 +351,11 @@ function tokenize
|
||||||
pow10 = 0 - pow10
|
pow10 = 0 - pow10
|
||||||
goto float_have_exponent
|
goto float_have_exponent
|
||||||
:float_zero
|
:float_zero
|
||||||
data = 0
|
data = 0
|
||||||
goto float_have_data
|
goto float_have_data
|
||||||
|
:float_infinity
|
||||||
|
data = 0x7ff0000000000000 ; double infinity
|
||||||
|
goto float_have_data
|
||||||
:tokenize_loop_end
|
:tokenize_loop_end
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
@ -416,7 +389,42 @@ function tokenize
|
||||||
:str_bad_float
|
:str_bad_float
|
||||||
string Bad floating-point number.
|
string Bad floating-point number.
|
||||||
byte 0
|
byte 0
|
||||||
|
|
||||||
|
function float_multiply_by_power_of_10
|
||||||
|
argument p_significand
|
||||||
|
argument p_exponent
|
||||||
|
argument pow10
|
||||||
|
local significand
|
||||||
|
local exponent
|
||||||
|
local p
|
||||||
|
local lower
|
||||||
|
local upper
|
||||||
|
local n
|
||||||
|
significand = *8p_significand
|
||||||
|
exponent = *8p_exponent
|
||||||
|
|
||||||
|
p = powers_of_10
|
||||||
|
p += pow10 < 4
|
||||||
|
full_multiply_signed(significand, *8p, &lower, &upper)
|
||||||
|
if upper == 0 goto fmultiply2_no_upper
|
||||||
|
n = leftmost_1bit(upper)
|
||||||
|
n += 1
|
||||||
|
significand = lower > n
|
||||||
|
exponent += n
|
||||||
|
n = 64 - n
|
||||||
|
significand |= upper < n
|
||||||
|
goto fmultiply2_cont
|
||||||
|
:fmultiply2_no_upper
|
||||||
|
significand = lower
|
||||||
|
goto fmultiply2_cont
|
||||||
|
:fmultiply2_cont
|
||||||
|
p += 8
|
||||||
|
exponent += *8p
|
||||||
|
|
||||||
|
*8p_significand = significand
|
||||||
|
*8p_exponent = exponent
|
||||||
|
return 0
|
||||||
|
|
||||||
; return character or escaped character from *p_in, advancing accordingly
|
; return character or escaped character from *p_in, advancing accordingly
|
||||||
; returns -1 on bad character
|
; returns -1 on bad character
|
||||||
function read_c_char
|
function read_c_char
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue