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
How to determine if a number is positive or negative?
提问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
.
我对此做了一些功课,代码如下,但它仅适用于整数类型。但是,他们让我写,对工作的通用代码float
,double
和long
。
// 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.");
}