Java 如何判断一个数是正数还是负数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3994531/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 08:05:02  来源:igfitidea点击:

How to determine if a number is positive or negative?

javanumbers

提问by Dead Programmer

I was asked in an interview, how to determine whether a number is positive or negative. The rules are that we should not use relational operators such as <, and >, built in java functions (like substring, indexOf, charAt, and startsWith), no regex, or API's.

我在一次采访中被问到,如何确定一个数字是正数还是负数。规则是我们不应使用关系运算符,例如<, 和>,内置于 Java 函数(如substring, indexOf, charAt, and startsWith),不使用正则表达式或 API。

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

我对此做了一些功课,代码如下,但它仅适用于整数类型。但是,他们让我写,对工作的通用代码floatdoublelong

 // This might not be better way!!

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

any ideas from your side?

你有什么想法吗?

采纳答案by Craig Gidney

The integer cases are easy. The double case is trickier, until you remember about infinities.

整数情况很容易。双重情况更棘手,直到您记住无穷大。

Note: If you consider the double constants "part of the api", you can replace them with overflowing expressions like 1E308 * 2.

注意:如果您将双常量视为“api 的一部分”,您可以将它们替换为像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");
}

回答by jeffo

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

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

回答by Will

Untested, but illustrating my idea:

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

boolean IsNegative<T>(T v) {
  return (v & ((T)-1));
}

回答by Warty

The following is a terrible approach that would get you fired at any job...

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

It depends on you getting a Stack Overflow Exception [or whatever Java calls it]... And it would only work for positive numbers that don't deviate from 0 like crazy.

这取决于你得到一个堆栈溢出异常 [或任何 Java 调用它]......它只适用于不会像疯了一样偏离 0 的正数。

Negative numbers are fine, since you would overflow to positive, and then get a stack overflow exception eventually [which would return false, or "yes, it is negative"]

负数很好,因为你会溢出到正数,然后最终得到一个堆栈溢出异常 [这将返回 false,或者“是的,它是负数”]

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

回答by Nabb

You can do something like this:

你可以这样做:

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

The main idea here is that we cast to a long and check the value of the most significant bit. As a double/float between -1 and 0 will round to zero when cast to a long, we multiply by large doubles so that a negative float/double will be less than -1. Two multiplications are required because of the existence of subnormals(it doesn't really need to be that big though).

这里的主要思想是我们转换为 long 并检查最高有效位的值。当转换为 long 时,-1 和 0 之间的双精度/浮点数将舍入为零,因此我们乘以大双精度数,以便负浮点数/双精度数将小于 -1。由于次正规的存在,需要两次乘法(虽然它并不需要那么大)。

回答by Steven Schlansker

// Returns 0 if positive, nonzero if negative
public long sign(long value) {
    return value & 0x8000000000000000L;
}

Call like:

像这样调用:

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

sign((long) valN);

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

从 double / float / integer 转换为 long 应该保留符号,如果不是实际值...

回答by Beep beep

What about this?

那这个呢?

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

回答by nanda

This will only works for everything except [0..2]

这仅适用于除 [0..2] 之外的所有内容

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

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

您可以像这样制定更好的解决方案(除 [0..1] 外有效)

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

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

您可以通过将 0.5 部分更改为 2^m(m 整数)之类的内容来获得更好的精度:

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

回答by Jason Goemaat

It seems arbitrary to me because I don't know how you would get the number as any type, but what about checking Abs(number) != number? Maybe && number != 0

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

回答by Donal Fellows

Integers are trivial; this you already know. The deep problem is how to deal with floating-point values. At that point, you've got to know a bit more about how floating point values actually work.

整数是微不足道的;这个你已经知道了。深层次的问题是如何处理浮点值。那时,您必须更多地了解浮点值的实际工作原理。

The key is Double.doubleToLongBits(), which lets you get at the IEEE representation of the number. (The method's really a direct cast under the hood, with a bit of magic for dealing with NaN values.) Once a double has been converted to a long, you can just use 0x8000000000000000L as a mask to select the sign bit; if zero, the value is positive, and if one, it's negative.

关键是Double.doubleToLongBits(),它可以让您获得数字的 IEEE 表示。(该方法实际上是在幕后直接转换,在处理 NaN 值时有点魔法。)一旦 double 被转换为 long,您就可以使用 0x8000000000000000L 作为掩码来选择符号位;如果为零,则值为正,如果为一,则为负。

回答by DreamWave

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

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

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