Finding absolute value of a number without using Math.abs()

坚强是说给别人听的谎言 提交于 2020-11-30 04:57:07

问题


Is there any way to find the absolute value of a number without using the Math.abs() method in java.


回答1:


If you look inside Math.abs you can probably find the best answer:

Eg, for floats:

    /*
     * 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:


Yes:

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

For integers, this works fine (except for Integer.MIN_VALUE, whose absolute value cannot be represented as an int).

For floating-point numbers, things are more subtle. For example, this method -- and all other methods posted thus far -- won't handle the negative zero correctly.

To avoid having to deal with such subtleties yourself, my advice would be to stick to Math.abs().




回答3:


Like this:

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



回答4:


Since Java is a statically typed language, I would expect that a abs-method which takes an int returns an int, if it expects a float returns a float, for a Double, return a Double. Maybe it could return always the boxed or unboxed type for doubles and Doubles and so on.

So you need one method per type, but now you have a new problem: For byte, short, int, long the range for negative values is 1 bigger than for positive values.

So what should be returned for the method

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

If the user calls abs on -128? You could always return the next bigger type so that the range is guaranteed to fit to all possible input values. This will lead to problems for long, where no normal bigger type exists, and make the user always cast the value down after testing - maybe a hassle.

The second option is to throw an arithmetic exception. This will prevent casting and checking the return type for situations where the input is known to be limited, such that X.MIN_VALUE can't happen. Think of MONTH, represented as 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; 
}

The "let's ignore the rare cases of MIN_VALUE" habit is not an option. First make the code work - then make it fast. If the user needs a faster, but buggy solution, he should write it himself. The simplest solution that might work means: simple, but not too simple.

Since the code doesn't rely on state, the method can and should be made static. This allows for a quick test:

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));
}

I catch the first exception and let it run into the second, just for demonstration.

There is a bad habit in programming, which is that programmers care much more for fast than for correct code. What a pity!


If you're curious why there is one more negative than positive value, I have a diagram for you.




回答5:


Although this shouldn't be a bottle neck as branching issues on modern processors isn't normally a problem, but in the case of integers you could go for a branch-less solution as outlined here: http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs.

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

This does fail in the obvious case of Integer.MIN_VALUE however, so this is a use at your own risk solution.




回答6:


You can use :

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



回答7:


Here is a one-line solution that will return the absolute value of a number:

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



回答8:


-num will equal to num for Integer.MIN_VALUE as

 Integer.MIN_VALUE =  Integer.MIN_VALUE * -1



回答9:


Use the class Math

Math.abs(num);



回答10:


In case of the absolute value of an integer x without using Math.abs(), conditions or bit-wise operations, below could be a possible solution in Java.

(int)(((long)x*x - 1)%(double)x + 1);

Because Java treats a%b as a - a/b * b, the sign of the result will be same as "a" no matter what sign of "b" is; (x*x-1)%x will equal abs(x)-1; type casting of "long" is to prevent overflow and double allows dividing by zero.

Again, x = Integer.MIN_VALUE will cause overflow due to subtracting 1.



来源:https://stackoverflow.com/questions/11013187/finding-absolute-value-of-a-number-without-using-math-abs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!