python理解浮点数运算的误差_浅谈浮点数运算的误差

本文通过测试程序展示了浮点数运算时产生的舍入误差,详细分析了在Linux和Windows环境下decimal类型的运算误差及其原因,揭示了不同环境下舍入规则对误差的影响,并通过调试过程展示了误差积累的过程。
摘要由CSDN通过智能技术生成

测试程序

我们知道,浮点数运算存在舍入误差。在某些特殊的情况下,舍入误差还可以累计到非常大的地步。让我们来看一下测试程序吧:

1 usingSystem;2

3 static classDecimalSumTester4 {5 static void Main(string[] args)6 {7 try

8 {9 var n = (args.Length > 0) ? int.Parse(args[0]) : 10;10 for (var i = 0; i < 3; i++) Console.WriteLine(F(n, i));11 }12 catch(Exception ex) { Console.WriteLine(ex.Message); }13 }14

15 static decimal F(int n, intk)16 {17 var z = 0.1m + k *1000000000000000000000000000m;18 var w = decimal.Round(z) / 2;19 while (n-- > 0) z += z / 2 -w;20 return z - w * 2;21 }22 }

在这个程序中:

第 19 行通过 while 循环不断进行累加: z += z / 2 - w; 。w是不变的,而 z 是通过不断累加而增大的。

第 9 行读取命令行参数作为 n 的值来决定 while 循环次数。

第 15 至 21 行的 F 方法第一个参数 n 就是循环次数。第二个参数 k 决定累加初值的整数部分的大小。

在这个程序中参数 k 仅取 0、1 和 2 三种情况。如果算术运算没有误差的话,这三种情况下 F 方法的返回值应该一样。

在 Linux 中编译和运行

在 Arch Linux 64-bit 操作系统的 Mono 3.0.4 环境下编译和运行:

work$ dmcs DecimalSumTester.cs

work$ mono DecimalSumTester.exe 24

1683.4112196028232574462890625

2730.9

2730.9

上述结果中第一行是计算出来的准确值。第二行和第三行的值理论上应该等于第一行。但是由于浮点数运算的舍入误差累计的结果,最终答案的误差相当大。在我的上一篇随笔“浅谈 System.Decimal 结构”中提到,decimal 的算术运算在 Linux 环境下的舍入规则是四舍五入,这可能导致误差累计得比较大。而在 Windows 环境下的舍入规则是四舍六入五向偶。那么我们就接着往下看吧。

在 Windows 中编译和运行

在 Windows 7 SP1 32-bit 操作系统的 Microsoft .NET Framework 4.5 环境下编译和运行:

D:\work> csc DecimalSumTester.cs

Microsoft(R) Visual C# 编译器版本 4.0.30319.17929

用于 Microsoft(R) .NET Framework 4.5

版权所有 (C) Microsoft Corporation。保留所有权利。

D:\work> DecimalSumTester 24

1683.4112196028232574462890625

2097.9

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值