21

有没有办法在不使用 java 中的 Math.abs() 方法的情况下找到数字的绝对值。

4

10 回答 10

59

如果您查看 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;
    }
于 2012-06-13T11:00:12.193 回答
20

是的:

abs_number = (number < 0) ? -number : number;

对于整数,这很好用(除了Integer.MIN_VALUE,其绝对值不能表示为int)。

对于浮点数,事情就更微妙了。例如,此方法——以及迄今为止发布的所有其他方法——将无法正确处理负零

为了避免自己处理这些微妙之处,我的建议是坚持使用Math.abs().

于 2012-06-13T10:44:26.910 回答
13

像这样:

if (number < 0) {
    number *= -1;
}
于 2012-06-13T10:44:03.383 回答
5

由于 Java 是一种静态类型的语言,我希望采用 int 的 abs 方法返回一个 int,如果它期望一个 float 返回一个 float,对于一个 Double,返回一个 Double。也许它可以总是为双打和双打等返回装箱或未装箱的类型。

因此,每种类型都需要一个方法,但现在出现了一个新问题:对于 byte、short、int、long,负值的范围比正值的范围大 1。

那么该方法应该返回什么

byte abs (byte in) {
   // @todo
}

如果用户在 -128 上调用 abs?您总是可以返回下一个更大的类型,以保证范围适合所有可能的输入值。这将长期导致问题,其中不存在正常的更大类型,并使用户在测试后总是降低值 - 可能很麻烦。

第二个选项是抛出一个算术异常。这将防止在已知输入受限的情况下强制转换和检查返回类型,这样 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));
}

我捕获了第一个异常并让它运行到第二个,只是为了演示。

编程中有一个坏习惯,那就是程序员更关心快速而不是正确的代码。太遗憾了!


如果你好奇为什么负值比正值多一个,我有一张图表给你

于 2012-06-13T13:01:13.603 回答
2

虽然这不应该是一个瓶颈,因为现代处理器上的分支问题通常不是问题,但对于整数,您可以使用此处概述的无分支解决方案:http: //graphics.stanford.edu /~seander/bithacks.html#IntegerAbs

(x + (x >> 31)) ^ (x >> 31);

但是,在明显的 Integer.MIN_VALUE 情况下,这确实会失败,因此这是一种使用风险自负的解决方案。

于 2016-04-01T16:31:18.053 回答
1

如果整数 x 的绝对值不使用 Math.abs()、条件或按位运算,以下可能是 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 会导致溢出。

于 2017-08-31T15:56:16.323 回答
0

您可以使用 :

abs_num = (num < 0) ? -num : num;
于 2012-06-13T10:45:21.633 回答
0

这是一个返回数字绝对值的单行解决方案:

abs_number = (num < 0) ? -num : num;
于 2012-06-13T10:47:48.207 回答
0

-num 将等于 Integer.MIN_VALUE 的 num 为

 Integer.MIN_VALUE =  Integer.MIN_VALUE * -1
于 2014-08-07T13:47:27.963 回答
0

使用数学类

Math.abs(num);
于 2014-08-19T14:31:19.113 回答