Поиск абсолютного значения числа без использования 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.