From 3122ac66bec23236937e98283a4d7d9df1ddfb5e Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Fri, 11 May 2007 02:19:36 +0000 Subject: [PATCH] Fix #107: Float input "1.000000" hit an edge case in the code that caused the rounding increment at the end of float conversion to wrap the mantissa from all 1's to 0, resulting in an incorrect result. svn path=/trunk/yasm/; revision=1836 --- libyasm/floatnum.c | 7 +++++-- libyasm/tests/floatnum_test.c | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/libyasm/floatnum.c b/libyasm/floatnum.c index ac343528..cb0435fe 100644 --- a/libyasm/floatnum.c +++ b/libyasm/floatnum.c @@ -482,8 +482,11 @@ yasm_floatnum_create(const char *str) } } - /* Round the result. (Don't round underflow or overflow). */ - if ((flt->exponent != EXP_INF) && (flt->exponent != EXP_ZERO)) + /* Round the result. (Don't round underflow or overflow). Also don't + * increment if this would cause the mantissa to wrap. + */ + if ((flt->exponent != EXP_INF) && (flt->exponent != EXP_ZERO) && + !BitVector_is_full(flt->mantissa)) BitVector_increment(flt->mantissa); return flt; diff --git a/libyasm/tests/floatnum_test.c b/libyasm/tests/floatnum_test.c index 45f951df..907aac98 100644 --- a/libyasm/tests/floatnum_test.c +++ b/libyasm/tests/floatnum_test.c @@ -95,6 +95,19 @@ static Init_Entry normalized_vals[] = { 0, {0x00,0x00,0x00,0x00,0x00,0xf4,0xb6,0xc0}, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0xb7,0x0b,0xc0} }, + /* Edge cases for rounding wrap. */ + { "1.00000", + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},0x7ffe,0,0, + 0, {0x00,0x00,0x80,0x3f}, + 0, {0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x3f}, + 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0x3f} + }, + { "1.000000", + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},0x7ffe,0,0, + 0, {0x00,0x00,0x80,0x3f}, + 0, {0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x3f}, + 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0x3f} + }, }; /* Still normalized values, but edge cases of various sizes, testing underflow/ @@ -417,7 +430,8 @@ runtest_(const char *testname, int (*testfunc)(void), void (*setup)(void), printf("%c", nf>0 ? 'F':'.'); fflush(stdout); if (nf > 0) - sprintf(failed, "%s ** F: %s failed!\n", failed, testname); + sprintf(failed, "%s ** F: %s failed: %s!\n", failed, testname, + result_msg); return nf; } #define runtest(x,y,z) runtest_(#x,test_##x,y,z) -- 2.40.0