floatdisf.c revision 256281
1/* Public domain. */ 2typedef int DItype __attribute__ ((mode (DI))); 3typedef unsigned int UDItype __attribute__ ((mode (DI))); 4typedef int SItype __attribute__ ((mode (SI))); 5typedef unsigned int USItype __attribute__ ((mode (SI))); 6typedef float SFtype __attribute__ ((mode (SF))); 7typedef float DFtype __attribute__ ((mode (DF))); 8 9SFtype __floatdisf (DItype); 10 11SFtype 12__floatdisf (DItype u) 13{ 14 /* Protect against double-rounding error. 15 Represent any low-order bits, that might be truncated by a bit that 16 won't be lost. The bit can go in anywhere below the rounding position 17 of SFtype. A fixed mask and bit position handles all usual 18 configurations. */ 19 if (53 < (sizeof (DItype) * 8) 20 && 53 > ((sizeof (DItype) * 8) - 53 + 24)) 21 { 22 if (!(- ((DItype) 1 << 53) < u 23 && u < ((DItype) 1 << 53))) 24 { 25 if ((UDItype) u & (((UDItype) 1 << (sizeof (DItype) * 8 - 53)) - 1)) 26 { 27 u &= ~ (((UDItype) 1 << (sizeof (DItype) * 8 - 53)) - 1); 28 u |= (UDItype) 1 << (sizeof (DItype) * 8 - 53); 29 } 30 } 31 } 32 /* Do the calculation in a wider type so that we don't lose any of 33 the precision of the high word while multiplying it. */ 34 DFtype f = (SItype) (u >> (sizeof (SItype) * 8)); 35 f *= 0x1p32f; 36 f += (USItype) u; 37 return (SFtype) f; 38} 39