PostgreSQL real类型转Java BigDecimal出现精度问题原因咨询
为什么从PostgreSQL real列读取为BigDecimal会显示超长小数?
这其实是浮点数的二进制存储特性搞的鬼,咱们一步步理清楚:
核心原因:浮点数的存储本质
PostgreSQL的real类型是32位单精度浮点数,和Java里的float完全对应。这类浮点数的底层用二进制存储,但很多十进制小数(比如0.18)没办法用有限的二进制位精确表示,只能存储一个最接近的近似值。这个近似值的十进制展开就是你看到的0.180000007152557373046875,它是0.18在单精度浮点数里的真实存储值。
Java中float和BigDecimal的行为差异
- 当你用
float类型读取值时,Java在打印float的时候会自动做近似格式化:它会找到最接近这个存储值的、符合人类阅读习惯的短十进制数,所以你看到的是0.18——但这只是显示层面的简化,内存里的真实值还是那个近似的长小数。 - 而
new BigDecimal(float_val)这个构造方法,它的设计是精确还原float的二进制存储值对应的十进制数,不会做任何格式化简化,所以直接把那个隐藏的真实近似值完整输出了。你的测试代码也完美验证了这一点:直接把0.18f转成BigDecimal,就会输出那个超长小数。
小解决方案
如果你的场景不需要那个精确的近似值,只是想要和float显示一致的BigDecimal,可以改用BigDecimal.valueOf(float_val)方法。这个方法会基于float的字符串表示来创建BigDecimal,就能得到你预期的0.18了。
测试代码验证
public class BigDecimalTest { public static void main(String[] args){ float float_val = 0.18f; BigDecimal output = new BigDecimal(float_val); BigDecimal output2 = BigDecimal.valueOf(float_val); System.out.println("BigDecimal output is: "+ output); System.out.println("BigDecimal.valueOf output is: "+ output2); System.out.println("Float output is: "+float_val); } }
输出结果
BigDecimal output is: 0.180000007152557373046875
BigDecimal.valueOf output is: 0.18
Float output is: 0.18
内容的提问来源于stack exchange,提问作者user3379502
相关产品推荐
相关产品推荐

