在C和x2B之间传递数据时出现浮点精度问题+;和Oracle数据库 我们有一个安装程序,其中一个远程C++客户端调用一个Oracle函数(使用OCI库)传递一些数据。然后,此Oracle函数将数据插入表中。传递给函数的数据之一是AMOUNT,它是一个浮点数 在C++客户端中,这个量变量定义为“double”。Oracle函数和表都将此列的数据类型定义为“NUMBER”(没有明确定义任何精度或刻度)

在C和x2B之间传递数据时出现浮点精度问题+;和Oracle数据库 我们有一个安装程序,其中一个远程C++客户端调用一个Oracle函数(使用OCI库)传递一些数据。然后,此Oracle函数将数据插入表中。传递给函数的数据之一是AMOUNT,它是一个浮点数 在C++客户端中,这个量变量定义为“double”。Oracle函数和表都将此列的数据类型定义为“NUMBER”(没有明确定义任何精度或刻度),c++,oracle,floating-point,C++,Oracle,Floating Point,我们发现客户端发送的内容与我们在数据库中接收和存储的内容之间存在很多不一致之处。例如,客户声称他们正在传递一个值“35.6”,但我们在表中看到的是“35.59999847” 我们应该存储精度高达小数点后6位的值。如果我将AMOUNT列的数据类型定义从NUMBER改为NUMBER(38,6),则得到“35.599998”。如果我把它改成数字(38,5),我最终会得到“35.6” 有人能告诉我这里可能发生了什么吗?我知道将数量或价格值当作浮点数字来处理是不可取的,应该用整数代替,但是在这种情况下,我

我们发现客户端发送的内容与我们在数据库中接收和存储的内容之间存在很多不一致之处。例如,客户声称他们正在传递一个值“35.6”,但我们在表中看到的是“35.59999847”

我们应该存储精度高达小数点后6位的值。如果我将AMOUNT列的数据类型定义从NUMBER改为NUMBER(38,6),则得到“35.599998”。如果我把它改成数字(38,5),我最终会得到“35.6”

有人能告诉我这里可能发生了什么吗?我知道将数量或价格值当作浮点数字来处理是不可取的,应该用整数代替,但是在这种情况下,我们对C++客户端没有任何控制。我们在一组非常大的数据中看到了这个问题(超过50%的数据存在这个问题)


而且,这个问题不仅仅局限于浮点数。即使使用大整数,我们也可以看到不一致的情况(例如,传递为100000000的值存储为1000000004)。

您可能无法控制客户端,但可以更改接口吗

将浮点传递给Oracle将不可避免地导致此问题,因为它们本身就是一种不精确的数据类型。但是如果您可以修改接口,您可以将两个整数传递给Oracle:金额的整数和金额的小数部分。然后Oracle可以将这两个整数组合成一个数字变量,它可以愉快地使用这个变量


因为我写了这篇文章,你已经编辑了你的问题,正如奥利指出的,这个建议不再有效

你能做些什么呢

  • 通过在Oracle层强制使用十进制精度来伪造它。这可能会产生一些舍入误差,但比现在要小得多。虽然它不能解决大整数的问题
  • 将此作为C++客户端开发人员的一个bug。(专业提示:提交bug报告时,尽量不要称他们为愚蠢的白痴)
  • 告诉你的用户他们将不得不接受它

  • 至于为什么这是Oracle的问题,而不是您的其他系统的问题,那么MySQL支持FLOAT和DOUBLE,据推测其他系统也支持FLOAT和DOUBLE。Oracle对数据完整性的要求一直非常严格,而浮点值太过宽松

    >如果C++客户端使用十进制和第二个数据库使用数字,那么浮点进入哪里?编辑了我的帖子。@OliCharlesworth,是的,我以前看过那个网站。但我从未想过这个问题会太广泛。同样,C++客户端也正在调用其他系统(例如MySQL数据库)。它们是同步的。到目前为止,这个问题只在C++和Oracle集成中出现,但已经太迟了。OP声明客户端将值存储在一个
    双精度文件中,因此精度已经丢失。@OliCharlesworth-OP在我发布此文件后更改了该值。虽然我同意,但这确实会使我的建议无效。