回答
浮点数学并不完美。 What every programmer should know关于它。
浮点运算被许多人认为是一个深奥的主题。这是相当令人惊讶的,因为浮点在计算机系统中无处不在。几乎每种语言都有一个浮点数据类型;从PC到超级计算机的计算机都有浮点加速器;大多数编译器会被要求不时地编译浮点算法;几乎每个操作系统都必须响应浮点异常,例如溢出。本文提供了一个关于浮点的方面的教程,这些方面对计算机系统的设计者有直接的影响。它从浮点表示和舍入错误的背景开始,继续讨论IEEE浮点标准,并结合大量计算机构建者如何更好地支持浮点的例子。
...
挤压无穷多的实数为有限位数需要一个近似表示。虽然有无限多的整数,但在大多数程序中,整数计算的结果可以存储在32位中。相反,给定任意固定的位数,大多数使用实数的计算都会产生无法使用多位来精确表示的数量。因此,浮点计算的结果必须经过四舍五入以适应其有限表示。该舍入误差是浮点计算的特征。
的确,浮点运算既无处不在,也很复杂,但这并不能回答这个问题(除非您链接到一个有答案的80页的论文)。 – 2010-03-11 02:00:45
@亨利 - 重点在于链接文章的标题。 **每个**程序员都应该知道这一点,如果他们不这样做,他们应该阅读文章。 (好吧,也许不是所有的80页...) – 2010-03-11 02:16:36
+1:链接到一个80页的文件,有答案的地方是标准anwser。这个问题 - 以某种形式 - 被频繁地询问。本文是*答案。问题都是重复的。我们不需要一再重复这些信息。 – 2010-03-11 02:25:56
双精度不准确,所以在内部33.46639实际存储为33.466389
编辑:正如理查德说,它的浮点数据(以二进制存储在一个有限的位集合),所以它不完全是) ...
或33.4668885或其他“足够接近”,取决于硬件。 – DaveE 2010-03-11 01:57:19
嗯,以上都不是。它的基数为2.大多数这样的数字不能完全以10为底数表示(不管怎样,无需使用无限重复的数字序列,类似于基数10中的1/3必须表示为0.33333 [inf]。) – 2010-03-11 02:02:37
,不完全是......但比原来的更接近那个。 – 2010-03-11 02:06:11
你有不同的结果的原因是,您使用的“投”
(int)(33.46639 * 1000000) returns 33466389 ^^^^^
的结果转换为一个类型的“廉政”的事实......这无论是围捕或向下整数类型时,一起倍增,然后转换为'int'....不要依靠浮点足够准确.... Skeet张贴在他的网站上的优秀介绍here和here ...
演员阵容本身没有任何损失。存在任意精度库。 – 2010-03-11 01:57:59
我想象他在问:“我的结果中有8个来自哪里?”乘以1000000就像将小数点6位移到右边,应该是“33466390”,但这不是他所得到的。你的答案是我最初想的,直到我再次读到这个问题。 – Pwninstein 2010-03-11 01:59:48
@Richard - 将'float'或'double'强制转换为'int'会丢弃小数部分,所以您确实会丢失信息。 – Seth 2010-03-11 02:32:50
如果你问它为什么没有变成33466390
,这是因为double
s没有无限精度,而且数字不能用二进制精确表示。
如果更换double
与decimal
((int)(33.46639m * 1000000)
),它等于33466390
,因为decimal
s的在碱计算10.
其原因是33.46639将被表示为一些比该数量稍少。
乘以1000000会给你33466389.99999999。
使用(int)进行类型转换将仅返回整数部分(33466389)。
如果您想要“正确”的数字,请在类型转换之前尝试round()。
哇! .....不不,不,不。如果你想要“正确的”答案,你不能使用浮点运算。 – 2010-03-11 02:08:40
不可以。如果你想要“正确”的答案,你不能使用*二进制*浮点运算。使用使用十进制浮点运算的“decimal”类型,它将按照您的预期工作。 – Gabe 2010-03-11 02:13:58
33.46639是“正确的”答案。问题是提问者没有提出正确的问题。 – 2010-03-11 02:21:54
因为33.46639不能准确地表示有限数量的二进制数字。 33.46639 * 1000000的实际结果是33466389.9999999962747097015380859375。演员将它截断为33466389.
尝试“不能准确表达在有限数量的小数二进制数字” – 2010-03-11 07:15:42
这是1994年底的除夕夜。英特尔首席执行官安迪格罗夫(Andy Grove)出现了一个伟大的一年,奔腾处理器出现并受到重创。于是,他走进一家酒吧,点了一瓶Johnnie Walker绿色标签。
酒保送达并说,“那将是20美元,先生。”
格罗夫在柜台上放了一张二十美元的钞票,看了一会儿,说道:“保持变化。”
但是...这是一个整数... – Rawling 2014-06-11 08:37:00
- 1. 为什么INT返回0 - C++
- 2. 为什么aspect要返回int类型?
- 3. 为什么string :: compare返回一个int?
- 4. 为什么+“1”返回一个int?
- 5. 为什么将Double转换为Int不会在Swift中返回可选的Int?
- 6. 为什么编译器假定malloc返回一个int?
- 7. 为什么python statistics.mean()返回一个int类型,而不是float
- 8. 为什么func1的返回类型是Unit,而func2是Int?
- 9. 为什么getActualTypeArguments返回Object而不是Integer for Option [Int]?
- 10. Math.Round/Floor/Ceiling为什么不返回long或int?
- 11. 为什么我的方法不返回一个int?
- 12. 为什么从双重函数返回变成int?
- 13. 为什么math.Ceiling(double a)不能直接返回int?
- 14. 为什么从int转换/转换返回星号
- 15. 为什么math.Pow10(e int)返回float64而不是int64?
- 16. 为什么添加两条短裤会返回一个int?
- 17. C++ - 为什么我可以返回一个int类的月
- 18. “const int&”做什么作为返回类型?
- 19. 为什么(INT)@ “ - 1” 的floatValue]不返回-1
- 20. 当参数字符串为空时,int compareTo()会返回什么?
- 21. 为什么PHP返回的字符串,而不是INT
- 22. 为什么C#Math.Floor()返回的双重不是int
- 23. Intel SSE:为什么`_mm_extract_ps`返回'int`而不是`float`?
- 24. CStringArray :: GetAt(int index)返回一个常量。为什么?
- 25. 为什么printf在C中返回int而不是size_t
- 26. 为什么==返回true?
- 27. getPerson()返回NULL,为什么?
- 28. 为什么scipy.sparse.linalg.svds返回ValueError?
- 29. 为什么DLookup返回空?
- 30. 为什么NSDateFormatter返回nil?
你期望发生的? – SLaks 2010-03-11 01:54:26
@Slaks:3346639,又名,正确的答案。 – 2010-03-11 01:56:04
开始的好地方:http://docs.sun.com/source/806-3568/ncg_goldberg.html(每个计算机科学家应该了解浮点运算) – mjv 2010-03-11 01:57:04