如何以全精度输出本地化的Java浮点值?
如果我使用如何以全精度输出本地化的Java浮点值?,java,scala,double,messageformat,Java,Scala,Double,Messageformat,如果我使用toString方法格式化一个double,那么我就得到了double的全部精度。例如(使用Scala语法): 将生成一个字符串,其中包含: 3.141592653589793 但是,此值不是本地化的。如果我将double值作为装箱的double传递,则如下所示: java.text.MessageFormat.format ("{0}", Math.PI.asInstanceOf[AnyRef]) (AnyRef是Scala类型,相当于Java中的Object),则结果是一个具有
toString
方法格式化一个double,那么我就得到了double的全部精度。例如(使用Scala语法):
将生成一个字符串,其中包含:
3.141592653589793
但是,此值不是本地化的。如果我将double值作为装箱的double
传递,则如下所示:
java.text.MessageFormat.format ("{0}", Math.PI.asInstanceOf[AnyRef])
(AnyRef
是Scala类型,相当于Java中的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
。如果我将其作为带格式字符串“{0,number}”的装箱Double
传递,则会得到荒谬的值100000000000000000000000000000
简言之,我似乎找不到一个格式字符串,在不首先将其转换为字符串的情况下保持double的全部精度,而这正是我希望避免的问题,就像瘟疫一样是否有一个数字格式字符串,可以输出双精度的全部精度作为本地化值?
更新:
为了澄清为什么我不希望将双精度转换为字符串:
返回一个有效的Java双文本值。作为字符串,当传递到toString
时,结果不会本地化。例如,假设我想要输出值的本地化形式MessageFormat.format
1234.567
将返回toString
,而“1234.567”
将保留它。好的我有我的精确输出。然而,在德国,如果它显示为MessageFormat.format
,则更有意义。即使在美国/英国,如果它显示为“1.234567”
,看起来也会更好“1234.567”
- 如果我将装箱的
、Integer
或任何其他非浮点基元类型传递到Boolean
(使用简单的“{n}”格式),那么我将得到精确本地化的全精度输出。我不需要——也不应该,因为我将丢失本地化输出——首先将这些值转换为字符串。这意味着我必须以不同的方式处理double(以及float和MessageFormat.format
s),并在将它们传递到BigDecimal
之前将它们转换为字符串。(此外,我必须记住每次都要这样做。)MessageFormat.format
因此,我认为结果
3.141592653589793
几乎就是您可以从Double中获得的所有结果。MessageFormat使用本地化表示,带有数千个分隔符,可能是十进制逗号等等。在您的使用中,它使用平台的默认语言环境
应该与通用程序员的符号valueOf/toString分开
使用double
和precision
有点自相矛盾,因为十进制表示法是double内部的2的幂和的近似值
要保留完整信息,您可以使用并在返回时使用longBitsToDouble
以文本形式存储原始位
double x = Math.PI;
String repr = String.format("%016x", Double.doubleToRawLongBits(x));
x = Double.longBitsToDouble(Long.valueOf(repr, 16));
我不需要一个
BigDecimal
——对于我来说,一个普通的双精度就可以了。转换成BigDecimal对我来说就像转换成字符串一样麻烦。事实上,我只是试着将PI
转换成BigDecimal并输出。。。结果是3.142
,所以这也不起作用问题是:是否有一个数字格式字符串可以输出双精度的全部精度?这不是关于提高浮点值精度的问题,而是关于以尽可能高的精度输出存储在double中的值的问题。我已经指出,如果您首先将双精度值转换为字符串,您将获得完全的精度,但是使用MessageFormat
@MikeAllen似乎没有办法做到这一点对不起,我没有抓住您问题的重点。那么,回到话题上来。似乎没有简单明了的方法可以让MessageFormat按您的需要翻倍。我可以指出的是,提供定制模式,如“#.##################################################等将起作用。您可以在点之后指定任意数量的数字,它将起作用。也许你可以考虑在尾部用一些额外的数字来制作格式常数,并在适当的时候使用它。谢谢你的回复。我正在努力沟通的问题是,自定义格式以某种方式截断了输出值的准确性/精度。如果我知道双精度的大小,比如说,在1-10范围内,那么您指定的格式就可以了。但是如果值是1.2345E-37呢?您的格式将输出0.000000000000000-因此我将失去所有精度!但是,如果我首先通过toString
将双精度值转换为字符串,就可以获得所有精度。我希望toString
中的功能可以作为格式规范使用,MessageFormat.format
可以用来保持完整的精度
double x = Math.PI;
String repr = String.format("%016x", Double.doubleToRawLongBits(x));
x = Double.longBitsToDouble(Long.valueOf(repr, 16));