6

如果我使用该方法格式化双toString精度,那么我将获得双精度。例如(使用Scala语法):

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

将产生一个包含以下内容的字符串:

3.141592653589793

但是,此值未本地化。如果我将 double 值作为 boxed 传递Double,则为:

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

(是等效于JavaAnyRef中的Scala类型),则结果是具有截断精度的本地化字符串:Object

3.142

即使我向格式字符串添加更多提示,结果也是一样的:

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

我可以通过指定自定义格式来获得完整的精度:

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

但这需要对双精度的大小和精度有所了解。如果我正在打印任何双精度值(不仅仅是Pi),并且想要保留该值的完整精度,那么这种方法意味着我必须动态更改格式字符串 - 如果(在我的情况下)这并不完全方便) 格式字符串实际上是从资源包中获取的。

例如,考虑 的双精度值1.0e37。首先转换为字符串并使用“{0}”作为格式字符串会产生适当但未本地化的字符串值1.0E37。如果我将其作为Double格式字符串“{0,number}”的框传递,那么我会得到荒谬的值10,000,000,000,000,000,000,000,000,000,000,000,000

简而言之,如果不首先将其转换为字符串,我似乎无法找到一个保留双精度的格式字符串 - 这是我宁愿避免像瘟疫一样的事情。是否有数字格式字符串将双精度的完整精度输出为本地化值?

更新

只是为了澄清为什么我不想将双打转换为字符串:

  • toString返回,据我所知,一个有效的Java双字面值。作为一个字符串,结果在传递给MessageFormat.format. 例如,假设我想输出 value 的本地化形式1234.567toString会返回"1234.567",并MessageFormat.format会离开它。美好的。我有我的精确输出。但是,在德国,如果它显示为"1.234,567". 即使在美国/英国,如果它显示为"1,234.567".
  • 如果我将 boxed IntegerBoolean或任何其他非浮点原始类型传递给MessageFormat.format(使用简单的“{ n }”格式),那么我会得到很好的本地化、全精度输出。我不需要——也不应该——因为我会丢失本地化输出——首先将这些值转换为字符串。这意味着我必须以BigDecimal不同的方式处理双精度数(以及浮点数和 s),并将它们转换为字符串,然后再将它们传递给MessageFormat.format. (此外,我必须记住每次都这样做。)
4

2 回答 2

0

MessageFormat 使用本地化表示,带有千位分隔符,可能是十进制逗号等。在您的使用中,它使用您平台的默认语言环境。

有些东西应该与通用程序员的符号 valueOf/toString 分开。

使用doubleandprecision有点矛盾,因为十进制表示是 double 在内部的 2 的幂和的近似值。

要保留完整信息,您可以使用Double.doubleToRawLongBits并在返回的路上以文本形式存储原始位longBitsToDouble

double x = Math.PI;
String repr = String.format("%016x", Double.doubleToRawLongBits(x));
x = Double.longBitsToDouble(Long.valueOf(repr, 16));
于 2014-09-23T14:05:14.753 回答
-1

Java中的double格式用64位表示,52位用于尾数。日志(2 52)= 15.65355977。这意味着 Double 的精度大约为 15-16 位。

所以我认为结果3.141592653589793几乎就是你能从 Double 获得的一切。

于 2014-09-23T12:53:09.360 回答