diff --git a/parse.c b/parse.c index 91e73bc..f4f57aa 100644 --- a/parse.c +++ b/parse.c @@ -397,12 +397,22 @@ int parse_float( /* ufrac is now >= 2**55 and < 2**56 */ - /* Round from FLT4 to FLT2 or single-word float */ + /* Round from FLT4 to FLT2 or single-word float. + * + * +--+--------+-------+ + * |15|14 7|6 0| + * +--+--------+-------+ + * | S|EEEEEEEE|MMMMMMM| + * +--+--------+-------+ + * Sign (1 bit) + * Exponent (8 bits) + * Mantissa (7 bits) + */ if (size < 4) { /* Round to nearest 8- or 24- bit approximation */ ufrac += (1UL << (56 - (8 + 16*(size-1)) - 1)); - if ((ufrac >> 56) > 0) { /* Overflow? */ + if ((ufrac >> 56) > 0) { /* Overflow? */ ufrac >>= 1; /* Normalize */ uexp--; } diff --git a/tests/RunTests b/tests/RunTests index e2edfa2..d14a063 100755 --- a/tests/RunTests +++ b/tests/RunTests @@ -14,6 +14,7 @@ TESTS="test-asciz \ test-enabl-ama \ test-enabl-lcm \ test-endm \ + test-float \ test-if \ test-impword \ test-include \ diff --git a/tests/test-float.mac b/tests/test-float.mac new file mode 100644 index 0000000..3459c0c --- /dev/null +++ b/tests/test-float.mac @@ -0,0 +1,28 @@ +;;;;; +; +; Test floating point numbers + + .word ^F 1.0 ; 040200 + .word ^F-1.0 ; 140200 + .word -^F 1.0 ; 137600 + .word -^F-1.0 ; 037600 + + .word ^F6.2 ; 040706 + .word ^C^F6.2 ; 137071 + .word ^C<^F6.2> ; 137071 + + .flt2 6.2 ; 040706 063146 + .flt4 6.2 ; 040706 063146 063146 063146 + + .flt2 1.5 ; 040300 000000 + .flt4 1.5 ; 040300 000000 000000 000000 + + .word ^F 72057594037927935 ; 056200 (rounded!) + .flt2 72057594037927935 ; 056200 000000 (rounded!) + .flt4 72057594037927935 ; 056177 177777 177777 177777 (exact!) + + .word ^F 72057594037927936 ; 056200 + .flt2 72057594037927936 ; 056200 000000 + .flt4 72057594037927936 ; 056200 000000 000000 000000 + + .flt4 72057594037927937 ; 056200 000000 000000 000001