任何人都可以解释这种古怪:
Dim result as single = 0
result = CType("8.01", Single) * 100 ' result=801.0 as expected
result = CType("8.02", Single) * 100 ' result=802.000061 --- not expected
继上述
之后result = 8.02 * 100 ' result = 802.0 as expected
答案 0 :(得分:2)
Single
(或float
)只有七位有效数字,所以除此之外可能打印的所有内容都是虚假的。这是浮点运算的正常工件。您只能依靠小数点后最多4位数字(因为三位有效数字已经在小数点之前)。
进一步详细说明,数字8.01和8.02不能用二进制存储精确表示(因为0.01和0.02都不能用1/2 n 形式的分数之和精确表示)。详细信息可能因数量而异,但在使用此类数字时,可能会看到正常精度范围之外的无关数字。
这并不影响801和802 可以完全表示的事实,但在这种情况下你没有确切的数字。
ETA:事实上,您直接包含计算时所看到的就是:编译器将为您计算计算结果并将802
写入程序。您可以使用Reflector来验证。此外,源代码中的浮点文字默认情况下可能为Double
,因此您可以从这里开始获得更高的精度。如果result
为Single
,则会将其下载到Single
,并且小数点后第16位的错误会被丢弃,因为它不适合Single
反正。
答案 1 :(得分:1)
这是由于浮点数在内存中的表示方式有限。请阅读wikipedia page以获取完整的下限 - 这不是错误,也不是特定于.net的内容。
编辑:这两篇文章也值得一看(后者是重数学)。答案 2 :(得分:0)
如果您需要比较浮点值,请参见此处:Comparing floating point values
答案 3 :(得分:0)
Single
和Double
表示为浮点数,遗憾的是存储这些数字并不准确。使用“单个”和“双重”数字时,您会遇到小的差异。
然而,还有另一种选择--.NET具有Decimal
类型,在处理这些数字方面要好得多。它仍然不完美(参见http://www.yoda.arachsys.com/csharp/decimal.html - 特别是最后一段),但在表示金钱等方面会更好。