-4

这是一个简单的例子:

Dim si As Single
For si = 2.6 To 3.3 Step 0.1
  MsgBox si
Next si

我得到的数字如下(它们显示在 MsgBox 中,如下所示):

2.6
2.7
2.8
2.9
3
3.099999
3.199999
3.299999

所以,我想我会将数据类型从 Single 更改为 Double 看看会发生什么。这一次,没有 .099999 类型编号,但最后一项(迭代)被跳过,如中,缺失,不存在。以下是出现在 MsgBox 显示中的结果):

2.6
2.7
2.8
2.9
3
3.1
3.2

我猜在缺少最后一次迭代的情况下,它会像 .299999 一样跟踪它,并且在自己的脑海中永远不会达到 .3,所以跳过它?但是,这样做的问题是,如果发生这种情况,您会得到一个先前的迭代出现两次才能发生这种情况,就像在单一数据类型示例中所做的那样,如果您在第一个小数,你会注意到 3.0 出现了两次。首先是“3”,然后是“3.0”(如果我们忽略/截断“3.0”部分之后出现的 5 次数字 9 - “3.099999”)。

有趣的是,另一个我使用单数据类型循环的函数显示了我们上面的双数据类型示例所存在的确切问题,而我们上面的单数据类型示例没有任何问题。所以,我在这里的真正原因是我的单一数据类型循环丢失并在使用“步骤 0.1”时跳过了最后一项(递增 0.1)。

有没有一种可靠的方法可以使用“Step 0.1”和非整数数据类型来做到这一点?如果不是,我们是否知道这些混乱事物发生的规则(也就是说,混乱是可预测的)?

我想你们都会觉得这很有趣,我当然很期待理解它。搜索谷歌是没有用的,因为我一输入“for”和“step”的工作,就不断地提出如何使用 step 运算符的示例,没有任何用处。

我很想知道如何忍受这种情况,或者安全地做到这一点,和/或首先为什么会发生这种情况。我宁愿不为这个特定的函数使用整数循环(然后使用另一个变量进行划分以获得我的十进制类型),但是如果我必须这样做并且没有可靠的方法可以做到这一点,我会的。但我把这个留给你们,我的程序员霸主。

我的例子发生在 VB6 中,但是,我也想知道在 VB.NET 甚至 C# 中是否也发生了同样的混乱?我假设它发生在 vba 和 vbscript 中。任何有关这方面的信息也会很有趣并受到赞赏。

先感谢您。

致版主(问题不需要阅读):这不是重复的帖子,可能有其他人用其他语言(例如 C#)发布浮点问题,但这个(VB6)问题的解决方案不一定是与 C# 问题的解决方案相同。可能有一些相同的解决方案,但也会有不同的解决方案,我无法从 C# 帖子中获得不同的解决方案/答案。事实证明,我感兴趣的解决方案是一个特定于 VB6 的解决方案,在引用的 C# 帖子中找不到该解决方案。我敦促模组在尝试关闭帖子之前要勤奋,我看到许多帖子被不公平地关闭有时,在一天结束时,您会进入一个阶段,您不会增加任何价值,而是从本网站的 Q 和 A 风格中删除实质性价值。总之,如果一个类似的帖子甚至有可能提供新的信息/答案或解决方案,你最好不要关闭。特别是如果问题是针对不同语言的,即使概念相似或相同,也必然会有不同的解决方案和特定于语言的解决方案。

4

3 回答 3

8

问题归结为浮点数在内存中的表示方式。许多其他人发布了有关了解浮点数表示方式的良好参考资料的链接。

当您尝试使用双精度而不是单精度时,数字增量如下 - 必须使用调试器逐步获取值,因为ToString不会输出值的完整精度。

2.6
2.7
2.8000000000000003
2.9000000000000004
3.0000000000000004
3.1000000000000005
3.2000000000000006
3.3000000000000007

如您所见,最终值略高于 for 循环的结尾,因此被跳过。

通过使用整数,您可以避免 for 循环中的浮点问题,但您需要在每次迭代时将数字除以 10 以获得要打印的值。

Dim i As Integer
For i = 26 To 33 Step 1
        MsgBox(i / 10)
Next
于 2012-07-06T21:50:56.380 回答
3

尝试使用小数代替精度:

For i As Decimal = 2.6 To 3.3 Step 0.1
  MessageBox.Show(i.ToString)
Next

如果使用 VB6,您可以尝试使用 Currency 类型(如 JeffSiver 所述):

Dim i As Currency
For i = 2.6 To 3.3 Step 0.1
  MsgBox i
Next
于 2012-07-06T21:24:42.520 回答
2

我乘以 10 并为循环使用整数。即使使用decimal我认为您可能会遇到相同类型的问题

于 2012-07-06T21:29:03.850 回答