I will assume the IEEE 754 single-precision representation of float
and 32-bit width for int
and unsigned
as indicated in the question.
<代码>int 范围[-2^31;2^31-1]。
<代码>float上的标识基本上为24倍比值,乘以2^-23(即23个位置改为正确)。 如果在最多30个地点向左边转移,则这在31个轨道之内。 因此,如果票价最多为30,则该数值将并入<条码>int。 然而,有一个情况是,票价为31,也符合:如果价值为-2^31,即标值为31,票价为31,而红利为0。
在进行转换时,必须在进行借方转换之前进行这些检查,以避免。 此外,必须检查的是,如果要转移红土,或者由于转移负值的行为不明确,就应当转移红土。
因此,可以实施:
int toInt(unsigned f)
{
int signBit = (f >> 31) & 1;
int exponent = (f >> 23) & 0xFF;
int mantissa = f & 0x7FFFFF;
exponent = exponent - 127;
int result = 0;
if(exponent >= 0)
{
if(exponent <= 30)
{ // The result is within range
int mantissa1 = mantissa | (1u << 23);
if(exponent <= 23) // Need to shift right
result = mantissa1 >> (23-exponent);
else // Need to shift left
result = mantissa1 << (exponent-23);
if(signBit) result = -result;
}
else
{ // Probably out of range, but check for -2^31
if(exponent == 31 && signBit && mantissa == 0)
result = -(1u<<31);
else
printf("Error: out of range");
}
}
// else the absolute value is less than 1, so the result is 0
return result;
}
Note: calling this function requires passing the bit pattern of a float as an unsigned. This can be done as follows:
#include <math.h>
#include <string.h>
int main()
{
float x = -pow(2.0, 31);
unsigned xBits;
memcpy(&xBits, &x, 4);
printf("%d, %d", (int)x, toInt(xBits));
return 0;
}
必须指出,<代码>(int)x>将未界定的行为,条件是x
不适用于<<>>。 <toInt(
>>,对于x
的任何价值,不得有任何未界定的行为。 然而,当然,toInt(
>在很大程度上取决于实施界定的行为,例如float
的表述。