JavaでMath.abs()メソッドを使用せずに数値の絶対値を見つける方法はありますか?
10 に答える
Math.abs の中を見ると、おそらく最良の答えを見つけることができます。
たとえば、フロートの場合:
/*
* Returns the absolute value of a {@code float} value.
* If the argument is not negative, the argument is returned.
* If the argument is negative, the negation of the argument is returned.
* Special cases:
* <ul><li>If the argument is positive zero or negative zero, the
* result is positive zero.
* <li>If the argument is infinite, the result is positive infinity.
* <li>If the argument is NaN, the result is NaN.</ul>
* In other words, the result is the same as the value of the expression:
* <p>{@code Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))}
*
* @param a the argument whose absolute value is to be determined
* @return the absolute value of the argument.
*/
public static float abs(float a) {
return (a <= 0.0F) ? 0.0F - a : a;
}
はい:
abs_number = (number < 0) ? -number : number;
Integer.MIN_VALUE
整数の場合、これは正常に機能します(絶対値をとして表すことができない、を除くint
)。
浮動小数点数の場合、状況はより微妙です。たとえば、このメソッド(およびこれまでに投稿された他のすべてのメソッド)は、負のゼロを正しく処理しません。
そのような微妙なことに自分で対処する必要を避けるために、私のアドバイスはに固執することMath.abs()
です。
このような:
if (number < 0) {
number *= -1;
}
Javaは静的に型付けされた言語であるため、intを受け取るabs-methodはintを返し、floatがfloatを返すことを期待している場合は、Doubleの場合はDoubleを返します。たぶん、doublesやDoublesなどの場合は常にボックス化または非ボックス化タイプを返す可能性があります。
したがって、型ごとに1つのメソッドが必要ですが、新しい問題が発生します。byte、short、int、longの場合、負の値の範囲は正の値の場合より1大きくなります。
したがって、メソッドに対して何を返す必要がありますか
byte abs (byte in) {
// @todo
}
ユーザーが-128でabsを呼び出した場合はどうなりますか?範囲がすべての可能な入力値に適合することが保証されるように、いつでも次に大きいタイプを返すことができます。これは、通常のより大きなタイプが存在しない長い間問題を引き起こし、ユーザーがテスト後に常に値をキャストするようにします-おそらく面倒です。
2番目のオプションは、算術例外をスローすることです。これにより、X.MIN_VALUEが発生しないなど、入力が制限されていることがわかっている状況での戻りタイプのキャストとチェックが防止されます。intとして表されるMONTHについて考えてみてください。
byte abs (byte in) throws ArithmeticException {
if (in == Byte.MIN_VALUE) throw new ArithmeticException ("abs called on Byte.MIN_VALUE");
return (in < 0) ? (byte) -in : in;
}
「MIN_VALUEのまれなケースを無視しましょう」という習慣は選択肢ではありません。最初にコードを機能させ、次に高速化します。ユーザーがより高速でバグのあるソリューションを必要とする場合は、自分で作成する必要があります。うまくいく可能性のある最も単純な解決策は、単純ですが、単純すぎないことを意味します。
コードは状態に依存しないため、メソッドは静的にすることができ、静的にする必要があります。これにより、簡単なテストが可能になります。
public static void main (String args []) {
System.out.println (abs(new Byte ( "7")));
System.out.println (abs(new Byte ("-7")));
System.out.println (abs((byte) 7));
System.out.println (abs((byte) -7));
System.out.println (abs(new Byte ( "127")));
try
{
System.out.println (abs(new Byte ("-128")));
}
catch (ArithmeticException ae)
{
System.out.println ("Integer: " + Math.abs (new Integer ("-128")));
}
System.out.println (abs((byte) 127));
System.out.println (abs((byte) -128));
}
デモンストレーションのために、最初の例外をキャッチして2番目の例外に遭遇させます。
プログラミングには悪い習慣があります。それは、プログラマーが正しいコードよりも高速を重視することです。お気の毒に!
正の値よりも負の値が1つ多い理由に興味がある場合は、図を示します。
Math.abs()、条件、またはビット単位の操作を使用しない整数 x の絶対値の場合、以下が Java で可能な解決策になる可能性があります。
(int)(((long)x*x - 1)%(double)x + 1);
Java はa%b
として扱うためa - a/b * b
、"b" の符号が何であっても、結果の符号は "a" と同じになります。(x*x-1)%x
に等しくなりabs(x)-1
ます。「long」の型キャストは、オーバーフローを防ぎdouble
、ゼロ除算を可能にするためのものです。
この場合も、x = Integer.MIN_VALUE
1 を減算するためオーバーフローが発生します。
あなたが使用することができます:
abs_num = (num < 0) ? -num : num;
以下は、数値の絶対値を返す 1 行のソリューションです。
abs_number = (num < 0) ? -num : num;
クラス Math を使用する
Math.abs(num);