1 java t-sql sql-server rounding-error jdbc
我在将具有一定小数精度的双精度值插入数据库表时遇到问题。我使用的是 MS SQL Server 版本 10.0.4000\n下面是一个示例表,其小数列具有 4 个小数位。
\n\ncreate table test (\ntest decimal (18,4))\nRun Code Online (Sandbox Code Playgroud)\n\n当我通过 MSSQL 控制台插入值 \xe2\x80\x9c36.78675\xe2\x80\x9d 时,它会四舍五入,因为36.7868该字段仅包含 4 位小数。这可以。
DECLARE @T DECIMAL(18, 5)\n\nSET @T = 36.78675\n\ninsert into test values(@T)\n\nselect * from test\nRun Code Online (Sandbox Code Playgroud)\n\n但是,当我通过 java 代码(MS SQL JDBC 驱动程序)执行等效插入(使用准备好的语句)时,数据存储在表中36.7867。如果我有一个类似 的值36.786750001,控制台和 JDBC 都会四舍五入到36.7868。\n我使用的java对象是double。我正在使用双值调用 setDouble() 。这里它会自动选择数据类型。但还有另一种 JDBC 方法,它采用对象和数据类型。使用它,我测试了 DECIMAL 和 FLOAT 类型。所有人都给出相同的结果。我什至将jdbc驱动程序更改为I-net。也有同样的结果。
有人知道为什么驱动程序的舍入工作方式不同吗?是否有任何设置可以使其行为像控制台一样?
\n这是因为二进制浮点的性质,这就是您所使用的double(在 Java 中)。
最接近 36.7875的精确值为double
36.7867499999999978399500832892954349517822265625
Run Code Online (Sandbox Code Playgroud)
该值将向下舍入为 36.7867。而最接近 36.78750001的精确值是double
36.786750000099999624580959789454936981201171875
Run Code Online (Sandbox Code Playgroud)
则四舍五入为 36.7878。这就是为什么你会出现这种行为。控制台可能将输入视为十进制数,而不是根本转换为二进制浮点数。
如果精确的十进制数字对您很重要,您可能不应该使用二进制浮点类型 - 使用BigDecimal而是使用。
你应该认真思考你的价值代表什么。如果它是物理连续值,例如身高、长度或体重,那么使用double可能是合适的 - 但您不应该对这样的情况感到困扰。如果它是具有离散(基于小数)值(例如货币值)的人工BigDecimal构造,那么您绝对应该使用,或者简单地缩放整数。
| 归档时间: |
|
| 查看次数: |
3855 次 |
| 最近记录: |