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.
This commit is contained in:
George Koehler 2016-11-05 17:00:24 -04:00
parent 5c62ec2d8f
commit 3bb41d3910

View file

@ -7,13 +7,15 @@
#ifndef __FLT_INCLUDED__ #ifndef __FLT_INCLUDED__
#define __FLT_INCLUDED__ #define __FLT_INCLUDED__
#include <stdint.h>
#ifndef arith #ifndef arith
#define arith long #define arith long
#endif #endif
struct flt_mantissa { struct flt_mantissa {
long flt_h_32; /* high order 32 bits of mantissa */ uint32_t flt_h_32; /* high order 32 bits of mantissa */
long flt_l_32; /* low order 32 bits of mantissa */ uint32_t flt_l_32; /* low order 32 bits of mantissa */
}; };
typedef struct flt_arith { typedef struct flt_arith {