如何检测浮点表示错误..99999.. 或 ..00000.. 并在C++中更正它们

How to detect floating point representation errors ...99999... or ...00000... and correct them in C++

本文关键字:C++ 并在 00000 99999 错误 何检测 检测 表示      更新时间:2023-10-16

我正在使用Firebird 1.5.x数据库,它对存储在双精度或numeric(15,2)字段中的变量有问题。 例如,我可以发出更新(field_1和field_2声明为数字(15,2)):

update test_table set
  field_1=0.34,
  field_2=0.69;

但是,当将field_1和field_2读入 SQL 存储过程内的变量var_1和var_2时,var_1 和 var_2 分别假定值为 0.3400000000000000024 和 0.689999999999999947。乘法 var_1*var_2*25 得到 5.8649999999999999635,可以四舍五入为 5.86。这显然是错误的,因为正确的最终值是 5.87。

舍入是使用来自我开发的DLL的用户定义函数完成C++。这个想法是检测有重复错误的情况,进行更正并仅对更正的值应用舍入过程。

所以,问题是 - 如何检测和纠正重新识别错误。 例如检测 0.68999999999999947 应更正为 0.69,并检测 0.340000000000000024 应更正为 0.34。通常,可能会出现点后有效数大于或小于 2 的情况,例如 0.234599999999999999854 应更正为 0.2346。

如果可以在C++做,也许已经存在一些解决方案?

附言我在最近的Firebird版本2.x中测试了这种情况,并且在存储过程中将数据库字段读取到变量中没有问题。但我可以猜测,在一些冗长的计算过程中,在最近的Firebird版本中也可能会出现表示错误。

谢谢!

此问题存在于使用浮点变量的所有编程语言中。

您需要了解没有准确的方法来显示 1/3。这种价值的任何展示都是有关各方必须商定的妥协。必须同意所需的精度。如果你明白这一点,我们就可以继续前进。

那么,我们如何(例如)准确地开发会计系统呢?一种方法是舍入(column_name、required_precision)计算中使用的所有值。还将任何除法的结果四舍五入到相同的精度。在整个应用中始终如一地使用商定的精度非常重要。

另一种方法是始终将浮点值乘以 100(如果您的值表示货币),并将结果值分配给整数变量。同样,除法的结果必须四舍五入到小数点后 0 位,然后才能分配给它的整数存储。然后将值除以 100 以显示目的。这是最好的。

相关文章: