Java:组合函数产生十进制数

时间:2013-02-14 04:21:03

标签: java double combinations

我试图实现一个简单的组合功能

private int combination(int n, int k)
{
    if(n>>1 < k)
        k = n - k;
    double mul = 1;
    for(int i=n+1-k;i<n+1;i++)
        mul *= i;
    for(int i=k;i>0;i--)
        mul /= i;
    return (int)mul;
}

当我将参数作为combination(33,17)输入时,它会给我 1166803109 ,但正确的数字应为 1166803110 。所以我在截断到int之前打印出mul变量,它给了我一个十进制数: 1.1668031099999998E9 ,这让我很困惑。根据定义,它应该是一个完美的分区,为什么它给我一个小数?

2 个答案:

答案 0 :(得分:2)

当谈到像floatdouble这样的浮点类型时,很少有完美的除法(在浮点结果是整数的意义上是完美的)。这是因为值在内部表示的方式;执行计算时会有一些精度损失。 (这类似于计算机将2/3划分为0.666667的原因。)而不是使用double,而是坚持使用int或{{1}等整数类型如果您的计算可能达到大于long可以容纳的值,请使用BigInteger或类似内容。

答案 1 :(得分:1)

由于internal representation,浮点运算并不完全准确。

由于您只对结果的整数表示感兴趣,因此可以使用Math.round()

对双精度数进行舍入,而不是截断

你的方法应该是这样的:

private int combination(int n, int k)
{
    if(n>>1 < k)
        k = n - k;
    double mul = 1;
    for(int i=n+1-k;i<n+1;i++)
        mul *= i;
    for(int i=k;i>0;i--)
        mul /= i;
    return (int) Math.round(mul);
}

输出:

System.out.println(combination(33,17));

1166803110