微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C#浮点数运算符

如何解决C#浮点数运算符

下面的代码在0.01、0.02、0.03,...,0.99上运行模数0.01

var testVals = Enumerable.Range(1,99).Select(n => double.Parse("0." + n.ToString("D2")));
var moduloTest = testVals.Select(v => v % 0.01).ToList();

(注意:从字符串中解析双精度是有意的,这样对浮点数进行的唯一数学运算就是模数)

我希望这里的moduleTest列表包含几个非常接近0的浮点值。但是,列表中的许多值却非常接近0.1。

我了解到浮点数学并不精确,并引入了舍入误差,但此处的0.1甚至不接近0。

解决方法

当我键入此内容时,我意识到了答案。确实由于浮动不精确而发生。只是对于模运算,与大多数数学运算不同,该值的较小不精确会导致结果产生较大差异。

例如,

0.03在浮点中最紧密地表示为0.2999999999999999999,如果您要对它进行模量0.01,则会得到一个像0.0999999999999的数字

,

我了解到浮点数学并不是精确的,但在许多情况下,它似乎还差得远。

这里的模量并没有增加错误/不准确度,只是使先前的不精确性产生的影响非常明显。


通过模数的质量实现,不会出现不精确性。参见Is fmod() exact when y is an integer?

问题在于假设数学的十进制值(例如0.01)始终接近于转换为最接近的可表示浮点数的那些值。有限的浮点值都是精确的。正是形成其值的运算才是“错误”的来源-模数等例外。

以十六进制或足够的十进制精度(例如17个重要小数位)打印值通常足以显示预期的0.01不会被编码为浮点数为0.01,而是接近值 。还要对计算结果执行此操作,以获得更深入的了解。

模运算的性质是一条sawtooth曲线,类似于绿线here

鉴于0.01转换和/(不是模数)产生的误差,OP值模数的结果恰好在不连续的任一侧 :大约为0.0或接近0.01。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。