14

私は2つの非負のロングを持っています。それらは大きく、Long.MAX_VALUEに近い場合があります。2つの数値からパーセンテージを計算したいと思います。

通常、私はこれを行います:

    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に対して2桁以内の場合、これは正しくありません。

これを行うための正しく、簡単で、速い方法は何ですか?

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);

a を a で割るlongと alongが得られますが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計算を行う前に両方を変換することですが、精度がわずかに低下します。代替案と比較して、それも遅いです。

1つの代替方法は、各値を2つの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);

  }
}

代わりは?つまり、除算の前に分子を大きくする代わりに、分母を小さくします。(n * 100) / d分母が大きいことがわかっているので、除算で 0 になるリスクはありません。これが、浮動小数点数を使用していないときに通常書き込む理由です。

于 2012-05-02T14:47:32.583 に答える