如何处理浮点数精度计算计算中的超精度

他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)C语言浮点数运算的精度问题
我的图书馆
C语言浮点数运算的精度问题
代码无法准确表示某些带小数位的十进制数据。
整数部分:连续用该整数除以2,取余数,然后商再除以2,直到商等于0为止。然后把得到的各个余数按相反的顺序排列。简称"除2取余法"。
小数部分:十进制小数转换为二进制小数,采用"乘2取整,顺序排列"法。用2乘以十进制小数,将得到的整数部分取出,再用2乘余下的小数部分,然后再将积的整数部分取出,如此进行,直到积中的小数部分为0或者达到所要求的精度为止。然后把取出的整数部分按顺序排列起来,即先取出的整数部分作为二进制小数的高位,后取出的整数部分作为低位有效位。简称"乘2取整法"。
含有小数的十进制数转换成二进制,整数、小数部分分别进行转换,然后相加。
转换为二进制数值,步骤如下:
及0.6转换为二进制代码:
这段二进制数值。
类型,下面我们来看看float类型是否能存储上面转换出的二进制代码。
(电气和电子工程师协会)754浮点存储格式标准来存储的。
单精度浮点格式共32位,包含三个构成字段:23位小数f,8位偏置指数e,1位符号s。将这些字段连续存放在一个32位字里,并对其进行编码。其中0:22位包含23位的小数f; 23:30位包含8位指数e;第31位包含符号s。如下图所示:
及0.5转换出的二进制代码,我们只能存储23位,即使数据类型为double,也只能存储52位,这样大家便能看出问题出现的原因了。
及0.5,根据这个二进制代码肯定无法正确得到结果0.05。
浮点型变量分为单精度(float型)、双精度(double型)、长双精度(long double型)3类,单精度浮点型小数点后面有效数字为6~7位和双精度浮点型小数点后面有效数字为15~16位如下面这个例子scanf("%f", &a);printf("%f\n", a);&输入:1.输出:1.&& //小数点后面6位才是精确值&
**********************************************
TA的最新馆藏[转]&[转]&
喜欢该文的人也喜欢当我们保存浮点数后再读取浮点数,结果可能会出现一点点偏差。
float ft1 = 20.2;(这样编译器会报警告,因为小点数默认为double)
str.Format(_T("%f"),ft1);
这时候ft1的值等于20.200001。
float ft2 = 20.8;
str.Format(_T("%f"),ft2);
这时候ft1的值等于20.799999。
解决方法1:
将float改用double存储:
double dt1 = 20.2;
解决方法2:
使用%g格式化,除去0后的有效位数。
float ft1 = 20.2;
str.Format(_T("%g"),ft1);
这时候ft1的值等于20.2。但是没法再用0对齐了,嘿嘿嘿嘿。。。。。。
解决方法3:
使用%0.4格式化
float ft1 = 20.2;
str.Format(_T("%0.4f"),ft1);
这时候ft1的值等于20.2000。
还有些比较复杂的,比如说计算过程中出现了精度损失。
我们通过简单的代码试验一下:
int newWidth, newH
GetThumbnailSize(200, 200, 100, 100, out newWidth, out newHeight);
Console.WriteLine("{0}, {1}", newWidth, newHeight);
GetThumbnailSize(300, 300, 100, 100, out newWidth, out newHeight);
Console.WriteLine("{0}, {1}", newWidth, newHeight);
得到的结果是:
第一个结果自然没有问题,但是在第二个结果中为什么是99而不是100?为此,我们再通过以下的代码来观察一番:
ratio: 0.3333
new value: 99.99
to int: 99
可见,虽然使用了decimal,精度已经非常高的,但是在经过了一除一乘,它还是没有恢复到最精确值。虽然一直说要注意浮点数计算时的精度问题,但是对于这个问题许多朋友往往只是理解到&不能直接两个浮点数相等&,包括我自己的第一印象。但事实上,从上面的结果也可以看出,把一个浮点数直接转换成整形,它便是使用了&去尾&而不是&四舍五入&的方法。因此,虽然newValue的值无比接近100,但是在强制去尾后它还是变成了99。
如果要在原来的方法中改变这个问题,最简单的方法可能是把最后的强制转型替换成Math.Round方法。Math.Round方法使用四舍五入,应该能够解决问题。不过如果只是这样的话收获不大,我们再仔细想想,应该如何做到尽可能的精确。
两个浮点数相除可能会丧失精度,但如果是乘法操作,在一般情况下精度是不会丢失的,除非发生了溢出的话,或者小数位数太多。因此在计算过程中为了保持精度,我们应该尽可能的做乘法,而不是作除法。例如以下的判断:
if ((decimal)desiredWidth / originalWidth & (decimal)desiredHeight / originalHeight)
其实最好改写成&等价&的乘法操作。
阅读(...) 评论()他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)

我要回帖

更多关于 双精度浮点数计算 的文章

 

随机推荐