How to determine if a number is positive or negative?

I was asked in an interview how to determine if a number is positive or negative. The rules are that we should not use conditional statements such as < and > built into java functions (e.g. substring , indexOf , charAt and startsWith )) without a regular expression or API.

I did some homework and the code is below, but it only works for the integer type. But they asked me to write common code that works for float , double and long .

  // This might not be better way!! SOP ((( number >> 31 ) & 1) == 1 ? "- ve number " : "+ve number ); 

any ideas on your part?

+55
java numbers
Oct 22 '10 at 6:48
source share
34 answers
  • one
  • 2

Entire cases are easy. The double case is more difficult until you think of infinity.

Note. If you are considering double constants "part of the api", you can replace them with overflow expressions, for example 1E308 * 2 .

 int sign(int i) { if (i == 0) return 0; if (i >> 31 != 0) return -1; return +1; } int sign(long i) { if (i == 0) return 0; if (i >> 63 != 0) return -1; return +1; } int sign(double f) { if (f != f) throw new IllegalArgumentException("NaN"); if (f == 0) return 0; f *= Double.POSITIVE_INFINITY; if (f == Double.POSITIVE_INFINITY) return +1; if (f == Double.NEGATIVE_INFINITY) return -1; //this should never be reached, but I've been wrong before... throw new IllegalArgumentException("Unfathomed double"); } 
+64
Oct 22 '10 at 13:10
source share

Below is a terrible approach that will force you to fire any job ...

It depends on whether you get an exception [or something that Java throws it] ... And this will only work for positive numbers that do not deviate from 0 like crazy.

Negative numbers are fine since you would overflow the positive values ​​and then get an exception at the end [which will return false or “yes, this is negative”]

 Boolean isPositive<T>(T a) { if(a == 0) return true; else { try { return isPositive(a-1); }catch(StackOverflowException e) { return false; //It went way down there and eventually went kaboom } } } 
+35
Oct 22 '10 at 7:14
source share

This will only work for everyone except [0..2]

 boolean isPositive = (n % (n - 1)) * n == n; 

You can make a better solution like this (works except for [0..1])

 boolean isPositive = ((n % (n - 0.5)) * n) / 0.5 == n; 

You can get better accuracy by changing the 0.5 part with something like 2 ^ m (m integer):

 boolean isPositive = ((n % (n - 0.03125)) * n) / 0.03125 == n; 
+17
Oct 22 '10 at 7:57
source share

You can do something like this:

 ((long) (num * 1E308 * 1E308) >> 63) == 0 ? "+ve" : "-ve" 

The main idea here is that we drop to the end and check the value of the most significant bit. Since a double / float between -1 and 0 will be rounded to zero when clicking on a long one, we multiply by large doubles so that the negative float / double is less than -1. Two multiplications are required due to the existence of subnormal values (in fact this is not necessarily so important).

+8
Oct 22 '10 at 7:20
source share

How about this?

 return ((num + "").charAt(0) == '-'); 
+4
Oct 22 '10 at 7:44
source share
 // Returns 0 if positive, nonzero if negative public long sign(long value) { return value & 0x8000000000000000L; } 

Call:

 long val1 = ...; double val2 = ...; float val3 = ...; int val4 = ...; sign((long) valN); 

Casting from double / float / integer to long should retain the sign, if not the actual value ...

+3
Oct 22 '10 at 7:25
source share

You speak

we should not use conditional statements

But this is a trick, because == also a conditional statement. ? : there also one built-in loop ? : ? : , while and for . Therefore, almost everyone could not give an answer that meets all the requirements.

The only way to build a solution without a conditional operator is to use a lookup table compared to one of several other solutions for people, which can be reduced to 0/1 or a character before the condition is met.

Here are the answers that I think might work against the lookup table:

  • Nabb
  • Steven slansker
  • Dennis Chung
  • Gary rowe
+3
Oct 25 '10 at 9:17
source share

This solution uses a module. And yes, this also works for 0.5 (tests below, in the main method).

 public class Num { public static int sign(long x) { if (x == 0L || x == 1L) return (int) x; return x == Long.MIN_VALUE || x % (x - 1L) == x ? -1 : 1; } public static int sign(double x) { if (x != x) throw new IllegalArgumentException("NaN"); if (x == 0.d || x == 1.d) return (int) x; if (x == Double.POSITIVE_INFINITY) return 1; if (x == Double.NEGATIVE_INFINITY) return -1; return x % (x - 1.d) == x ? -1 : 1; } public static int sign(int x) { return Num.sign((long)x); } public static int sign(float x) { return Num.sign((double)x); } public static void main(String args[]) { System.out.println(Num.sign(Integer.MAX_VALUE)); // 1 System.out.println(Num.sign(1)); // 1 System.out.println(Num.sign(0)); // 0 System.out.println(Num.sign(-1)); // -1 System.out.println(Num.sign(Integer.MIN_VALUE)); // -1 System.out.println(Num.sign(Long.MAX_VALUE)); // 1 System.out.println(Num.sign(1L)); // 1 System.out.println(Num.sign(0L)); // 0 System.out.println(Num.sign(-1L)); // -1 System.out.println(Num.sign(Long.MIN_VALUE)); // -1 System.out.println(Num.sign(Double.POSITIVE_INFINITY)); // 1 System.out.println(Num.sign(Double.MAX_VALUE)); // 1 System.out.println(Num.sign(0.5d)); // 1 System.out.println(Num.sign(0.d)); // 0 System.out.println(Num.sign(-0.5d)); // -1 System.out.println(Num.sign(Double.MIN_VALUE)); // -1 System.out.println(Num.sign(Double.NEGATIVE_INFINITY)); // -1 System.out.println(Num.sign(Float.POSITIVE_INFINITY)); // 1 System.out.println(Num.sign(Float.MAX_VALUE)); // 1 System.out.println(Num.sign(0.5f)); // 1 System.out.println(Num.sign(0.f)); // 0 System.out.println(Num.sign(-0.5f)); // -1 System.out.println(Num.sign(Float.MIN_VALUE)); // -1 System.out.println(Num.sign(Float.NEGATIVE_INFINITY)); // -1 System.out.println(Num.sign(Float.NaN)); // Throws an exception } } 
+2
Nov 17 '10 at 21:47
source share

This code covers all cases and types:

 public static boolean isNegative(Number number) { return (Double.doubleToLongBits(number.doubleValue()) & Long.MIN_VALUE) == Long.MIN_VALUE; } 

This method accepts any of the wrapper classes ( Integer , Long , Float and Double ) and, thanks to the automatic boxing of any of the primitive numeric types ( int , Long , Float and Double ), it simply checks its high bit, which is a signed bit in all types.

It returns true when passing any of the following values:

  • any negative int / Integer
  • any negative Long / Long
  • any negative Float / Float
  • any negative Double / Double
  • Double.NEGATIVE_INFINITY
  • Float.NEGATIVE_INFINITY

and false otherwise.

+2
Aug 04 '15 at 16:00
source share

Unconfirmed, but illustrating my idea:

 boolean IsNegative<T>(T v) { return (v & ((T)-1)); } 
+1
22 Oct. '10 at 6:56
source share

It seems arbitrary to me because I don’t know how you would get a number like any type, but what about checking Abs (number)! = Number? May be && number! = 0

+1
Oct 22 '10 at 8:05
source share

Whole are trivial; you already know that. The deep problem is how to deal with floating point values. At this point, you will learn a little more about how floating point values ​​really work.

The key is Double.doubleToLongBits () , which allows you to get an IEEE representation of this number. (The method is really straight under the hood, with a bit of magic for working with NaN values.) Once the double has been converted to a long one, you can simply use 0x8000000000000000L as a mask to select the sign bit; if zero, the value is positive, and if it is negative.

+1
Oct 22 '10 at 8:17
source share

one more option that I could come up with

 private static boolean isPositive(Object numberObject) { Long number = Long.valueOf(numberObject.toString()); return Math.sqrt((number * number)) != number; } private static boolean isPositive(Object numberObject) { Long number = Long.valueOf(numberObject.toString()); long signedLeftShifteredNumber = number << 1; // Signed left shift long unsignedRightShifterNumber = signedLeftShifteredNumber >>> 1; // Unsigned right shift return unsignedRightShifterNumber == number; } 
+1
Oct 22 2018-10-10T00:
source share

If this is a valid answer

 boolean IsNegative(char[] v) throws NullPointerException, ArrayIndexOutOfBoundException { return v[0]=='-'; } 
+1
Oct 22 '10 at 9:19
source share

This example is based on ItzWarty's answer, but it works during login! Caveat: only works for integers.

 Boolean isPositive(int a) { if(a == -1) return false; if(a == 0) return false; if(a == 1) return true; return isPositive(a/2); } 
+1
Oct 22 '10 at 19:59
source share

I think there is a very simple solution:

 public boolean isPositive(int|float|double|long i){ return (((ii)==0)? true : false); } 

Tell me if I'm wrong!

+1
Oct 23 '10 at 10:57
source share

Try this without code: (x-SQRT(x^2))/(2*x)

+1
Aug 04 2018-11-11T00: 00Z
source share

Write it using a conditional expression, then look at the generated assembly code.

0
Oct 22 '10 at 6:55
source share

Why not get the square root of the number? If its negative - java will throw an error, and we will deal with it.

  try { d = Math.sqrt(THE_NUMBER); } catch ( ArithmeticException e ) { console.putln("Number is negative."); } 
0
Oct 22 '10 at 8:19
source share

Well, using casting (since we don't care what the real value is), perhaps the following will work. Keep in mind that actual implementations do not violate API rules. I edited this to make the method names more obvious in the light of @chris's comment on the problem domain {-1, + 1}. In fact, this problem cannot be resolved without using the API methods in Float or Double, which refer to the native bit structure of float and double primitives.

As everyone said: a stupid interview question. Grr.

 public class SignDemo { public static boolean isNegative(byte x) { return (( x >> 7 ) & 1) == 1; } public static boolean isNegative(short x) { return (( x >> 15 ) & 1) == 1; } public static boolean isNegative(int x) { return (( x >> 31 ) & 1) == 1; } public static boolean isNegative(long x) { return (( x >> 63 ) & 1) == 1; } public static boolean isNegative(float x) { return isNegative((int)x); } public static boolean isNegative(double x) { return isNegative((long)x); } public static void main(String[] args) { // byte System.out.printf("Byte %b%n",isNegative((byte)1)); System.out.printf("Byte %b%n",isNegative((byte)-1)); // short System.out.printf("Short %b%n",isNegative((short)1)); System.out.printf("Short %b%n",isNegative((short)-1)); // int System.out.printf("Int %b%n",isNegative(1)); System.out.printf("Int %b%n",isNegative(-1)); // long System.out.printf("Long %b%n",isNegative(1L)); System.out.printf("Long %b%n",isNegative(-1L)); // float System.out.printf("Float %b%n",isNegative(Float.MAX_VALUE)); System.out.printf("Float %b%n",isNegative(Float.NEGATIVE_INFINITY)); // double System.out.printf("Double %b%n",isNegative(Double.MAX_VALUE)); System.out.printf("Double %b%n",isNegative(Double.NEGATIVE_INFINITY)); // interesting cases // This will fail because we can't get to the float bits without an API and // casting will round to zero System.out.printf("{-1,1} (fail) %b%n",isNegative(-0.5f)); } } 
0
Oct 22 '10 at 12:48
source share

I don’t know exactly how Java coerces numeric values, but the answer is quite simple if put in pseudo-code (I leave the details for you):

 sign(x) := (x == 0) ? 0 : (x/x) 
0
Oct 22 2018-10-22
source share

If you are allowed to use "==" as it seems, you can do something like this, taking advantage of the fact that an exception will be raised if the array index goes out of bounds. The code is for deuce, but you can use any numeric type for double (here the final loss of accuracy will not be important at all).

I added comments to explain the process (add value to] -2.0; -1.0] union [1.0; 2.0 [) and a small test driver.

 class T { public static boolean positive(double f) { final boolean pos0[] = {true}; final boolean posn[] = {false, true}; if (f == 0.0) return true; while (true) { // If f is in ]-1.0; 1.0[, multiply it by 2 and restart. try { if (pos0[(int) f]) { f *= 2.0; continue; } } catch (Exception e) { } // If f is in ]-2.0; -1.0] U [1.0; 2.0[, return the proper answer. try { return posn[(int) ((f+1.5)/2)]; } catch (Exception e) { } // f is outside ]-2.0; 2.0[, divide by 2 and restart. f /= 2.0; } } static void check(double f) { System.out.println(f + " -> " + positive(f)); } public static void main(String args[]) { for (double i = -10.0; i <= 10.0; i++) check(i); check(-1e24); check(-1e-24); check(1e-24); check(1e24); } 

Output:

 -10.0 -> false -9.0 -> false -8.0 -> false -7.0 -> false -6.0 -> false -5.0 -> false -4.0 -> false -3.0 -> false -2.0 -> false -1.0 -> false 0.0 -> true 1.0 -> true 2.0 -> true 3.0 -> true 4.0 -> true 5.0 -> true 6.0 -> true 7.0 -> true 8.0 -> true 9.0 -> true 10.0 -> true -1.0E24 -> false -1.0E-24 -> false 1.0E-24 -> true 1.0E24 -> true 
0
Oct 22 '10 at 19:16
source share

Ineffective, but I think it doesn’t matter here: (I'm also a little rusty with Java, hopefully this is more or less the correct syntax.)

 boolean isPositive = false; int n = (int)(x * x); while (n-- != 0) { if ((int)(--x) == 0) { isPositive = true; break; } } 

This should work, because x will be decremented no more than x * x times (always a positive number), and if x never 0, then for starters it should be negative. If x , on the other hand, is 0 at some point, it should be behavioral.

Note that this will cause isPositive be false for 0.

PS: Admittedly, this will not work with very large numbers, since (int)(x * x) will overflow.

0
Oct 22 '10 at 20:32
source share

This solution does not use conditional statements, but relies on trapping two excrement.

A separation error means that the number was initially "negative". Alternatively, the number will eventually fall off the planet and throw a StackOverFlow exception if it is positive.

 public static boolean isPositive( f) { int x; try { x = 1/((int)f + 1); return isPositive(x+1); } catch (StackOverFlow Error e) { return true; } catch (Zero Division Error e) { return false; } } 
0
22 Oct. 2018-10-22
source share

What about the next one?

 T sign(T x) { if(x==0) return 0; return x/Math.abs(x); } 

Should work for every type of T ...

Alternatively, you can define abs (x) as Math.sqrt (x * x), and if that is also cheating, do your own square root function ...

0
Apr 01 2018-11-11T00:
source share
 if (((Double)calcYourDouble()).toString().contains("-")) doThis(); else doThat(); 
0
01 Oct '11 at 17:50
source share

Combined generics with dual API. Guess this is a bit of a hoax, but at least we need to write only one method:

 static <T extends Number> boolean isNegative(T number) { return ((number.doubleValue() * Double.POSITIVE_INFINITY) == Double.NEGATIVE_INFINITY); } 
0
Sep 12
source share

Two simple solutions. Also works for infinities and numbers -1 <= r <= 1 Returns "positive" for NaN.

 String positiveOrNegative(double number){ return (((int)(number/0.0))>>31 == 0)? "positive" : "negative"; } String positiveOrNegative(double number){ return (number==0 || ((int)(number-1.0))>>31==0)? "positive" : "negative"; } 
0
Nov 11 '13 at 6:07
source share
0
Sep 15 '14 at 18:13
source share

Easy to do, e.g.

 private static boolean isNeg(T l) { return (Math.abs(l-1)>Math.abs(l)); } 
0
Oct 21 '14 at 18:36
source share
  • one
  • 2



All Articles