我知道这个问题有很多重复,但请先看看声明,然后再说明已经回答:)
为了截断双精度值2个小数位,我使用了两种方法,这些方法大多数都是在任何地方提到的。它们在下面给出
//this one
DecimalFormat dtime = new DecimalFormat("#.##");
return Double.valueOf(dtime.format(val));
//or the one below
BigDecimal bd = new BigDecimal(val);
BigDecimal rounded = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
return rounded.doubleValue();
问题在于,对于这两种方式,我主要在数据集中获得正确的舍入值。但奇怪的是,同时我获得的值为2.00000000000005或19.97999999999。
我没有得到的问题是为什么只有少数几个值没有被舍入。可能有什么不对?
答案 0 :(得分:2)
为了截断双精度值2个小数位,我使用了两种方法,这些方法大多数都是在任何地方提到的。
他们都错了,因为他们正在尝试不可能的事情。 没有这样的东西将截断到2个小数位的两倍,因为双倍的具有小数位。他们有二进制位置。有关证据,请参阅my answer here。如果你想要小数位,你必须使用十进制基数,即BigDecimal
或DecimalFormat
。
答案 1 :(得分:0)
问题是浮点数本质上是近似的,给定底层表示。因此,您会希望在近似值良好的地方使用它们,并在近似值不佳的地方避免它们(例如财务)。
对rounded.doubleValue()
的调用仍会返回一个浮点数,因此它仍然受到表示限制的影响。
见
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
了解更多信息。
答案 2 :(得分:0)
以下代码段帮助我限制了双精度值的小数位数(截断)。
public static Double truncate (double valueToTruncate, int numberOfDecimalPlaces) {
if (valueToTruncate > 0) {
return new BigDecimal(String.valueOf(valueToTruncate)).setScale(numberOfDecimalPlaces, BigDecimal.ROUND_FLOOR).doubleValue();
} else {
return new BigDecimal(String.valueOf(valueToTruncate)).setScale(numberOfDecimalPlaces, BigDecimal.ROUND_CEILING).doubleValue();
}
}
希望这对某人有帮助:)
答案 3 :(得分:-1)
我是新手,但把一切都放在我面前我是这样做的。现在请注意,这是一个数学截断,除了在每行之后的调试中,我不会转换为字符串。
它不优雅但似乎有效。这纯粹是一个解决问题的框架。
反正;
import java.util.Scanner;
public class TestConstructs
{
private static double w;
private static int w1;
private static double w2;
private static double w3;
private static int w4;
private static double w5;
private static double w6;
public static void main(String[] args)
{
// TODO Auto-generated method stub
TestConstructs foo = new TestConstructs();
foo.setWage(w);
}
public void setWage(double w)
{
Scanner input = new Scanner(System.in);
System.out.println("Enter Wage: "); //enter something longish like 30987.978654 or w/e
w = input.nextDouble();
w1 = (int)w;
System.out.printf("%d w1\n",w1);
w2 = w - w1;
System.out.printf("%.3f w2\n",w2);
w3 = w2*100;
System.out.printf("%.3f w3\n",w3);
w4 = (int)w3;
System.out.printf("%d w4\n",w4);
w5 = (double)w4;
System.out.printf("%.3f w5\n",w5);
w6 = 0 + w5/100;
System.out.printf("%.3f w6\n",w6);
w = w1 + w6;
System.out.printf("%.3f final value\n",w); //.3 to show zero
input.close();
}
}
我最后得到了什么 输入工资: 30987.978654 30987 w1 0.979 w2 97.865 w3 97 w4 97.000 w5 0.970 w6 30987.970最终价值