Java 中要向上舍入的双精度值
我有一个双精度值 = 1.068879335
我想用两个小数值(例如 1.07)将其四舍五入。
我这样尝试,
DecimalFormat df=new DecimalFormat("0.00");
String formate = df.format(value);
double finalValue = Double.parseDouble(formate) ;
这给了我以下异常,
java.lang.NumberFormatException: For input string: "1,07"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1224)
at java.lang.Double.parseDouble(Double.java:510)
有人可以告诉我我的代码有什么问题吗?
最后我需要 FinalValue = 1.07;
I have a double value = 1.068879335
i want to round it up with only two decimal values like 1.07.
I tried like this
DecimalFormat df=new DecimalFormat("0.00");
String formate = df.format(value);
double finalValue = Double.parseDouble(formate) ;
this is giving me this following exception
java.lang.NumberFormatException: For input string: "1,07"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1224)
at java.lang.Double.parseDouble(Double.java:510)
can some one tell me what is wrong with my code.
finaly i need the finalValue = 1.07;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
请注意字符串中的逗号:“1,07”。
DecimalFormat
使用特定于区域设置的分隔符字符串,而Double.parseDouble()
则不使用。由于您碰巧生活在小数点分隔符为“,”的国家/地区,因此您无法解析您的号码。但是,您可以使用相同的
DecimalFormat
来解析它:但是您确实应该这样做:
注意: 正如已经指出的,您应该只在以下情况下使用浮点:您不需要精确控制准确性。 (财务计算是不使用它们的主要例子。)
Note the comma in your string: "1,07".
DecimalFormat
uses a locale-specific separator string, whileDouble.parseDouble()
does not. As you happen to live in a country where the decimal separator is ",", you can't parse your number back.However, you can use the same
DecimalFormat
to parse it back:But you really should do this instead:
Note: As has been pointed out, you should only use floating point if you don't need a precise control over accuracy. (Financial calculations being the main example of when not to use them.)
实时@Sergey 的解决方案,但使用整数除法。
打印
编辑:正如谢尔盖指出的那样,乘以 double*int 和 double*double 与除以 double/int 和 double/double 之间应该没有区别。我找不到结果不同的例子。然而,在 x86/x64 和其他系统上,有一个针对混合 double,int 值的特定机器代码指令,我相信 JVM 使用它。
印刷
Live @Sergey's solution but with integer division.
prints
EDIT: As Sergey points out, there should be no difference between multipling double*int and double*double and dividing double/int and double/double. I can't find an example where the result is different. However on x86/x64 and other systems there is a specific machine code instruction for mixed double,int values which I believe the JVM uses.
Prints
问题是您使用本地化格式化程序来生成特定于区域设置的小数点,在您的情况下为“,”。但 Double.parseDouble() 需要非本地化的双文本。您可以通过使用特定于区域设置的解析方法或将格式化程序的区域设置更改为使用“.”的区域来解决您的问题。作为小数点。或者更好的是,通过使用如下内容来避免不必要的格式化:
The problem is that you use a localizing formatter that generates locale-specific decimal point, which is "," in your case. But Double.parseDouble() expects non-localized double literal. You could solve your problem by using a locale-specific parsing method or by changing locale of your formatter to something that uses "." as the decimal point. Or even better, avoid unnecessary formatting by using something like this:
您尝试做的事情存在根本性错误。二进制浮点值没有小数位。您无法有意义地将 1 舍入到给定的小数位数,因为大多数“舍入”十进制值根本无法表示为二进制分数。这就是为什么永远不要使用
float
或double
来表示金钱。因此,如果您希望结果中包含小数位,则该结果必须是
String
(您已通过DecimalFormat
获得)或BigDecimal
> (它有一个setScale()
方法,可以完全满足您的需求)。否则,结果不可能是你想要的。请阅读浮点指南了解更多信息。
There is something fundamentally wrong with what you're trying to do. Binary floating-points values do not have decimal places. You cannot meaningfully round one to a given number of decimal places, because most "round" decimal values simply cannot be represented as a binary fraction. Which is why one should never use
float
ordouble
to represent money.So if you want decimal places in your result, that result must either be a
String
(which you already got with theDecimalFormat
), or aBigDecimal
(which has asetScale()
method that does exactly what you want). Otherwise, the result cannot be what you want it to be.Read The Floating-Point Guide for more information.
试试这个:
org.apache.commons.math3.util.Precision.round(double x, int scale)
请参阅:
http://commons.apache .org/proper/commons-math/apidocs/org/apache/commons/math3/util/Precision.html
Apache Commons 数学库主页是:
http://commons.apache.org/proper/commons-math/index.html
该方法的内部实现是:
Try this:
org.apache.commons.math3.util.Precision.round(double x, int scale)
See:
http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/util/Precision.html
Apache Commons Mathematics Library homepage is:
http://commons.apache.org/proper/commons-math/index.html
The internal implemetation of this method is:
您可以尝试定义一个新的 DecimalFormat 并将其用作新的 double 变量的 Double 结果。
举个例子让你明白我刚才说的。
You could try defining a new DecimalFormat and using it as a Double result to a new double variable.
Example given to make you understand what I just said.
这在请求的方式中是不可能的,因为有两位小数的数字无法使用 IEEE 浮点数精确表示(例如 1/10 = 0.1 不能表示为
Double
或浮动
)。格式化应该始终作为将结果呈现给用户之前的最后一步进行。我猜你这么问是因为你想处理货币价值。没有办法用浮点数可靠地做到这一点,你应该考虑切换到定点算术。这可能意味着所有计算都以“美分”而不是“美元”为单位。
This is not possible in the requested way because there are numbers with two decimal places which can not be expressed exactly using IEEE floating point numbers (for example 1/10 = 0.1 can not be expressed as a
Double
orFloat
). The formatting should always happen as the last step before presenting the result to the user.I guess you are asking because you want to deal with monetary values. There is no way to do this reliably with floating-point numbers, you shoud consider switching to fixed-point arithmetics. This probably means doing all calculations in "cents" instead of "dollars".
您可以使用类似 的格式在这里,
You can use format like here,
如果您不想使用 DecimalFormat (例如由于其效率)并且想要一个通用的解决方案,您也可以尝试这种使用缩放舍入的方法:
If you do not want to use DecimalFormat (e.g. due to its efficiency) and you want a general solution, you could also try this method that uses scaled rounding: