Поиск абсолютного значения числа без использования Math.abs()
Есть ли способ найти абсолютное значение числа без использования метода Math.abs() в java.
Ответы
Ответ 1
Если вы заглянете в Math.abs, вы, вероятно, найдете лучший ответ:
Например, для float:
/*
* 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;
}
Ответ 2
Да:
abs_number = (number < 0) ? -number : number;
Для целых чисел это работает отлично (кроме Integer.MIN_VALUE
, абсолютное значение которого не может быть представлено как int
).
Для чисел с плавающей запятой вещи более тонкие. Например, этот метод и все другие методы, опубликованные до сих пор, не будут корректно обрабатывать отрицательный нуль.
Чтобы избежать необходимости иметь дело с такими тонкостями самостоятельно, я бы посоветовал придерживаться Math.abs()
.
Ответ 3
Вот так:
if (number < 0) {
number *= -1;
}
Ответ 4
Поскольку Java является статически типизированным языком, я бы ожидал, что абс-метод, который принимает int, возвращает int, если он ожидает, что float вернет float, для Double вернет Double. Возможно, он может всегда возвращать коробку или распакованный тип для парных и парных разрядов и так далее.
Итак, вам нужен один метод для каждого типа, но теперь у вас есть новая проблема: для байта, short, int, long диапазон для отрицательных значений на 1 больше, чем для положительных значений.
Итак, что должно быть возвращено для метода
byte abs (byte in) {
// @todo
}
Если пользователь называет abs на -128? Вы всегда можете вернуться к следующему большему типу, чтобы гарантировать, что диапазон будет соответствовать всем возможным входным значениям. Это приведет к возникновению проблем на долгое время, когда нет нормального большего типа, и заставить пользователя всегда отбрасывать значение после тестирования - может быть, хлопот.
Второй вариант - это выбросить арифметическое исключение. Это предотвратит кастинг и проверку типа возврата для ситуаций, когда известно, что вход ограничен, так что X.MIN_VALUE не может произойти. Подумайте о MONTH, представленном как int.
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));
}
Я поймаю первое исключение и позволю ему работать во втором, просто для демонстрации.
В программировании есть плохая привычка, которая заключается в том, что программисты заботятся гораздо быстрее, чем для правильного кода. Какая жалость!
Если вам интересно, почему есть еще одно отрицательное, чем положительное значение, у меня есть диаграмма для вас.
Ответ 5
Использовать класс Math
Math.abs(num);
Ответ 6
Хотя это не должно быть шеей бутылки, поскольку проблемы с ветвлением на современных процессорах обычно не являются проблемой, но в случае целых чисел вы можете использовать решение без ветвей, как описано здесь: http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs.
(x + (x >> 31)) ^ (x >> 31);
Это, однако, не работает в очевидном случае Integer.MIN_VALUE, поэтому это полезно для решения вашего собственного риска.
Ответ 7
Вы можете использовать:
abs_num = (num < 0) ? -num : num;
Ответ 8
Вот однострочное решение, которое вернет абсолютное значение числа:
abs_number = (num < 0) ? -num : num;
Ответ 9
-num будет равно num для Integer.MIN_VALUE как
Integer.MIN_VALUE = Integer.MIN_VALUE * -1
Ответ 10
В случае абсолютного значения целого x без использования Math.abs(), условия или бит-меры операции ниже могут быть возможным решением в Java.
(int)(((long)x*x - 1)%(double)x + 1);
Поскольку Java рассматривает a%b
как a - a/b * b
, знак результата будет таким же, как "a", независимо от того, какой знак "b"; (x*x-1)%x
будет равно abs(x)-1
; тип "длинный" - это предотвращение переполнения и double
позволяет делить на ноль.
Опять же, x = Integer.MIN_VALUE
вызовет переполнение из-за вычитания 1.