如何检测浮点表示错误..99999.. 或 ..00000.. 并在C++中更正它们
How to detect floating point representation errors ...99999... or ...00000... and correct them in C++
我正在使用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 以显示目的。这是最好的。
- 仅使用绝对值对数组进行排序,并在C++中显示实际值
- 如何创建一个空的全局类并在启动时实例化它
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 在函数内部的声明中初始化数组,并在外部使用它
- C++-我可以创建另一个类的成员并在构造函数中使用它吗
- 缓存std::数组的选定元素,并在c++中自动保持其一致性
- 定义C++新的环境变量并在 bat 文件中使用它
- Visual Studio 2017 停止工作,并在打开后显示许多控制台窗口
- 如何读取单个字符并在输入两个字符序列时输出? 使用 while 循环和C++
- 在 c++ 中模拟输入并在 JAVA 中读取它?
- 是否有必要获取锁并在不需要唤醒线程时通知condition_variable?
- 将通用对象传递给 Rust 并在使用后传递回 C++ 进行销毁
- 动态获取 esp32 的 mac 地址并在以太网库中使用它.
- 从.txt文件中读取浮点型数字并在公式中使用它们
- 如何将成员函数作为参数传递并在派生对象上执行方法列表
- 在C++的头文件中使用常量并在程序中询问其地址的任何潜在危险
- C++ 和 Boost.Python - 如何将变量公开给 python 并在循环中更新它?
- 如何在组合框中列出所有可用的 VCL 样式,并在组合框更改事件中应用该样式C++生成器?
- 是否可以在文本文件中找到最长单词的长度,并在同一个文本文件中读取,只需 1 个 while 循环?
- 初始化类中的指针数组,并在另一个类中检索它