在Java中用两个长整数计算百分比的溢出安全方法

时间:2012-05-02 14:14:17

标签: java

我有两个非负长。它们可能很大,接近Long.MAX_VALUE。我想从两个数字中计算一个百分比。

通常我会这样做:

    long numerator = Long.MAX_VALUE / 3 * 2;
    long denominator = Long.MAX_VALUE;

    int percentage = (int) (numerator * 100 / denominator);
    System.out.println("percentage = " + percentage);

如果分子在Long.MAX_VALUE的两个数量级内,则这是不正确的。

这是一种正确,简单,快速的方法吗?

5 个答案:

答案 0 :(得分:12)

我会用:

int percentage = (int)(numerator * 100.0 / denominator + 0.5);

100.0强制从该点开始浮点运算,+ 0.5向最接近的整数舍入而不是截断。

答案 1 :(得分:7)

int percentage = (int) (0.5d + ((double)numerator/(double)denominator) * 100);

如果您将longlong分开,则会得到long,这对百分比不利。

答案 2 :(得分:2)

琐碎的方法是在进行计算之前将两者转换为floatdouble,代价是精度略有下降。与替代品相比,它也很慢。

另一种方法是将每个值拆分为两个32位组件,并进行长乘法和长除法。

答案 3 :(得分:2)

除非我遗漏了一些明显的东西,否则你只能写下:

public class round {
  public static void main(String[] argv) {
    long numerator = Long.MAX_VALUE / 3 * 2;
    long denominator = Long.MAX_VALUE;

    int percentage = (int) (numerator / (denominator / 100));
    System.out.println("percentage = " + percentage);

  }
}

代替?即不是在除法之前使分子更大,而是使分母更小。既然你知道分母很大,那么除法不会给出0,这就是你在不使用浮点数时通常写(n * 100) / d的原因。

答案 4 :(得分:1)

Guys以下列方式实现,因为建议使用BigDecimal和BigInteger进行计算。这是实施:

    BigDecimal n = new BigDecimal(Long.MAX_VALUE);
    BigDecimal d = new BigDecimal(Long.MAX_VALUE);
    BigDecimal i = new BigDecimal(100);
    int percentage = n.multiply(i).divide(d).intValue();
    System.out.println(percentage);