如何解决如何理解将大浮点数添加到小双数的结果?
当我编写一些C代码时:
connectionTimeout
结果f + d仍将是f值本身,我检查了CSAPP书,它说,因为表达式f + d将四舍五入为1.0e20,但我不知道为什么将其四舍五入。浮点类型值的范围远大于1.0e20,不是吗?
有人可以帮助我了解这种机制吗?
解决方法
浮标…
规模无关紧要。有效位数中使用的位数很重要。
数字的浮点表示形式为± d 。 ddd … ddd • b e ,其中 b 是固定基数, e 是缩放数字的指数,而 d 。 ddd ... ddd 是基数 b 中的固定位数的数字。
在float
常用的格式中, b 为2, d 。 ddd … ddd 有24位数字(这些位是数字,因为数字在2开头)。
此格式不能表示1e20,因为它是+ 1.0101101011110001110101111000101101011000110001•2 66 ,具有51位。当您在源代码中编写float f = 1.0e20;
时,f
通常以值+ 1.0101101011110001110110••2 66 结尾,该值已四舍五入为24位。 (十进制为100000002004087734272。)
使用实数算法向其添加一个时,结果将为+ 1.01011010111100011101100000000000000000000000000000000000000000000000000•2 66 ,该位数又太多了。因此结果是四舍五入的。在float
中,将产生+ 1.01011010111100011101100•2 66 ,该值与f
开头的值相同。但是,您使用了f + d
,后者使用了double
,因此f
也被转换为double
,并且double
算法用于乘法。但是,即使在double
中,+ 1.010110101111111000111011000000000000000000000000000000000000000000001•2 66 的位数也太多。 double
常用的格式在 d 。 ddd ... ddd 部分中有53位。因此也将其四舍五入为+ 1.01011010111100011101100000000000000000000000000000000•2 66 ,该值与+ 1.01011010111111100011101100•2 66 相同。
问题不是浮点类型的标度(范围),而是精度-即它们可以表示的有效十进制数字的数量。不保证单精度resource.type="k8s_container"
resource.labels.cluster_name="gke-label"
-->labels."k8s-pod/stackdriver"="look_here_for_me"
可以表示超过6个有效十进制数字,并且不保证label
可以表示超过10个有效十进制数字。 float
是
double
行超过6或10个有效数字。
这里有一个小程序可以证明这一点:
1.0e20 + 1.0
及其输出:
100000000000000000001.0
如您所见,一旦我们开始超过8位数字,#include <stdio.h>
int main( void )
{
float f = 1.0f;
for ( size_t i = 0; i < 11; i++ )
{
printf( "i == %2zu,(1.0e%02zu) %15.2f + 1.0 == %15.2f\n",i,f,f + 1.0f );
f *= 10;
}
return 0;
}
就开始丢失-该类型不能代表那么多有效的十进制数字。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。