❶ c语言浮点运算感觉很奇怪同样的数,算出来结果却不一样,这是怎么回事
计算机存储和运算都是以二进制处理的,而表达式是十进制的,那么存储或运算时是要转换成二进制,计算完成后输出还要再转换成十进制。
那么你应该明白二进制每一位权重都是2^N,此处N为位号,位号分布如下:
...3,2,1,0(小数点) -1,-2,-3...
权重分布如下:
...2^3,2^2,2^1,2^0 (.小数点)2^-1,2^-2,2^-3
例如一个二进制的1.111(B)=1.875(D)
整数部分:1的位号为0,因此1*2^0=1*1=1
小数点向右第一个1:位号为-1,因此1*2^-1=1*1/2=0.5
小数点向右第二个1:位号为-2,因此1*2^-2=1*1/4=0.25
小数点向右第三个1:位号为-3,因此1*2^-3=1*1/4=0.125
合起来1+0.5+0.25+0.125=1.875,其他位依此类推。
无需想得太多,你可以明显看到,二进制小数表达的数都是不同级别减半后的累加。与十进制的某些小数没有一一对应,显然转换必然会发生误差。
另一方面,存储时CPU会对十进制小数会进行编码,float的尾数长度为23位,阶码8位,符号占1位,共32位。double是64位,无论如何精度都是有限的,因此也会存在误差,1.1*100时编译器会将表达式先转换二进制并运算运算,运算后再编码存储到变量中或临时变量中,而运算是由CPU直接处理的,因此你可以看到有个0.000002的误差数,而printf是个函数,对误差进行了修正。
PS:简单了解下浮点数的编码方式网页链接
❷ 关于c语言
浮点数在内存里怎么可能是这样存放的。。。。
参考IEEE的浮点数标准。
IEEE制定的浮点数格式
鉴于有人问到在 C 语言中 float 和 double 型态的储存格式的问题, 所以我就在这边献丑一翻, 讲讲我所了解的部份, 如
有任何错误, 请各位大哥多多指教...
IEEE 制定之浮点数格式说明:
float 型态: 用 4 个 bytes 储存, 也就是 32 bits.
各个 bit 的用途如下:
bit 31 23~30 0~22
┌———┬————┬———————┐
│正负号│ 指数 │ 底数 │
└———┴————┴———————┘
double 型态: 用 8 个 bytes 储存, 也就是 64 bits.
各个 bit 的用途如下:
bit 63 52~62 0~51
┌———┬————┬———————┐
│正负号│ 指数 │ 底数 │
└———┴————┴———————┘
< 说明 > 正负号 (sign): 1 为负, 0 为正.
指数 (exponential): 将底数乘上 2 的指数次方后就是原来的数.
须注意的是: float 时, 因有 8 bits, 所以能表示的有 2 的
256 次方, 但因为指数应可正可负, 所以 IEEE 规定, 此处算
出的次方须减去 127 才是真的指数,所以 float 的指数可从
-126 到 128.
同理, double 型态有 11 bits, 算出的值须减去 1023, 所以
相关帖子>>>:备下(0字)sinos[5次]2008-7-23 10:12:57IEEE 浮点数格式[详解](5336字)zzwj5120[23次]2008-7-21 22:03:57IEEE 浮点数格式
IEEE 754 标准规定了三种浮点数格式:单精度、双精度、扩展精度。《编程卓越之道》第一部的 4.2 节对这些浮点数格式已
进行了详细的讲解,为了让读书笔记更像读书笔记,本文只道出个人的一些理解以及一些疑惑之处。
IEEE 浮点数标准的由来
话说 Intel 计划给最早的 8086 增加浮点运算单元 (FPU) 时,他们请来了最好的数值分析专家来为 8087 FPU 设计浮点数格
式,这位专家接着又请来了该领域的另外两位专家,这三个人 (Kahn, coonan 与 Stone) 设计了 Intel 的浮点格式,即
KCS 浮点数标准。这个标准实在太出色了,因此 IEEE 组织将 KCS 选作为 IEEE 浮点数格式的基础,即 IEEE 标准 754。
单精度浮点数
IEEE 754 标准所定义的单精度浮点数的长度为 32 位,按位域可划分为:符号位、阶码位与尾数位,如下:
31----------------------22---------------------------------------------------------0
| | |
X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X
| |-------------------| |----------------------------------------------------------|
符号 阶码 尾数符号位取 0 表示正数,取 1 表示负数。
阶码位是 8 位,这里有一点小门道需要注意,那就是的指数 n 并不能直接当作阶码来处理,需要将其与 127 (0x7f) 相加才
可得到 的阶码表示。
尾数的位域长度在图示中是 23 位,但实际上却是 24 位,这个位是“不可见”的,其值固定为 1,这也就是说 IEEE 754 标
准所定义的浮点数,其有效数字是介于 1 与 2 之间的小数。
可以尝试写一下 1.0 这个数的二进制单精度浮点格式,这有助于更好地理解单精度浮点数格式的位域分布。
1.0 的二进制单精度浮点格式:0 0111 1111 000 0000 0000 0000 0000 0000值得注意的一个问题是:书上说之所以要将指数
加上 127 来得到阶码,是为了简化浮点数的比较运算,这一点我没有体会出来。但是通过 127 这个偏移量 (移码),可以区
分出指数的正负。阶码为 127 时表示指数为 0;阶码小于 127 时表示负指数;阶码大于 127 时表示正指数。
第二个值得思考的问题是:使用 24 位尾数,大概可以得到 个十进制数字的精度,其中的“半个”数字由 FPU 的好意而产
生的一个随机数字,这个数字通常接近 5 (四舍五入?)。
第三个问题是我经常要碰到的:IEEE 754 标准所定义的单精度浮点数所表示的数的范围是多少?书上给出的答案是大约为
或者大约 。这个比较好理解,因为尾数的最大值是接近 2,而指数的范围是 [-127, 127],那么这个范围就可以表示为。
双精度浮点数
相对于单精度浮点数格式,双精度的阶码变为 11 位,移码变为为 1,023,尾数变为 53 位 (包含那个固定为 1 的隐含位)。
这样,再加上符号位,双精度浮点数的长度为 64 位,提供了大约 的动态范围以及 个数字的精度。
扩展精度浮点数
为了追求更高的浮点运算精度,Intel 又搞出来扩展精度格式。扩展精度的浮点数长度为 80 个位,相对于双精度浮点数所多
出来的 16 个位,有 12 位加入到尾数位中,有 4 位加入到阶码位中。
据说 Intel IA32 架构的的 FPU都是采用扩展精度浮点数进行运算的。当程序调入单、双精度浮点数时,FPU 将它们转为扩展
精度,运算结束后再将结果转成 (四舍五入) 对应的单、双精度浮点数。
❸ c语言浮点数中的计算问题
浮点数的实现依赖于具体的环境,不同的环境可以有不同的实现特征。
devc的
我没有怎么学习浮点数的实现,只能经验地说这些了
;还有为方便调试,“%d”可以换成“%f”,那样编译器才知道你想要输出浮点数
❹ c语言浮点型运算错误
给定的输入数据式样中间有逗号分隔吗:scanf("%d,%d",&p,&q);
如果是空格分隔就要改为:scanf("%d%d",&p,&q);这样才行
❺ c语言计算有一些不准确
浮点数就是不精确的,使用浮点数计算得到的结果可能不精确。
❻ 在c语言中,为什么在一些算数运算中,使用浮点数会损失更多精度
浮点数在计算机中的储存是不准确的,然而在计算的时候,如果类型转换为整数的话,小数部分也会丢弃
❼ C语言中浮点类型变量计算误差
不会吧?你计算的数值是多少?
你输入的数值是多少啊?