在不使用Math.abs()的情况下查找数字的绝对值

时间:2012-06-13 10:42:53

标签: java number-formatting absolute-value

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

10 个答案:

答案 0 :(得分:54)

如果您查看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;
    }

答案 1 :(得分:19)

是:

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

对于整数,这工作正常(Integer.MIN_VALUE除外,其绝对值不能表示为int)。

对于浮点数,事情更加微妙。例如,此方法 - 以及迄今为止发布的所有其他方法 - 无法正确处理negative zero

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

答案 2 :(得分:13)

像这样:

if (number < 0) {
    number *= -1;
}

答案 3 :(得分:5)

由于Java是一种静态类型语言,我希望一个带有int的abs方法返回一个int,如果它期望一个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));
}

我抓住了第一个异常并让它进入第二个异常,只是为了演示。

编程中存在一个坏习惯,即程序员比正确的代码要快得多。真可惜!


如果你很好奇为什么还有一个负值而不是正值,我有一个diagram for you

答案 4 :(得分:2)

虽然这不应该是一个瓶颈,因为现代处理器上的分支问题通常不是问题,但在整数的情况下,你可以选择这里概述的无分支解决方案:{{ 3}}

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

但是在Integer.MIN_VALUE的明显情况下,这确实失败了,所以这是一个自行风险解决方案。

答案 5 :(得分:1)

使用数学类

Math.abs(num);

答案 6 :(得分:0)

您可以使用:

abs_num = (num < 0) ? -num : num;

答案 7 :(得分:0)

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

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

答案 8 :(得分:0)

-num将等于Integer.MIN_VALUE的num作为

 Integer.MIN_VALUE =  Integer.MIN_VALUE * -1

答案 9 :(得分:0)

如果不使用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而导致溢出。