简体   繁体   English

PostgreSQL和Java之间的浮点数表示形式差异

[英]Floating-point number representation difference between PostgreSQL and Java

I use PostgreSQL 9.4.1 (32-bit, Windows) and have a table with a real column - quantity. 我使用PostgreSQL 9.4.1(32位,Windows),并且有一个带有real列的表-数量。 When I execute the following query on pgAdmin: 当我在pgAdmin上执行以下查询时:

SELECT quantity || ' pcs' FROM table

I get the following results: 我得到以下结果:

123.234 psc 123 psc 12 psc 12.3 psc

Surprisingly, the same query through Java driver postgresql-9.4-1201.jdbc4 (and postgresql-9.2-1002.jdbc3 ) is different: 令人惊讶的是,通过Java驱动程序postgresql-9.4-1201.jdbc4 (和postgresql-9.2-1002.jdbc3 )进行的同一查询是不同的:

123.2341 psc 123 psc 12 psc 12.3000002 psc

As quantity is not returned by the query directly (but a string containing it), I don't expect such differences in the results. 由于quantity不是直接由查询返回的(而是包含该quantity的字符串),因此我不希望结果出现这种差异。 Can anyone suggest a solution so that Java result is the same as the one from pgAdmin. 任何人都可以提出一种解决方案,以使Java结果与pgAdmin的结果相同。

It looks like pgAdmin is set to display only 3 trailing digits. 看起来pgAdmin设置为仅显示3个尾随数字。

You can use a DecimalFormat object in your code to display the data in the same manner. 您可以在代码中使用DecimalFormat对象,以相同的方式显示数据。

double numberOne = 123.2341;
double numberTwo = 123;
double numberThree = 12;
double numberFour = 12.30000002;

DecimalFormat formatter = new DecimalFormat();
formatter.setMaximumFractionDigits(3);

System.out.println(formatter.format(numberOne));   // 123.234
System.out.println(formatter.format(numberTwo));   // 123
System.out.println(formatter.format(numberThree)); // 12
System.out.println(formatter.format(numberFour));  // 12.3

PostgreSQL says that the real data type is an inexact, variable-precision numeric types , and that [o]n most platforms, the real type has a range of at least 1E-37 to 1E+37 with a precision of at least 6 decimal digits , because they use an IEE754 single precision representation with only 24 bits for the mantissa. PostgreSQL表示实数据类型是不精确的,可变精度的数字类型 ,并且在大多数平台上,实类型的范围至少为1E-37到1E + 37,精度至少为10位小数数字 ,因为它们使用的IEE754单精度表示形式的尾数只有24位。

That means that in the database , 123.234 and 123.2341 are represented by the same value. 这意味着在数据库中 ,123.234和123.2341用相同的值表示。 I assume that you are using double datatype in Java, with a precision of about 15 decimal digits. 我假设您在Java中使用double数据类型,其精度约为15个十进制数字。 The differences are normal. 差异是正常的。

If you want the values to be the same, you can try to use simple precision floats in Java, but you will still depend on the display modes between Java and pgAdmin. 如果您希望这些值相同,则可以尝试在Java中使用简单的精度floats ,但是您仍将依赖于Java和pgAdmin之间的显示模式。

The only foolproof way to maintain accuracy on decimal values is to use NUMERIC(precision, scale) in PostgreSQL, and BigDecimal in Java. 保持十进制值准确性的唯一简单方法是在PostgreSQL中使用NUMERIC(precision, scale)小数位数NUMERIC(precision, scale) ,在Java中使用BigDecimal

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM