Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何确定一个数字是正数还是负数?_Java_Numbers - Fatal编程技术网

Java 如何确定一个数字是正数还是负数?

Java 如何确定一个数字是正数还是负数?,java,numbers,Java,Numbers,我在一次采访中被问到,如何确定一个数字是正还是负。规则是,我们不应该使用关系运算符,如、内置java函数(如子字符串、indexOf、charAt和startsWith),不使用正则表达式或API 我做了一些家庭作业,下面给出了代码,但它只适用于整数类型。但是他们要求我编写一个通用代码,它适用于float、double和long // This might not be better way!! S.O.P ((( number >> 31 ) & 1) == 1 ?

我在一次采访中被问到,如何确定一个数字是正还是负。规则是,我们不应该使用关系运算符,如
、内置java函数(如
子字符串
indexOf
charAt
startsWith
),不使用正则表达式或API

我做了一些家庭作业,下面给出了代码,但它只适用于整数类型。但是他们要求我编写一个通用代码,它适用于
float
double
long

 // This might not be better way!!

 S.O.P ((( number >> 31 ) & 1) == 1 ? "- ve number " : "+ve number );

您有什么想法吗?

使用条件语句编写,然后查看生成的汇编代码。

未经测试,但说明了我的想法:

boolean IsNegative<T>(T v) {
  return (v & ((T)-1));
}
布尔值为负(tV){
返回(v&(T)-1);
}

以下是一种可怕的方法,会让你在任何工作中被解雇

这取决于您是否获得堆栈溢出异常[或Java如何调用它]。。。它只适用于不偏离0的正数

负数是可以的,因为您将溢出为正数,然后最终会得到堆栈溢出异常[这将返回false,或“yes,it is Negative”]

Boolean正(ta)
{
如果(a==0),则返回true;
其他的
{
尝试
{
返回为正(a-1);
}捕获(StackOverflowException e)
{
return false;//它一直在下面,最后变成了kaboom
}
}
}

您可以执行以下操作:

((long) (num * 1E308 * 1E308) >> 63) == 0 ? "+ve" : "-ve"
这里的主要思想是,我们将其转换为long并检查最高有效位的值。由于-1和0之间的double/float在转换为long时将舍入为零,因此我们将乘以大的double,这样负的float/double将小于-1。需要两次乘法,因为存在(虽然它实际上不需要那么大)

比如:

long val1 = ...;
double val2 = ...;
float val3 = ...;
int val4 = ...;

sign((long) valN);
从double/float/integer到long的转换应该保留符号,如果不是实际值…

这怎么办

return ((num + "").charAt(0) == '-');

这只适用于除[0..2]之外的所有对象

boolean isPositive = (n % (n - 1)) * n == n;
您可以制作这样的更好的解决方案(除[0..1]外都适用)

通过使用类似于2^m(m整数)的值更改0.5部分,可以获得更好的精度:


对我来说,这似乎是任意的,因为我不知道你将如何获得任何类型的数字,但是检查Abs(数字)怎么样号码?也许&&number!=0

整数是平凡的;这你已经知道了。深层次的问题是如何处理浮点值。在这一点上,您必须更多地了解浮点值实际上是如何工作的


关键是,它可以让您获得数字的IEEE表示形式。(该方法实际上是一种直接隐藏的方法,具有处理NaN值的一点魔力。)一旦将double转换为long,您就可以使用0x80000000000000L作为掩码来选择符号位;如果为零,则值为正;如果为一,则值为负。

为什么不求出数字的平方根?如果它是负数,java将抛出一个错误,我们将处理它

         try {
            d = Math.sqrt(THE_NUMBER);
         }
         catch ( ArithmeticException e ) {
            console.putln("Number is negative.");
         }

我还能想到一个选择

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;
}
private静态布尔值isPositive(Object numberObject){
Long number=Long.valueOf(numberObject.toString());
返回Math.sqrt((number*number))!=number;
}
私有静态布尔值isPositive(对象编号对象){
Long number=Long.valueOf(numberObject.toString());
long SIGNED LEFTSHIFTEREDNUMBER=number>>1;//无符号右移位
返回unsignedRightShifterNumber==number;
}

如果答案有效

boolean IsNegative(char[] v) throws NullPointerException, ArrayIndexOutOfBoundException
{ 
  return v[0]=='-'; 
} 

好吧,利用casting(因为我们不关心实际值是多少)也许下面的方法可以奏效。请记住,实际实现并不违反API规则。我对其进行了编辑,以使方法名称更加明显,并考虑到@chris对{-1,+1}问题域的评论。从本质上讲,如果不使用Float或Double中引用Float和Double原语的本机位结构的API方法,这个问题似乎是无法解决的

正如其他人所说:愚蠢的面试问题。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));

  }

}

整数的情况很简单。在你记起无穷大之前,双格法更为棘手

注意:如果考虑双常量“API的一部分”,可以用溢出的表达式替换它们,如“代码> 1E308* 2 < < /P>”。

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

我不知道Java到底是如何强制数值的,但答案很简单,如果放入伪代码(我把细节留给您):

如果您被允许使用“==”,那么您可以利用这样一个事实,即如果数组索引超出范围,将引发异常。代码用于double,但是您可以将任何数字类型转换为double(在这里,精度的最终损失根本不重要)

我添加了一些注释来解释这个过程(将值引入到-2.0;-1.0]union[1.0;2.0[)和一个小型测试驱动程序中

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

这一个大致基于伊兹瓦蒂的答案,但它在logn时间内运行!警告:只适用于整数

Boolean isPositive(int a)
{
  if(a == -1) return false;
  if(a == 0) return false;
  if(a == 1) return true;
  return isPositive(a/2);
}

此解决方案不使用条件运算符,但依赖于捕获两个例外

除法错误等于原来是“负数”的数字。或者,该数字最终会从行星上掉下来,如果是正数,则抛出StackOverFlow异常

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


   }

我认为有一个非常简单的解决方案:

public boolean isPositive(int|float|double|long i){
    return (((i-i)==0)? true : false);
}
如果我错了,告诉我!

你说

我们不应该使用条件运算符

但这是一个技巧性要求,因为
==
也是一个条件运算符。
中还内置了一个:
while
for
循环。因此,几乎所有人都未能提供满足所有要求的答案

构建一个没有条件运算符的解决方案的唯一方法是使用查找表,而不是其他几个人的解决方案中的一个
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");
}
sign(x) := (x == 0) ? 0 : (x/x)
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);
   }
-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
Boolean isPositive(int a)
{
  if(a == -1) return false;
  if(a == 0) return false;
  if(a == 1) return true;
  return isPositive(a/2);
}
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;
           }


   }
public boolean isPositive(int|float|double|long i){
    return (((i-i)==0)? true : false);
}
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

    }
}
T sign(T x) {
    if(x==0) return 0;
    return x/Math.abs(x);
}
if (((Double)calcYourDouble()).toString().contains("-"))
        doThis();
else doThat();
static <T extends Number> boolean isNegative(T number)
{       
    return ((number.doubleValue() * Double.POSITIVE_INFINITY) == Double.NEGATIVE_INFINITY);
}
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";
}
private static boolean isNeg(T l) {
        return (Math.abs(l-1)>Math.abs(l));
 }
public static boolean isNegative(Number number) {
    return (Double.doubleToLongBits(number.doubleValue()) & Long.MIN_VALUE) == Long.MIN_VALUE;
}