1

私はここである種の非常にばかげた間違いを犯したと確信しています。私はこのコードを持っています:

private static String generateRAM()
{
    final long RAM_TOTAL = Runtime.getRuntime().totalMemory();
    final long RAM_FREE = Runtime.getRuntime().freeMemory();
    final long RAM_USED = RAM_TOTAL - RAM_FREE;
    final long RAM_TOTAL_MB = RAM_TOTAL / 8 / 1024;
    final long RAM_FREE_MB = RAM_FREE / 8 / 1024;
    final long RAM_USED_MB = RAM_USED / 8 / 1024;
    final double RAM_USED_PERCENTAGE = (RAM_USED / RAM_TOTAL) * 100;
    return RAM_TOTAL_MB + "MB TOTAL / " + RAM_FREE_MB + "MB FREE / " + RAM_USED_MB + "MB USED (" + RAM_USED_PERCENTAGE + "%)"; 
}

これは以下を返します:

15440MB TOTAL / 11809MB FREE / 3630MB USED (0.0%)

パーセンテージは明らかに間違っています。これはどのように起こりますか?私は、私の知る限り、すべての計算を正しく行っています。与えられた数字を電卓に打ち込んでパーセンテージを自分で見つけると、23.5 という私の期待される結果が得られます。

私は自分自身を蹴る恐ろしい間違いを犯したと確信しています.誰かが私を啓発してくれますか?

4

3 に答える 3

3
final double RAM_USED_PERCENTAGE = (RAM_USED / RAM_TOTAL) * 100;

整数除算だからです。タイプの 1 つをダブルにキャストします。

例:

final double RAM_USED_PERCENTAGE = ((double)RAM_USED / RAM_TOTAL) * 100;

JLS 15.17.2 による部門オペレーター /

整数除算は 0 に向かって丸められます。つまり、2 進数値昇格 (§5.6.2) 後の整数であるオペランド n と d に対して生成される商は、|d · q| を満たしながら、その大きさができるだけ大きい整数値 q です。≤ |n|。また、|n| の場合、q は正です。≥ |d| n と d は同じ符号ですが、|n| の場合、q は負です。≥ |d| n と d の符号は反対です。

この規則を満たさない特殊なケースが 1 つあります。被除数がその型で可能な最大の大きさの負の整数で、除数が -1 の場合、整数オーバーフローが発生し、結果は被除数と等しくなります。この場合、オーバーフローがあっても例外はスローされません。一方、整数除算の除数の値が 0 の場合、ArithmeticException がスローされます。

于 2013-01-25T20:32:11.773 に答える
1

2つのエラーがあります。freeMemory()そしてtotalMemory()バイト数を返すので、MBに変換するには、1024(kBとMB)で2回、次に8で除算する必要があります。さらに、これを浮動小数点として計算するには、RAM_USEDをdoubleに変換する必要があります。ポイント操作:

private static String generateRAM()
{
    final long RAM_TOTAL = Runtime.getRuntime().totalMemory();
    final long RAM_FREE = Runtime.getRuntime().freeMemory();
    final long RAM_USED = RAM_TOTAL - RAM_FREE;
    final long RAM_TOTAL_MB = RAM_TOTAL / 1024 / 1024;
    final long RAM_FREE_MB = RAM_FREE  / 1024 / 1024;
    final long RAM_USED_MB = (double) RAM_USED / 1024 / 1024;
    final double RAM_USED_PERCENTAGE = ((double) RAM_USED / RAM_TOTAL) * 100;
    return RAM_TOTAL_MB + "MB TOTAL / " + RAM_FREE_MB + "MB FREE / " + RAM_USED_MB + "MB USED (" + RAM_USED_PERCENTAGE + "%)";
}

これは次を返します:

10MB TOTAL / 9MB FREE / 0MB USED (2.47130735892926%)
于 2013-01-25T20:36:17.703 に答える
1

この行を変更

final double RAM_USED_PERCENTAGE = (RAM_USED / RAM_TOTAL) * 100;

final double RAM_USED_PERCENTAGE = ((RAM_USED * 1.0) / RAM_TOTAL) * 100;

これは、Java が結果をlong/long除算として解釈するためです。したがって、結果はlong値、つまり 5 / 10 => 0 になります。オペランドのいずれかに係数 1.0 を適用することにより、コンパイラはdouble/long演算を実行します。値になりdoubleます。

于 2013-01-25T20:32:00.703 に答える