diff -paur -N --exclude='*.rej' --exclude='*.orig' --exclude='*svn*' --exclude='*~' --exclude='*#*' 5-kill-unsigned_conversion_warning/gcc/dfp.c 6-decimal-float/gcc/dfp.c --- 5-kill-unsigned_conversion_warning/gcc/dfp.c 2006-09-18 12:33:52.000000000 +0100 +++ 6-decimal-float/gcc/dfp.c 2006-11-20 00:40:14.000000000 +0000 @@ -714,3 +714,20 @@ decimal_real_maxval (REAL_VALUE_TYPE *r, if (sign) r->sig[0] |= 0x80000000; } + +/* Set R to its normalized version. */ + +void +decimal_normalize (REAL_VALUE_TYPE *r) +{ + decNumber dn, dn2; + decContext set; + + decContextDefault (&set, DEC_INIT_DECIMAL128); + set.traps = 0; + set.round = DEC_ROUND_DOWN; + decimal128ToNumber ((decimal128 *)r->sig, &dn2); + decNumberNormalize (&dn, &dn2, &set); + decimal_from_decnumber (r, &dn, &set); +} + diff -paur -N --exclude='*.rej' --exclude='*.orig' --exclude='*svn*' --exclude='*~' --exclude='*#*' 5-kill-unsigned_conversion_warning/gcc/dfp.h 6-decimal-float/gcc/dfp.h --- 5-kill-unsigned_conversion_warning/gcc/dfp.h 2006-09-18 12:33:52.000000000 +0100 +++ 6-decimal-float/gcc/dfp.h 2006-11-20 00:32:40.000000000 +0000 @@ -44,4 +44,6 @@ void decimal_real_maxval (REAL_VALUE_TYP void decimal_real_to_integer2 (HOST_WIDE_INT *, HOST_WIDE_INT *, const REAL_VALUE_TYPE *); HOST_WIDE_INT decimal_real_to_integer (const REAL_VALUE_TYPE *); +void decimal_normalize (REAL_VALUE_TYPE *); + #endif /* GCC_DFP_H */ diff -paur -N --exclude='*.rej' --exclude='*.orig' --exclude='*svn*' --exclude='*~' --exclude='*#*' 5-kill-unsigned_conversion_warning/gcc/real.c 6-decimal-float/gcc/real.c --- 5-kill-unsigned_conversion_warning/gcc/real.c 2006-11-18 14:41:17.000000000 +0000 +++ 6-decimal-float/gcc/real.c 2006-11-20 19:50:55.000000000 +0000 @@ -482,7 +482,10 @@ normalize (REAL_VALUE_TYPE *r) int i, j; if (r->decimal) - return; + { + decimal_normalize (r); + return; + } /* Find the first word that is nonzero. */ for (i = SIGSZ - 1; i >= 0; i--) @@ -2505,6 +2508,10 @@ exact_real_truncate (enum machine_mode m /* After conversion to the new mode, the value must be identical. */ real_convert (&t, mode, a); + + if (a->decimal != t.decimal) + return !decimal_do_compare (&t, a, -1); + return real_identical (&t, a); } @@ -4977,5 +4984,18 @@ real_isinteger (const REAL_VALUE_TYPE *c REAL_VALUE_TYPE cint; real_trunc (&cint, mode, c); + + /* Trailing zeroes are significant in decimal float values so they + are not kept normalized. Normalize before comparing against the + truncated value. */ + if (c->decimal) + { + REAL_VALUE_TYPE cnorm; + cnorm = *c; + decimal_normalize (&cnorm); + return real_identical (&cnorm, &cint); + } + return real_identical (c, &cint); } +