2014-04-01 54 views
0

我遇到了计算在我的函数中关闭的问题。我正在使用VB6,这可能是我的第一个问题。发生了什么是我遍历一个循环,从一个变量步进到另一个变量,逐步变量,计算每个项目的折扣。它将每个计算得出的折扣放在文本文件查找表中。如果用户输入的值在这两个值之间,那就是它应用的折扣。被设置为错误值的变量

问题出在计算折扣价值。假设我每步每单位折扣0.04美元。因此,第一步的折扣将是.04,然后是.08,然后是.12等。要计算此值,它会计算经过指定范围的步数,然后将步数乘以每步折扣值。这是主要问题。当我这样做,我得到一个浮点舍入错误。我将总步骤(1)乘以总折扣(.04)并获得.03999999999999999。

这不会是一个大问题,但是因为它多次计算出来,并且将计算添加到计算中,所以我不会有这种精度损失,它会在晚些时候丢掉我的值。我如何避免这种舍入错误? 另外值得注意的是,我分配的价值是双打和单打,这是否可以解决问题?

TL; DR:1 * .04 = .03999999999999出于某种原因在VB6中。即使我分配一个浮点变量= 15.1,它也会变成= 15.1000003814697。我将如何去解决这个问题?

+0

尝试使用十进制数据类型而不是double或single。另外,无处不在地使用它。 –

+0

我应该说你应该在计算中转换为十进制。例如:CDec(变量1)* CDec(变量2) –

回答

1

浮点值类型(单和双)都有这个问题,由于它们在内存中被表示为两部分:尾数和指数。如果你想要整数类似的精度,那么你必须使用十进制子类型。 VB6不直接支持这种类型。例如,你不能写:

Dim decValue As Decimal 
decValue = 1.536 

相反,Decimal支持通过Variant类型,例如,

Dim vdecValue As Variant 
vdecValue = CDec (1.536) 

好处是你得到了你想要的精度。缺点是每个值占用14个字节而不是4或8个。您也受限于接受Variant/Decimals的函数。

这是一个耻辱,你还没有提供一个算法。你很可能可以预先解决舍入问题。例如,如果您的折扣在已知范围内,并且已知精度(例如0.11至0.95),则可以将总折扣记录为整个值的百分之一。您将百分之一作为整数/长整型值,并且只在最后可能的点处转换为单/双。显然,这只适用于你不需要运行总数的情况。具有讽刺意味的是,这个“假定的小数点”正是VB代表货币和十进制值的方式。