TEL:服务热线

400-006-2918

产品中心

新闻动态

【青岛德瑞鑫净化工程面试真经】(程序开发岗)C++ float转double会有精度损失吗?

  • 浏览次数: ...
  • 发布时间: 2023-09-01

float精度能保证6位有效,double保证15位有效。

一般认为float转double是不会丢失精度的,但是实际情况会丢失,如下代码所示

 

$ cat main.c
#include <stdio.h>
int main(void) {
printf("%.100g\n%.100g\n%.100g\n%.100g\n", 25.0 * 3.14159, 25.0 * 3.14159f, 3.14159, 3.14159f);
return 0;
}
 
$ gcc main.c
$ ./a.out
78.539749999999997953636921010911464691162109375
78.539752960205078125
3.14158999999999988261834005243144929409027099609375
3.141590118408203125
 

出现这种结果的原因:让一个float或double精确的表示0.1或者任何其他负数次方值是不可能的(十进制系统中不能准确的表示出1/3,同样二进制系统也不能准确的表示1/10)。

 

1.十进制整数转为二进制数:

例子:11表示成二进制数:

11/2 =5 余1

5/2 = 2 余1

2/2 = 1 余0

1/2 = 0 余1

0结束,11二进制表示为(从下往上):1011

注意:只要遇到除以后的结果为0就结束了。所有的整数除以2一定能够最终得到0,但是小数就不能,小数转变为二进制的算法就有可能会无限循环下去。

 

2.十进制小数转为二进制数

算法是乘以2知道没有了小数为止,例子:

0.9表示成二进制数:

0.9*2 = 1.8 取整数部分:1

0.8*2 = 1.6 取整数部分:1

0.6*2 = 1.2 取整数:1

0.2*2 = 0.4 取整数:0

0.4*2 = 0.8 取整数:0

0.8*2 = 1.6 取整数:1

 

0.9二进制表示为(从上往下):1100100100100.......

注意:上面的计算过程循环了,也就是说乘以2永远不能消灭小数部分,这样算法将无限下去。显然,小数的二进制表示有时是不能精确的。道理很简单,十进制系统中不能准确的表示出1/3,同样二进制也无法准确的表示1/10。这也是浮点型出现精度丢失问题的主要原因。

 

解决方案一:

如果不介意记录十进制的小数点,而且数值不大,那么可以使用long,int等基本类型,

int resultInt = 10 -9;

double result  = (double)resultInt / 100;//自己控制小数点

 

解决方案二:

使用BigDecimal,而且需要在构造参数使用String类型.

float和double只能用来做科学计算或者工程计算,在商业计算等精确计算中,要用java.math.BigDecimal。

本文网址: https://www.deruixin.com.cn/news/133.html
找不到任何内容

首页        |        产品中心        |        新闻资讯        |        关于我们        |        在线留言        |        联系我们

Copyright @ 2022 青岛德瑞鑫净化工程有限公司 . All rights reserved.