float fla = -1000;
unsigned int *pfla = (unsigned int*)&fla;
printf("fla=%X
",*pfla);
#include<stdio.h>
int main(int argc,char *argv[])
{
float f=8.25f;
int *i = (int*)&f;
printf("%d
",*i);
return 0;
}
浮点数的操作,尤其是大小比较,是比较棘手的,需要计算机组成原理的相关知识,恰恰我又没学过这门课,只能边干边学。
根据IEEE 754规定,浮点数有自己的保存格式,其中,最高位是符号位,这一点是规定好的。1为负,0为正
上面的代码可以将浮点数在内存中的保存以十六进制显示出来,
通过这个网站的对比,https://www.h-schmidt.net/FloatConverter/IEEE754.html,代码运行正确。
-1000十六进制就是0xc47a0000,最高位就是负的。
以下是知乎转载,
作者:匿名用户
链接:https://www.zhihu.com/question/21711083/answer/376836065
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
计算机再进行数的表达时,没有直接对正负、小数点的表达方式,人类设计了多种计数编码方式的,但最著名、应用最广泛的便是IEEE754标准。
计算机在存储一个数的时候,采用的是多个不同位置的二进制数代表不同的意义,如单精度浮点数和双精度浮点数,单精度浮点数和双精度浮点数的本质区别是计数范围不同。
我们举例为单精度浮点数,设这串二进制数为a[31:0],最高位a[31]代表的是符号位,a[23:30]位代表的是阶码也称偏移码(象征着小数点在数据中的位置),a[22,0]代表尾数(象征着拿掉小数点之后的不含小数点的数)。注意:象征不意味着相等,在实际的二进制中我们叫做:符号位真值、阶码真值、尾数真值。
我们在编码空间(计算机实际处理时)要对符号位、阶码、尾数进行操作,但在实际中我们认知的称为符号位真值、阶码真值、尾数真值。编码空间是真值的映射。
符号位=符号位真值
阶码=阶码真值+127
尾数=尾数真值-1
所以,一般在计算机里将二进制数这样表达:
我们从这个公式中可以分析出,阶码真值控制着小数点的位置,阶码每加1,整个数值增大2倍,小数点则向右移1位;阶码每减1,整个数值减小2倍,小数点则向左移动1位。
单精度浮点数
因为阶码真值有符号数,计算机无法表示有符号数,通常要引入符号位,但IEEE754则有另一种编码方式,因为阶码是8位宽,可以表达2^8=256个数,我们至多可以表达出-127~+127共计255个数,我们从阶码的0000-0000开始对应-127~+127共计255个数,所以就有了:阶码=阶码真值+127。
我们在计算初始要进行编码规范化,除明晰符号位、阶码值、补码值外,我们还要对小数点进行初始化,为了最大范围地表达出我们的数,所以我们默认该数的小数点在1后,即尾数的最高位a[22]必须是1,在规范化的过程中,小数点右移阶码要减1,小数点左移阶码要加1。
关于浮点数,需要再说几句:
-
在二进制,第一个有效数字必定是“1”,因此这个“1”并不会存储。
-
浮点数不能精确表示其范围内的所有数。
-
可精确表示的数不是均匀分布的,越靠近0越稠密。
-
默认舍入方式为向偶舍入,也被称为最接近的值舍入。
-
不遵守普遍的算数属性,比如结合律。