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

Dea*_*mer 56 java numbers

我在接受采访时被问及如何判断一个数字是正数还是负数.这些规则,我们不应该使用条件运算符,如<,和>,建于Java的功能(例如substring,indexOf,charAt,和startsWith),没有正则表达式,或者API的.

我做了一些关于此的功课,下面给出了代码,但它只适用于整数类型.但是,他们让我写,对工作的通用代码float,doublelong.

 // This might not be better way!!

 S.O.P ((( number >> 31 ) & 1) == 1 ? "- ve number " : "+ve number );
Run Code Online (Sandbox Code Playgroud)

你身边的任何想法?

Cra*_*ney 66

整数的情况很简单.双重情况比较棘手,直到你记得无穷大.

注意:如果你认为双常量是"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");
}
Run Code Online (Sandbox Code Playgroud)

  • 双重解决方案非常聪明/光滑 (7认同)
  • 根据之前对其他答案的评论,我们可以说Double.POSITIVE_INFINITY是API的一部分.我喜欢它.可以通过(双)演员制作完整的通用. (2认同)

War*_*rty 36

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

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

负数很好,因为你会溢出到正数,然后最终得到一个堆栈溢出异常[会返回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
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 那个人笑了起来.:d (25认同)
  • 如果数字是"1.5",它在任何情况下都不会直接导致0,"0.5"和"-0.5"你也应该考虑,否则好主意:) (7认同)
  • 谢谢,但这就像吹炸弹并知道结果. (6认同)

nan*_*nda 17

这只适用于[0..2]以外的所有内容

boolean isPositive = (n % (n - 1)) * n == n;
Run Code Online (Sandbox Code Playgroud)

你可以像这样做一个更好的解决方案([0..1]除外)

boolean isPositive = ((n % (n - 0.5)) * n) / 0.5 == n;
Run Code Online (Sandbox Code Playgroud)

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

boolean isPositive = ((n % (n - 0.03125)) * n) / 0.03125 == n;
Run Code Online (Sandbox Code Playgroud)


Nab*_*abb 8

你可以这样做:

((long) (num * 1E308 * 1E308) >> 63) == 0 ? "+ve" : "-ve"
Run Code Online (Sandbox Code Playgroud)

这里的主要思想是我们投入很长时间并检查最重要位的值.当-1和0之间的double/float在转换为long时将舍入为零,我们乘以大的double,以便负float/double小于-1.由于存在次正规,所以需要两次乘法(虽然它实际上并不需要那么大).

  • @nanda根据Java语言规范,抛出一个太长到太长的double将导致long类型的最大可表示值(负数的行为方式相同).无论如何,如果num适合长,我们无论如何都要将它乘以无穷大(零除外). (3认同)

Bee*_*eep 5

那这个呢?

return ((num + "").charAt(0) == '-');
Run Code Online (Sandbox Code Playgroud)