问题
My impression is that C float has 8 bits of exponent and 23 bits of mantissa.
So one is 0011 1111 1000 0000 0000 0000 0000 0000 = 0x3F800000.
However, the following code produced 1.06535e+09 instead of 1. Can anyone help me understand why?
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
float i = 0x3F800000;
cout<<i << endl;
return 0;
}
回答1:
How is 1 coded in C as a float?
Can anyone help me understand why (code fails)?
float i = 0x3F800000;
is the same as i = 1065353216
;
In C, to overlay the bit pattern use a union
or use memcpy()
.
In C++, suggest memcpy()
.
Using a cast risks failure due to anti-aliasing. @Eric Postpischil
#include <stdio.h>
#include <stdint.h>
_Static_assert(sizeof(float) == sizeof(uint32_t), "Unexpected types");
int main(void) {
union {
uint32_t u;
float f;
} x = {.u = 0x3f800000};
float f = x.f;
printf("%e\n", f);
return 0;
}
On less common systems, this can fail due to
float
is not binary32.Endian differs between
float/uint32
回答2:
Using IEEE-754, the floating point number 1 is written as:
0 01111111 00000000000000000000000 (base-2) = 3f80 0000 (base-16)
So, your assumption is correct. Unfortunately, the bit-pattern represented by 0x3f800000
cannot be assigned to a float by just doing:
float a = 0x3f800000
The hexadecimal number will first be converted to an unsigned integer which has the value 1065353216
in base-10. This number will then implicitly be converted to the nearest floating-point number.
So in short, while your bit-pattern for an IEEE-754 floating point number is correct, your assumption how to assign this pattern is incorrect. Have a look at Convert a hexadecimal to a float and viceversa in C how this can be achieved or the other answers in this question.
来源:https://stackoverflow.com/questions/56710780/how-is-1-encoded-in-c-c-as-a-float-assuming-ieee-754-single-precision-represe