首页 > 编程知识 正文

定点数和浮点数举例,c语言打印浮点数

时间:2023-05-03 13:47:20 阅读:26744 作者:3929

我们在评价CPU的性能时,经常有浮点运算作为概念。 我经常思考浮点运算是什么样的,是否需要将其作为评价CPU性能的重点。 要弄清楚这个问题,首先谈谈浮点数和固定分数。 首先看一个例子,在javascript中运行console.log(0.1 ) 0.2 ),然后查看其输出,可以看到0.1 ) 0.20.3! 为什么会这样呢? 这完全违反常识!

显示计算机中的数字

计算机通过内存存储数据。 1个字节是8位,最多可以表示256个数据。 表示数字时,1字节可用于表示0-255。 您可以直接用CPU表示最多32位整数进行计算,如32位计算机,如果超过32位,则可以分步计算。 但是,尽管如此,还是出现了一些问题。 引入非整数后,我们发现很多数字不能完全表示所有,整数之间有无限的数。 此外,还有无理数。 圆周率、2等也无法准确表示,所以在计算机中用近似的方法表示。

计算机中的所有信息都用二进制表示。 例如,字符“a”用ASCII代码表示二进制文件为01000001。 整数10,用二进制表示为00001010。 那么,如果是小数,例如0.2,用二进制数怎么表示呢? 在十进制0.1=1/10和二进制0.1b=1/2中,十进制0.2用二进制表示,表示尾数循环,即:

(0.2 ) 10=) 0.00110011001100110011001100110011 ) 2

言归正传,对于这些不能用固定位表示的数,只能用近似的方法表示,所以会出现开头那样的问题。 现在,让我们更详细地分析一下计算机的浮点数是如何表示的。 现代计算机浮点数的表示符合IEEE754标准,包括单精度和双精度浮点数,分别占32位和64位。 浮点数的记忆包括三个部分。 第一部分为符号,第一部分为指数位,单精度为8bit,双精度为11bit,第三部分为底数,单精度为23bit,双精度为52bit。 其中符号位1采用负,0采用正,指数位采用阶梯符号的形式。

像0.75那样单精度地存储:

(0.75 ) 10=(0.75 )2=) 1.1*2-1)2=(00111010000000000000 )2=0x3f400000=1061158912

验证一下:

#包含

类型定义单元{

int a;

浮点b;

}数据;

int main () )

{

数据d;

d.a=1061158912;

printf (转换器% x (n ),d.a );

printf (转换浮点% f (n ),d.b );

返回0;

}

使用gcc编译并运行时,打印结果为以下:

转换为hex 3f 400000

转换为浮动0.750000

浮点数在计算中用科学的计数法来表示。 其中需要注意的是,在底数中,一位数始终为1,因此在编码中不言而喻,第二点是单精度浮点数的符号是指数加上127形成的,在处理时需要注意。

浮点数运算

浮点运算是衡量CPU性能的重要指标,那么CPU如何对浮点数进行浮点运算呢? 我们已经知道浮点数在CPU中是以指数的形式表示的。 以加法为例,如何运算浮点数呢? 正如两个数a=1.23*103和b=4.25*108一样,我们有比较快速的方法。

a=1.23*103

b=425000*103

a b=42501.23*103

对计算机来说,这种方法特别简单,将指数移动到相同位置可以方便地对两个浮点数进行加减运算。 浮点数加减运算一般分为:0操作数的检查,比较阶码的大小完成对阶,加减尾数,将其结果归一化舍入。 具体流程建议看这篇文章。

因此,浮点运算可能在两个位置失去精度。 第一种是十进制转换二进制数,由于浮点数长度的限制,尾数可能会被舍弃。 第二,在浮点运算的对层时,可能会对尾数进行移位操作,失去部分精度。 第三种是将尾数相加后保存,也有可能舍弃某一位。 那么,0.1 0.2是哪里出了问题,让我们来恢复现场吧。

首先,对于0.1和0.2,求出各自二进制表现形式:

(0.1 ) 10=(0.0001100110011001100110011…)2=1.100110011001101 *2-4(偶数优先舍入原则1 ) ) ) )。

(0.2 ) 10=) 0.0011001100110011001100110…)2=1.100110011001101 *2-3(偶数优先舍入原则1 ) )。

指数差1,对小的数字a进行合并,尾数上加上:

a=0.11001100110011001100110 *2-3(偶数优先舍入原则-1) ) ) ) ) ) ) )。

b=1.10011001100110011001100110011001101 *2- 3

a=10.01100110011001100110011001100110011 *-3

a b=1.00110

011001100110011010*-2 (偶数优先舍入原则1 ) ) )。

此时,a b以二进制表示时为0-01111101-00110011001100110011010,以十六进制表示时为0x3e99999a,转换为十进制时为0.30000001192092896000。

但是这里有问题。 分别用javascript、python和c语言进行测试时,我们发现在javascript和python环境中为0.1(0.2为0.30000000000004 ),c语言与上述结果相同。 我想请高手指出这是为什么。

参考资料

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。