14

我有两个非负多头。它们可能很大,接近 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 的两个数量级内,则这是不正确的。

什么是正确、简单和快速的方法?

4

5 回答 5

16

我会使用:

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

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

于 2012-05-02T14:19:24.403 回答
7
int percentage = (int) (0.5d + ((double)numerator/(double)denominator) * 100);

如果您将 along与 a相除,long您将得到 a long,这对百分比不利。

于 2012-05-02T14:18:11.473 回答
3

伙计们按照以下方式实现,因为建议使用 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);
于 2012-05-02T14:56:48.003 回答
2

float最简单的方法是在进行计算之前或之前都进行转换double,代价是精度略有下降。与替代品相比,它也很慢。

一种替代方法是将每个值拆分为两个 32 位分量,然后进行长乘和长除。

于 2012-05-02T14:19:14.427 回答
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在不使用浮点数时编写的原因。

于 2012-05-02T14:47:32.583 回答