.Net 和单数乘法

发布于 2024-08-11 03:47:46 字数 299 浏览 3 评论 0原文

谁能解释一下这种奇怪的现象:

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

Can anyone explain this weirdness:

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

Further to the above

result = 8.02 * 100 ' result = 802.0 as expected

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

我是男神闪亮亮 2024-08-18 03:47:46

Single(或float)只有七个有效数字,因此除此之外可能打印的所有内容都几乎是伪造的。这是浮点运算的正常现象。您的号码最多只能依赖小数点后 4 位数字(因为小数点前已经有 3 位有效数字)。

进一步详细说明,数字 8.01 和 8.02 无法使用二进制存储来精确表示(因为 0.01 和 0.02 都无法用 1/2n 形式的分数和来精确表示)。详细信息可能因数字而异,但在使用此类数字时,您可能会看到超出正常精度范围的无关数字。

这并不影响 801 和 802 可以精确表示,但在这种情况下您没有确切的数字可以开始。

预计到达时间:事实上,当您直接包含计算时,您看到的只是这样:编译器会为您计算计算结果,并将 802 写入程序中。您可以使用 Reflector 来验证这一点。另外,源代码中的浮点文字默认情况下可能是 Double ,因此您可以从这里开始获得更高的精度。如果 resultSingle ,这将被向下转换为 Single 并且小数点后第 16 位数字中的错误将被简单地丢弃,因为它可以无论如何都不适合 Single

Single (or float) only has seven significant digits, so everything that might be printed beyond those is pretty much bogus anyway. This is a normal artifact of floating-point arithmetic. You can only rely on up to 4 digits after the decimal point with your number (as three significant digits are already before the decimal point).

Further elaborated, the numbers 8.01 and 8.02 can't be represented exactly using binary storage (as neither 0.01 nor 0.02 can be represented exactly with sums of fractions of the form 1/2n). The details may vary from number to number but you may see extraneous digits outside the normal precision range when using such numbers.

This doesn't affect the fact that 801 and 802 can be represented exactly but you have no exact number to start with in this case.

ETA: In fact, what you see when you include the calculation directly is just this: The compiler will evaluate the calculation for you and simply write 802 into the program. You can use Reflector to verify that. Also floating point literals in the source code are likely Double by default so you have much greater precision to begin with here. If result is a Single this will be downcasted to Single and the error in the 16th digit after the decimal point is simply thrown away since it can't fit into Single anyway.

最后的乘客 2024-08-18 03:47:46

这是由于浮点数在内存中表示方式的限制。通读 wikipedia 页面 了解完整的内幕 - 这不是错误,也不是特定的内容到.net。

编辑:这两篇文章也值得一看(后者是数学重)。

This is due to a limitation in the way floating point numbers are represented in memory. Have a read through the wikipedia page for the full lowdown - it's not an error, or something specific to .net.

EDIT: these two articles are worth a look too (the latter is math heavy).

∞觅青森が 2024-08-18 03:47:46

如果您需要比较浮点值,请参阅此处:比较浮点值

If what you need is to compare floating point values, see here: Comparing floating point values

猫瑾少女 2024-08-18 03:47:46

.NET 中的 SingleDouble 表示为浮点数,不幸的是,存储这些类型的数字并不精确。使用“单”和“双”数字时,您会得到微小的差异。

然而,还有另一种选择 - .NET 有一个 Decimal 类型,它可以更好地处理这些数字。它仍然不完美(请参阅 http://www.yoda.arachsys.com/csharp/ decimal.html - 特别是最后一段),但在表示金钱等数量方面会更好。

Single and Double in .NET are represented as floating point numbers and unfortunately storing these kinds of numbers is not precise. You will get small discrepancies when working with 'Single' and 'Double' numbers.

However there is an alternative - .NET has a Decimal type which is much better at dealing with these numbers. It's still not perfect (see http://www.yoda.arachsys.com/csharp/decimal.html - in particular the last paragraph) but will be much better at representing quantities like money.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文