mac*_*aca 2 c floating-point integer type-conversion
我对以下代码的输出感到困惑:
float a = 1.32;
int* b;
b= &a;
printf("%d", *b);
Run Code Online (Sandbox Code Playgroud)
这段代码将float转换为int,但我得到的输出是:1068037571
这与计算机的IEEE 754转换功能有关吗?谢谢!
Dav*_*nan 10
您的程序调用未定义的行为.你只是重新解释了float作为一个的表示int.你绝对不会将inta 转换为a float.你不能指望任何特定的行为.
要将float转换为int,您将使用如下代码:
int b = a;
Run Code Online (Sandbox Code Playgroud)
截断float到一个int.
您正在使用代码执行的操作是查看浮点数的存储方式.浮点占用内存中的4个字节(通常),如下所示(来自维基百科的例子):

运行代码时,假装这些位是四字节整数:
float a = 1.32;
int* b;
b= &a;
printf("%d", *b);
Run Code Online (Sandbox Code Playgroud)
如果你想看到十六进制表示,那就做
printf("%08x", *b);
Run Code Online (Sandbox Code Playgroud)
你会得到的
3f9d70a4
Run Code Online (Sandbox Code Playgroud)
意思是位模式是
00111111100111010111000010100100
Run Code Online (Sandbox Code Playgroud)
打破它:
0 01111111 00111010111000010100100
Run Code Online (Sandbox Code Playgroud)
符号位0
指数01111111
分数(1)00111010111000010100100
你会发现那个二进制数
100111010111000010100100 = 10317988
Run Code Online (Sandbox Code Playgroud)
然后
10317988.0 / (4096.0*2048.0) = 1.23
Run Code Online (Sandbox Code Playgroud)
更新完整程序,准确显示如何执行此操作:
#include <stdio.h>
#include <math.h>
#include <stdint.h>
int main(void) {
float a = 1.23;
uint32_t *b = (uint32_t *)&a;
uint32_t signbit;
uint32_t exponent;
uint32_t mantissa;
uint32_t fpAsInt;
fpAsInt = *b;
signbit = (fpAsInt & 0x80000000) >> 31;
exponent = (fpAsInt & 0x7F800000) >> 23 ;
mantissa = (fpAsInt & 0x007FFFFF) | 0x00800000;
printf("fpAsInt: 0x%08x\n", fpAsInt);
printf("sign bit: %d\n", signbit);
printf("exponent: 0x%02x\n", exponent);
printf("mantissa: 0x%03x\n", mantissa);
printf("the value is %10f\n", ((signbit == 1)?-1.0:1.0)*mantissa / pow(2.0, (127 - exponent + 23)));
printf("the original value was %10f\n", a);
}
Run Code Online (Sandbox Code Playgroud)
打印结果
fpAsInt: 0x3f9d70a4
sign bit: 0
exponent: 0x7f
mantissa: 0x9d70a4
the value is 1.2300000191
the original value is 1.2300000191
Run Code Online (Sandbox Code Playgroud)
我在最后一行使用浮点数学似乎是作弊 - 有效的批评,但这里的重点是展示如何构造浮点,而不是如何使用整数数学来提取值.
注 - 我假设浮点数是IEEE 4字节表示.此外,我包括一些特定的转换来摆脱编译器警告.只有当你确定你知道自己在做什么时才这样做......
一个编辑
有人指出代码仍然存在未定义的行为.为了解决这个问题,并且仍然让您对上述内容有所了解,让我们再来一次.现在我使用一个位数组和一个浮点数的联合来"合法地"访问不同的元素 - 并且在编译时没有得到警告-Wall -pedantic.这可能还不够,但我知道这是最好的...
#include <stdio.h>
#include <math.h>
#include <stdint.h>
union ieee754_float
{
float f;
/* This is the IEEE 754 single-precision format on a little-endian machine. */
struct
{
unsigned int mantissa:23;
unsigned int exponent:8;
unsigned int negative:1;
} ieee;
};
int main(void) {
float a = 1.23;
union ieee754_float *pa;
pa = (union ieee754_float*)&a;
uint32_t signbit;
uint32_t exponent;
uint32_t mantissa;
signbit = pa->ieee.negative;
exponent = pa->ieee.exponent;
mantissa = pa->ieee.mantissa | 0x00800000;
printf("sign bit: %d\n", signbit);
printf("exponent: 0x%02x\n", exponent);
printf("mantissa: 0x%03x\n", mantissa);
printf("the value is %.10f\n", ((signbit == 1)?-1.0:1.0)*mantissa / pow(2.0, (127 - exponent + 23)));
printf("the original value is %.10f\n", a);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2214 次 |
| 最近记录: |