On Fri, 31 May 2019, Tejas Joshi wrote: > +/* Return true if integer part of R is even, else return false. */ > + > +bool > +is_even (REAL_VALUE_TYPE *r) > +{ > + if (REAL_EXP (r) <= 0) > + return false;
But the integer part (truncation towards 0) of something in the interval (-1, 1) is of course even. > + else if (REAL_EXP (r) < SIGNIFICAND_BITS) > + { > + unsigned int n = SIGNIFICAND_BITS - REAL_EXP (r); > + int w = n / HOST_BITS_PER_LONG; > + > + unsigned long num = ((unsigned long)1 << (n % HOST_BITS_PER_LONG)); > + > + if ((r->sig[w] & num) == 0) > + return true; > + } > + return false; > +} Suppose REAL_EXP (r) == SIGNIFICAND_BITS. Then you still need to check the low bit in that case. Suppose REAL_EXP (r) > SIGNIFICAND_BITS. Then the number is definitely even, so you should return true, not false. The comment on this function needs to define what it does for infinity / NaN, and you should make sure it behaves accordingly. (If it should never be called for them, a gcc_assert would be appropriate.) What does this function do for zero? It should, of course, return that it is even. > +/* Return true if R is halfway between two integers, else return false. */ Again, define what this does for infinity / NaN and make sure it behaves accordingly. > +bool > +is_halfway_below (const REAL_VALUE_TYPE *r) > +{ > + if (REAL_EXP (r) < 0) > + return false; > + > + if (REAL_EXP (r) == 0) > + { > + unsigned long temp = ((unsigned long)1 << 63); unsigned long might be 32-bit; you can't assume it's 64-bit. You may mean (HOST_BITS_PER_LONG - 1) instead of 63. > + if (((r->sig[SIGSZ-1] & temp) != 0) && ((r->sig[SIGSZ-1] & (temp-1)) == > 0)) > + return true; > + else > + return false; This appears only to be checking the high word, not lower bits. > + else if (REAL_EXP (r) < SIGNIFICAND_BITS) > + { > + unsigned int n = SIGNIFICAND_BITS - REAL_EXP (r); > + int i, w = n / HOST_BITS_PER_LONG; So n is the bit position, and w is the word position, of the bit with value 1; n-1 is the position of the bit with value 0.5. > + for (i = 0; i < w; ++i) > + { > + if (r->sig[i] != 0) > + return false; > + } If n is a multiple of HOST_BITS_PER_LONG (that is, the bits with values 0.5 and 1 are in different words), this will incorrectly return false when the 0.5 bit is set. > + unsigned long num = ((unsigned long)1 << ((n - 1) % HOST_BITS_PER_LONG)); > + > + if (((r->sig[w] & num) != 0) && ((r->sig[w] & (num-1)) == 0)) > + return true; And this also needs updating to handle the case where 0.5 and 1 are in different words correctly; currently it's checking bits that are all one word too high. It's possible that for both issues, you want w to be the word with the 0.5 bit, not the word with the 1 bit. For all the above, please add appropriate tests in the testsuite (for example, where 0.5 and 1 are in different words and the above would have produced incorrect results). -- Joseph S. Myers jos...@codesourcery.com