From 3bb41d391038f56b74bd5e34a820d31a4dbd658f Mon Sep 17 00:00:00 2001 From: George Koehler Date: Sat, 5 Nov 2016 17:00:24 -0400 Subject: [PATCH] Switch flt_mantissa fields from long to uint32_t. This seems to fix an error when flt_arith converts a literal double-precision float to IEEE format. For example, 0.5 and 0.75 got converted to slightly below their correct values. My host gcc for amd64 has 64-bit long, but flt_arith needs only 32 bits. The code (at least flt_add.c) can make 32-bit overflows. Such overflows would set the higher bits of a 64-bit long, which might cause problems later. I need to use uint32_t and not int32_t because the code still uses long, and the sign extension from int32_t to long would cause problems. The mantissa represents a value in [0, 2) that can't be negative, so unsigned type is better. Also, signed overflow is undefined behavior in C, so flt_add.c better make overflows with uint32_t and not int32_t. This commit doesn't touch lang/cem/libcc.ansi/stdlib/ext_fmt.h which continues to use unsigned long for its mantissa fields. --- modules/src/flt_arith/flt_arith.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/src/flt_arith/flt_arith.h b/modules/src/flt_arith/flt_arith.h index 964c19580..9a21e5135 100644 --- a/modules/src/flt_arith/flt_arith.h +++ b/modules/src/flt_arith/flt_arith.h @@ -7,13 +7,15 @@ #ifndef __FLT_INCLUDED__ #define __FLT_INCLUDED__ +#include + #ifndef arith #define arith long #endif struct flt_mantissa { - long flt_h_32; /* high order 32 bits of mantissa */ - long flt_l_32; /* low order 32 bits of mantissa */ + uint32_t flt_h_32; /* high order 32 bits of mantissa */ + uint32_t flt_l_32; /* low order 32 bits of mantissa */ }; typedef struct flt_arith {