BigDecimal 变量在 JDBC 插入中用随机数填充
考虑 SQL 语句 INSERT INTO 表(字段)VALUES (-0.11111111)
和 field
Oracle 类型 NUMBER。
当要插入的值是float或double类型时,您将在field
中获得精确的值,即-0.11111111。
但是,当要插入的值是 BigDecimal 类型时,您会得到用随机数填充的值,即 0.1111111099999999990428634077943570446223。
为什么?
Java 声明“BigDecimal 是不可变的、任意精度的有符号十进制数”。
代码是:
String sql = "INSERT INTO pat_statistics (file_key,test_number,rqw)"
+ " VALUES (3778, 100, " + new BigDecimal(-0.11111111) + ")";
Class.forName(driver);
Connection conn = DriverManager.getConnection(url, user, pwd);
Statement st = conn.createStatement();
int n = st.executeUpdate(sql);
数据库是Oracle。
Consider SQL statement INSERT INTO table (field) VALUES (-0.11111111)
with field
Oracle type NUMBER.
When the value to be inserted is of type float or double, you get the exact value in field
, i.e. -0.11111111.
But when the value to be inserted is of type BigDecimal
, you get the value padded with random numbers, i.e. 0.1111111099999999990428634077943570446223.
Why?
Java states that "BigDecimal
is an immutable, arbitrary-precision signed decimal numbers."
The code is:
String sql = "INSERT INTO pat_statistics (file_key,test_number,rqw)"
+ " VALUES (3778, 100, " + new BigDecimal(-0.11111111) + ")";
Class.forName(driver);
Connection conn = DriverManager.getConnection(url, user, pwd);
Statement st = conn.createStatement();
int n = st.executeUpdate(sql);
The DB is Oracle.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您正在从 double 创建 BigDecimal,因此它将准确反映 double 的值,并且您可能知道浮点数的尾随数字更加随机。
我假设您在数据库中看到了这一点,因为 JDBC 驱动程序认为:嘿,我得到了一个
BigDecimal
。我可以使用我能掌握的所有数字。当您使用
float
或double
时,JDBC 驱动程序知道我无法真正使用所有数字,并忽略该阈值之后的数字。如果您需要
BigDecimal
的额外精度,请从String
创建它或从Integer
计算它。更正 该处理
不是由 JDBC 驱动程序完成的,而是由各种
toString
转换完成的,因为您正在组装 SQL 字符串。顺便说一句:你真的应该为此使用绑定变量。
You are creating the BigDecimal from a
double
so it will reflect exactly the value of thedouble
, and as you probably know the trailing digits of a float are more ore less random.I assume you see this in the database because the JDBC driver thinks: Hey I am getting a
BigDecimal
. I can use all the digits I can master.When you use
float
ordouble
the JDBC driver knows I can't realy use all the digits and ignores what comes after that threshold.If you need the additional precision of
BigDecimal
, create it from aString
or calculate it fromInteger
s.a correction
The handling is not done by the JDBC driver, but by the various
toString
conversions, since you are assembling your SQL String.BTW: you really should use bind variables for this.
对于文字值,您应该始终使用带有字符串参数的 BigDecimal 构造函数。请参阅 BigDecimal( double) 构造函数 了解详细信息。
For a literal value you should always use the BigDecimal constructor taking a string argument. See the documentation of the BigDecimal(double) constructor for details.