How can I output localized Java floating point values โ€‹โ€‹with full precision?

If I format double using the toString method, I get the full precision of the double. For example (using Scala syntax):

 java.text.MessageFormat.format ("{0}", Math.PI.toString) 

will result in a line containing:

 3.141592653589793 

However, this value is not localized. If I pass a double value in the form of a marked Double , that is, like:

 java.text.MessageFormat.format ("{0}", Math.PI.asInstanceOf[AnyRef]) 

( AnyRef is a Scala type equivalent to Object in Java), the result is a localized string with truncated precision:

 3.142 

The result will be the same even if I add more hint to the format string:

 java.text.MessageFormat.format ("{0,number}", Math.PI.asInstanceOf[AnyRef]) 

I can get full accuracy by specifying my own format:

 java.text.MessageFormat.format ("{0,number,#.###############}", Math.PI.asInstanceOf[AnyRef]) 

but this requires some knowledge of double magnitude and accuracy. If I print any double value (and not just Pi) and want to preserve the full accuracy of the value, then this approach means that I have to dynamically change the format string - and this is not very convenient if (as in my case) the format string is actually obtained from resource package.

For example, consider the double value 1.0e37 . Converting to a string first and using "{0}" as the format string results in a corresponding, but non-localized, string value of 1.0e37 . If I pass this as a Double box with the format string "{0, number}", then I get a ridiculous value of 10,000,000,000,000,000,000,000,000,000,000,000,000 .

In short, I cannot find a format string that preserves the full precision of the double without first converting it to a string - and this is something I would prefer to avoid, like a plague. Is there a number format string that displays the full precision of the double as a localized value?

UPDATE

Just to clarify why I would prefer not to convert double strings to strings:

  • toString returns, as far as I can tell, the valid value of a double Java literal. As a string, the result is not localized when passed to MessageFormat.format . For example, let's say that I want to output a localized form of the value 1234.567 . toString will return "1234.567" , and MessageFormat.format will leave it. Good. I have accuracy. However, in Germany this would make more sense if it looked like "1.234,567" . Even in the US / UK, it would look better if it looked like "1,234.567" .
  • If I pass Integer , Boolean or any other non-primitive floating-point type in MessageFormat.format (with the simple format "{n}") in the box, then I get a well-localized full precision output. I do not need - and should not, because I will lose localized output - I will first convert these values โ€‹โ€‹to strings. This means that I have to look at doubles differently (both floats and BigDecimal s) and convert them to strings before passing them to MessageFormat.format . (Moreover, I must remember this every time.)
+5
source share
2 answers

MessageFormat uses a localized representation with thousands separators, maybe a decimal point, etc. Your use uses the default locale of your platform.

Something needs to be left separate from the programmerโ€™s universal notation, valueOf / toString.

Using double and precision is a bit oxymoron, since the decimal representation is an approximation of the sum of powers of 2 that the double is internal.

To preserve the complete information, you can save the original bits in text form using Double.doubleToRawLongBits and on the return path longBitsToDouble .

 double x = Math.PI; String repr = String.format("%016x", Double.doubleToRawLongBits(x)); x = Double.longBitsToDouble(Long.valueOf(repr, 16)); 
0
source

The binary format in Java is represented by 64 bits, 52 bits are used for the mantissa. log (2 52 ) = 15.65355977. This means that the accuracy of Double is approximately 15-16 digits.

So, I think the result of 3.141592653589793 is almost everything you can get from Double.

-1
source

Source: https://habr.com/ru/post/1203184/


All Articles