为什么ghci说1.1 + 1.1 + 1.1> 3.3是真的吗? [英] Why does ghci say that 1.1 + 1.1 + 1.1 > 3.3 is True?

查看:143
本文介绍了为什么ghci说1.1 + 1.1 + 1.1> 3.3是真的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近经历了一个Haskell教程,并且在交互式 ghci shell中尝试一些简单的Haskell表达式时注意到了这种行为:

  Prelude> 1.1 + 1.1 == 2.2 
True
Prelude> 1.1 + 1.1 + 1.1 == 3.3
False
Prelude> 1.1 + 1.1 + 1.1> 3.3
True
Prelude> 1.1 + 1.1 + 1.1
3.3000000000000003

有人知道为什么吗?

解决方案

因为 1.1 3.3 浮点数。十进制小数(例如.1或.3)在二进制浮点数中不能完全表示。 .1意味着1/10。要用二进制表示,其中每个小数位代表1/2(n,n)(1/2,1 / 4,1 / 8等),则需要无限个数字0.000110011 .. 。无限重复。

这与代表基数为10的1/3完全相同。在基数10中,您需要无限数量的数字, .33333 ...永远,完全代表1/3。所以在10号基础上工作,你通常会围绕像.33这样的东西。但是,如果您将这三个副本相加,您会得到.99,而不是1。



有关该主题的更多信息,请阅读每位计算机科学家应该知道的有关浮点算术的知识

为了更精确地在Haskell中表示有理数,你总是可以使用有理数据类型, 比率 ;再加上bignums(任意大整数,Haskell中的 Integer ,与 Int 是固定大小)相反,对于分子和分母而言,您可以表示任意精确的有理数,但速度明显低于浮点数,这些数字是在硬件中实现的,并针对速度进行了优化。

浮动点数对于科学和数值计算来说是一种优化,它将高精度折衷考虑在内,只要您知道舍入及其对计算的影响,就可以在很短的时间内执行大量计算。

I've been going through a Haskell tutorial recently and noticed this behaviour when trying some simple Haskell expressions in the interactive ghci shell:

Prelude> 1.1 + 1.1 == 2.2
True
Prelude> 1.1 + 1.1 + 1.1 == 3.3
False
Prelude> 1.1 + 1.1 + 1.1 > 3.3
True
Prelude> 1.1 + 1.1 + 1.1
3.3000000000000003

Does anybody know why that is?

解决方案

Because 1.1 and 3.3 are floating point numbers. Decimal fractions, such as .1 or .3, are not exactly representable in a binary floating point number. .1 means 1/10. To represent that in binary, where each fractional digit represents 1/2n (1/2, 1/4, 1/8, etc), you would need an infinite number of digits, 0.000110011... repeating infinitely.

This is exactly the same problem as representing, say, 1/3 in base 10. In base 10, you would need an infinite number of digits, .33333... forever, to represent 1/3 exactly. So working in base 10, you usually round, to something like .33. But if you add up three copies of that, you get .99, not 1.

For far more information on the topic, read What Every Computer Scientist Should Know About Floating Point Arithmetic.

For representing rational numbers more precisely in Haskell, you can always use the rational data type, Ratio; coupled with bignums (arbitrarily large integers, Integer in Haskell, as opposed to Int which are fixed size) as the type for numerator and denominator, you can represent arbitrarily precise rational numbers, but at a significantly slower speed than floating point numbers, which are implemented in hardware and optimized for speed.

Floating point numbers are an optimization, for scientific and numerical computation, that trade off precision for high speed, allowing you to perform a very large number of computations in a small time, as long as you are aware of rounding and how it affects your computations.

这篇关于为什么ghci说1.1 + 1.1 + 1.1> 3.3是真的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆