Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java DecimalFormat和Double.valueOf()格式_Java_Number Formatting_Decimalformat - Fatal编程技术网

Java DecimalFormat和Double.valueOf()格式

Java DecimalFormat和Double.valueOf()格式,java,number-formatting,decimalformat,Java,Number Formatting,Decimalformat,我试图在我的双精度值的小数分隔符之后去掉不必要的符号。我是这样做的: DecimalFormat format = new DecimalFormat("#.#####"); value = Double.valueOf(format.format(41251.50000000012343)); 但当我运行此代码时,它抛出: java.lang.NumberFormatException: For input string: "41251,5" at sun.misc.Floating

我试图在我的双精度值的小数分隔符之后去掉不必要的符号。我是这样做的:

DecimalFormat format = new DecimalFormat("#.#####");
value = Double.valueOf(format.format(41251.50000000012343));
但当我运行此代码时,它抛出:

java.lang.NumberFormatException: For input string: "41251,5"
    at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1224)
    at java.lang.Double.valueOf(Double.java:447)
    at ...
正如我所看到的,
Double.valueOf()
对于
“11.1”
这样的字符串非常有效,但是它会阻塞
“11,1”
这样的字符串。我如何解决这个问题?还有比这更优雅的方式吗

Double.valueOf(format.format(41251.50000000012343).replaceAll(",", "."));

是否有方法覆盖
DecimalFormat
类的默认十进制分隔符值?还有其他想法吗?

您不能以这种方式更改
double
/
double
的内部表示形式

如果要更改(人类)表示,只需保留它
String
。因此,将该
Double#valueOf()
放在一边,并在演示文稿中使用
DecimalFormat()的
字符串
结果。如果您想使用它进行计算,您可以使用
DecimalFormat
Double\valueOf()
将其转换回实数
Double


顺便说一句,根据你的抱怨,我正试图在我的双精度值的十进制分隔符之后去掉不必要的符号?闻起来有点像您在表示层中使用了未格式化的Double,您没有意识到,在普通UI中,您可以使用
DecimalFormat
来表示它们,而无需转换回
Double

使用
Locale.getDefault()
获取系统的十进制分隔符,您也可以设置它。您不能同时使用两个不同的分隔符,因为另一个分隔符通常用作数千的分隔符:
2.001.000,23 2001000.23
对于“
”而不是“
”,您必须更改区域设置

对于小数位数,请使用
setMaximumFractionDigits(int newValue)


对于其余部分,.

格式化字符串使用
作为十进制分隔符,而异常则抱怨
指向区域设置问题;i、 e.DecimalFormat正在使用与Double.valueOf不同的区域设置来格式化数字

通常,您应该基于特定的区域设置构造一个
NumberFormat

Locale myLocale = ...;
NumberFormat f = NumberFormat.getInstance(myLocale);
从以下的JavaDocs:

要获取特定区域设置(包括默认区域设置)的NumberFormat,请调用NumberFormat的工厂方法之一,例如getInstance()。通常,不要直接调用DecimalFormat构造函数,因为NumberFormat工厂方法可能返回DecimalFormat以外的子类

然而,试图将double格式化为字符串,然后将字符串解析回double是一种非常糟糕的代码味道。我怀疑您所处理的问题是,您希望使用固定精度的十进制数(如货币金额),但由于double是一个浮点数,这意味着许多值(如
0.1
)无法精确地表示为double/float,因此遇到了问题。如果是这种情况,处理固定精度十进制数的正确方法是使用。

By

在我的双精度值的小数分隔符后去掉不必要的符号

你的意思是要四舍五入到小数点后五位吗?那就用

value = Math.round(value*1e5)/1e5;
(当然,如果你真的想剪掉其他数字,你也可以
Math.floor(value*1e5)/1e5

编辑

使用此方法(或任何浮点舍入)时要非常小心。对于265.335这样简单的东西,它失败了。中间结果265.335*100(2位精度)为26533.49999996。这意味着它将四舍五入到265.33。从浮点数转换为十进制实数时,存在一些固有的问题。见EJP的答案,见-


问题是十进制格式将值转换为本地化字符串。我猜您的区域设置的默认十进制分隔符是带有“
”的。这种情况经常发生在法国或世界其他地区

基本上,您需要做的是使用“.”分隔符创建格式化日期,以便
Double.valueOf
可以读取它。如注释所示,您也可以使用相同的格式来解析值,而不是使用
Double.valueOf

DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance();
symbols.setDecimalSeparator('.');
DecimalFormat format = new DecimalFormat("#.#####", symbols);
value = format.parse(format.format(41251.50000000012343));

与此相关,但不是问题的答案:尝试切换到BigDecimal而不是Double和Float。我在比较这些类型时遇到了很多问题,现在我可以使用BigDecimal了。

看起来您的本地语言使用逗号“,”作为十进制分隔符。要将“.”作为十进制分隔符,您必须声明:

DecimalFormat dFormat =new DecimalFormat("#.#", new DecimalFormatSymbols(Locale.ENGLISH));

真正的解决方案是:对于需要精确计数的任何东西,都不要使用浮点数:

  • 如果你在处理货币问题,不要使用两倍的美元,使用整数的美分
  • 如果您处理的是小时数,并且需要计算四分之一小时和10分钟间隔,请使用整数分钟数
浮点数几乎总是某个实数的近似值。它们适用于物理量(最高精度)的测量和计算以及统计伪影

游手好闲地将浮点四舍五入到多个数字是一种代码味道:这是浪费,而且您永远无法真正确定您的代码在所有情况下都能正常工作。

我的代码功能:

 private static double arrondi(double number){
         DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance();
         symbols.setDecimalSeparator('.');
         DecimalFormat format = new DecimalFormat("#.#####", symbols);
         return Double.valueOf(format.format(number));
     }

问题是,当我将其转换为
字符串时,它将不会使用
Double.valueOf()
,将其转换回
Double
,因为
DecimalFormat
放置
,其中
valueOf()
应为
。那么有没有一种方法可以在
DecimalFormat
类中重写它(这样我就不必在那里调用
replaceAll(“,”,“)