如何(1/3)* 3 = 1.00000000000000000000,是否从0.9999舍入......?
public static void main(String[] args) {
double numerator = 1.0;
double denominator = 3.0;
double result = numerator / denominator;
System.out.printf("1 / 3 = %f \n", result);
double multiplied = result * 3;
System.out.printf("3 * (1/3) = %.20f \n", multiplied);
System.out.format("%.14f", 1.0/3.0 * 3);
}
结果
1 / 3 = 0.333333
3 * (1/3) = 1.00000000000000000000
1.00000000000000
答案 0 :(得分:2)
就像1/3.0
无法用Java中的double精确表示一样,也无法准确表示3 * 1.0/3.0
。 可以准确地由double
表示的最接近的数字是1
。
你很幸运。
您可以使用Double.doubleToLongBits
将双精度的64位转换为长整数。这表明以下3个双表达式在double的位中具有相同的表示形式:
System.out.println(Double.doubleToLongBits(1.0 / 3.0 * 3));
System.out.println(Double.doubleToLongBits(1d));
System.out.println(Double.doubleToLongBits(0.99999999999999999d));
节目:
4607182418800017408
4607182418800017408
4607182418800017408
答案 1 :(得分:1)
我修改了你的程序以显示确切的值,没有输出舍入。 Set found = Range("A:A").Find(what:=DatetoRun, LookIn:=xlFormulas, lookat:=xlPart)
对于探究BigDecimal
的行为非常有用。
double
输出结果为:
import java.math.BigDecimal;
public class Test {
public static void main(String[] args) {
double numerator = 1.0;
double denominator = 3.0;
double result = numerator / denominator;
System.out.printf("1 / 3 = %s \n", new BigDecimal(result));
double multiplied = result * 3;
System.out.printf("3 * (1/3) = %s \n", new BigDecimal(multiplied));
BigDecimal exactMultiplied = new BigDecimal(result).multiply(new BigDecimal(3));
System.out.println(exactMultiplied);
BigDecimal upError = BigDecimal.ONE.subtract(exactMultiplied);
System.out.printf("Error on round up %s \n", upError);
BigDecimal downError = exactMultiplied.subtract(new BigDecimal(Math.nextDown(1.0)));
System.out.printf("Error on round down %s \n", downError);
}
}
乘以3的结果恰好是介于1.0和最大双倍之间的一半,小于1.0。在这种情况下,圆形到均匀的规则发挥作用。 1.0的有效数字的最低有效位为零,因此1.0就是答案。圆形到偶数规则确实倾向于支持整数和其他整数数字而不是邻居。
答案 2 :(得分:0)
0.333333已经四舍五入。
double存储在三个部分,sign,exponent和fraction
实际上,1/3存储为0x3FD5555555555555,不等于0.333333,而是3.33333333333333314829616256247E-1。
即使它已经四舍五入,它也足够准确,因此这个数字* 3等于1