从MySQL返回到Java的双精度值不正确。

huangapple go评论78阅读模式
英文:

Incorrect double values returned from mysql to java

问题

以下是翻译好的内容:

所以我试图从MySQL读取一些双精度(double)值到Java中。
我正在使用一个MyBatis映射器(mapper)来读取我的值,并将该值作为映射(map)返回。

当我在SQL中运行我的查询时,我的值变为-42295.8451869851,但是当我使用MyBatis从查询中获取相同的值并将其放入Java HashMap中时,该值变为{Double@25327}-42295.84518699004。为什么会出现这种异常情况,我该如何防止它?

这是我使用的MyBatis查询行:
我使用了类org.apache.ibatis.session.SqlSession

List<Map<String, Object>> myListMaps = getSqlSession().selectList(QUERY_NAME, queryParameters);

编辑:在查看了一些回答后,我意识到我需要以某种方式使用BigDecimal而不是Double/Float。因此,我将重新调整我的问题,以解决我的目标。是否有任何方法可以告诉MyBatis将特定的SQL类型映射到HashMap中的BigDecimal,而不是Double/Float?

我还从SQL中获取其他值,如integervarchar,它们会自动转换为所需的integerstring类型的Java值,并且我希望它们按原样获取。我只需要将双精度(double)更改为BigDecimal即可。

英文:

So I was trying to read some double values from mysql to java.
I am using a mybatis mapper to read my values and return the value as a map.

When I run my query in sql, my value comes out to be -42295.8451869851 but when I use mybatis to pick the same from a query and put it in a java Hashmap the value changes to {Double@25327}-42295.84518699004 . Why is this anomaly and what can I do to prevent it?

This is the mybatis query line I am using:
I am using the class org.apache.ibatis.session.SqlSession;

List&lt;Map&lt;String, Object&gt;&gt; myListMaps =  getSqlSession().selectList(QUERY_NAME, queryParameters);

Edit: After looking at few responses, I realize that I need to somwhow use bigDecimal instead of Double/Float. So I will reframe my question to solve my purpose here. Is there any way to tell mybatis that a certain sql type is to be mapped to BigDecimal instead of Double/Float in a HashMap?

I also have other values being picked up from sql like integer and varchar that are being converted to the required types of integer and string in java automatically and I want them picked as it is. Just need to change the doubles to bigdecimal.

答案1

得分: 2

这种行为对于浮点数是预期的。您可以阅读 IEEE 754 的工作原理:https://en.wikipedia.org/wiki/IEEE_754。

但我认为还有另一个问题正在发生。您说这个数字是双精度(64位),但根据结果,它似乎被转换为单精度(32位)。

-42295.8451869851 -> 0xC0E4A6FB0BC59380(64位)- 0xC72537D8(32位)

-42295.84518699004 -> 0xC0E4A6FB0BC59627(64位)- 0xC72537D8(32位)

如果要保持正确的精度,您需要在数据库中正确定义,然后在Java中使用https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html

英文:

This behavior is expected for the floating point number. You can read how the IEEE 754 works https://en.wikipedia.org/wiki/IEEE_754.

But I think there is another issue happening. You say that the number is double (64-bit), but based on the result it look that it gets converted to float(32-bit)

-42295.8451869851 -&gt; 0xC0E4A6FB0BC59380 (64bit) - 0xC72537D8 (32bit)

-42295.84518699004 -&gt; 0xC0E4A6FB0BC59627 (64bit)- 0xC72537D8 (32bit)

If you want to keep the precision correct then you need to define it correctly both in DB and then in Java use https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html

答案2

得分: 1

使用BigDecimal来确保精度 文档

英文:

Use BigDecimal if you need precision doc.

huangapple
  • 本文由 发表于 2020年9月11日 13:48:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/63841429.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定