C#double数据类型运算中的误差(乘以100得到的数据不准确)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#double数据类型运算中的误差(乘以100得到的数据不准确)相关的知识,希望对你有一定的参考价值。

参考技术A 我们有意思的发现:double类型的数71.1乘以100以后得到的是7109.9999999999991,并不是7110。这样的问题出现在精度要求高的场景就是个大问题了,比如跟金钱相关的应用。

这是为什么呢?其实这些数字在计算机中用二进制保存的,二进制就有精度问题,位数越多精度越高,16位比8位高,64位比32位高等,所以计算转换成十进制后可能会出现误差,出现无限小数的情况。
处理办法有:转为decimal数据类型做运算

或者用Math.Round舍为最接近的整数:

使用decimal或者Math.Round可尽量减少这种误差的出现,但是不知道是否能解决所有这样数据的误差。有时候放大100倍、1000倍、10000倍等做计算后再换算回来也可以提高精度。

c语言 不同数据类型间的混合运算

书上有个例子
“6.0/5是将5转换成float型后进行运算,值是1.2”
而自动转换里float型不是要自动转换成double型参与运算,而且是必须的转换。(即使两个float型数据相加,也要先转换成double型,然后再相加)。

高手帮忙解释下啊,万分感谢!!!
书上写着
自动转换里float型要自动转换成double型参与运算,而且是必须的转换。(即使两个float型数据相加,也要先转换成double型,然后再相加)。

书上有个例子
“6.0/5是将5转换成float型后进行运算,值是1.2”
相矛盾了啊!???

c语言里 不同数据类型间的混合运算会强制转换的``
`如6.0/5``结果必然向float型转换```
比如char short型参与运算都是先转为int型`
float转为double型
int double混合运算时转为double型
都是向着占用较大的方向转换``使适用范围也更大```

``书上应该说的比较详细了 `呵呵`
参考技术A 再回来说下,你可以这样进行检测,看隐式转换的问题还是溢出的问题:
typedef unsigned long long uint64;//最新的编译器都支持这种用法吧,总之你找个能表示64位的longlong就行了.
//uint
cout << (uint64)iu + (uint)i << endl;

这里先将i转换成uint型,此时未溢出,然后加上转换uint64(iu)的值,再将其提升为uint64,因为原来已经为uint型,所以提升为uint64时值不再改变,最后结果超出了uint的范围,如果你再对最终结果进行(uint),得到的答案你应该知道了.

------------------
溢出问题.

i=-8,转化为uint型后,为2^32-8,再加上个uint(10),结果为:
2^32+2,溢出后,结果为2.

你只考虑到一个很大的正数,却没有考虑到uint范围的问题!

以上是关于C#double数据类型运算中的误差(乘以100得到的数据不准确)的主要内容,如果未能解决你的问题,请参考以下文章

java double b = 0.333 , 乘以100 以后小数位变多;

java下double乘以100后精度丢失问题

double数据控制保留小数的几种方法

c语言 不同数据类型间的混合运算

关于java的double类型和float类型

float类型和double类型的二进制存储