Java проверить число на отрицательное

Проверять положительные или отрицательные значения без использования условных операторов в java

Мне нужна функция, чтобы распечатать, является ли число положительным или отрицательным, не используя условные выражения типа if else while for switch a? b:c и т.д. Как я могу это сделать.

Я сказал интервьюеру, что это невозможно, потому что вопрос носит «условный характер». Он сказал мне, что это возможно, но не сказал мне, как это сделать. Я сделал довольно много поиска, но никаких хороших ответов.

ОТВЕТЫ

Ответ 1

Одно из возможных решений:

String[] responses = ; System.out.println(responses[(i >> 31) & 1]); 

Это также считается нулем в качестве положительного числа.

Поскольку целые числа в Java должны храниться в два дополнения (или вести себя так, как если бы они были), самый старший бит любого отрицательного числа 1, а старший бит любого другого числа равен 0. (i >> 31) копирует самый старший бит на каждый другой бит (поэтому отрицательные числа становятся 11111111 11111111 11111111 11111111 , а положительные/нулевые числа становятся 00000000 00000000 00000000 00000000 ). & 1 устанавливает для всех, кроме младшего разряда, значение 0. Комбинация (i >> 31) & 1 эффективно читает только самый старший бит i .

Ответ 2

Вот вариант, учитывающий тот факт, что нуль не является ни положительным, ни отрицательным:

 int x = (int)Math.sqrt(Math.pow(n, 2)); try < x = n / x; >catch (ArithmeticException e) < x = 0; >String[] result = ; System.out.println(result[x + 1]); 

Ответ 3

Просто, чтобы подробно остановиться на immibis, ответьте немного:

int index(int i) < return 1 + (i>>31) - (-i>>31); > String[] text = ; private String text(int i)

Подписанный сдвиг i>>31 преобразует каждое отрицательное число в -1 и все остальные в 0 . Вычисление -i>>31 позволяет отличать положительные числа от неположительных. Теперь посмотрим на вычисленный index :

positive: 1 + 0 - (-1) = 2 zero: 1 + 0 - 0 = 1 negative: 1 + (-1) - 0 = 0 

Ответ 4

Супер простое решение, злоупотребляющее тем, что массивы не могут иметь отрицательный размер:

void printPositive(int i) < try < new int[i]; System.out.println("positive"); >catch( NegativeArraySizeException e) < System.out.println("negative"); >> 

Хорошо, этот ответ может выделять огромный массив, если i положителен, и VM может использовать условные обозначения под его капотом при оценке new int[i] , но по крайней мере это покажет интервьюеру какое-то творчество. Кроме того, это может показать интервьюеру, что вы можете придумать «из коробки» (потому что он может ожидать, что вы будете делать немного магии, как и большинство других ответов) и сделать что-то совершенно другое.

Ответ 5

Старый ответ. Причина, по которой я делаю этот новый ответ, заключается в том, что я использовал метод Boolean compareTo , который использует тернарный оператор для преобразования булевых выражений в двоичные.

Вот мой новый ответ, который намного нечитабелен.

public static String positiveOrNegative(int n) < ArrayListresponses = new ArrayList(); // first element should be "Zero", so if n is 0, the response is "Zero" responses.add("Zero"); // this populates the ArrayList with elements "Positive" for n elements // so that if n is positive, n will be an index in the ArrayList // and the return will be "Positive" // but still if n is negative, it will never be an index in the ArrayList for (int i = 0; i < n; i++) < responses.add("Positive"); >String response = ""; try < // try to get a response from the ArrayList response = responses.get(n); >catch (Exception e) < // index is out of bounds, so it must have been negative response = "Negative"; >return response; > public static void main(String[] args) < System.out.println(positiveOrNegative(4)); // Positive System.out.println(positiveOrNegative(1)); // Positive System.out.println(positiveOrNegative(0)); // Zero System.out.println(positiveOrNegative(-1)); // Negative System.out.println(positiveOrNegative(-4)); // Negative >

Ответ 6

boolean isPositive(int n) < return n >((n + 1) % n); > 
String isPositive(int n) < String[] results = ; return results[1+(1+((n+1)%n)*((n-1)%n))/n]; > 

Он по-прежнему не работает для 0 .

Читайте также:  Javascript число с нулями

Ответ 7

Люди, это не очень сложно, не нужно сдвигать биты или делать странные вызовы, просто используйте метод signum в классе Math!; Р

http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#signum%28float%29 

Источник

Проверка на отрицательность

Проверка на отрицательность регистра с табличной части документа
Здраствуйте, такой вопрос, есть 2 документа приходная и расходная, оба подвязаны к регистру.

Проверить число на отрицательность
Доброго времени суток! Подскажите как можно проверить число на <0. Просьба помочь кодом и.

Проверить число на отрицательность
проверяю так MAX_VALUE dw 32768 . cmp ax, MAX_VALUE А можно как-то без MAX_VALUE?

Целочисленный массив. Нечетность, отрицательность.
Задан целочисленный массив из 20 элементов определить и вывести на экран сумму тех элементов.

Лучший ответ

Сообщение было отмечено Vityafuf как решение

Решение

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
import java.math.BigInteger; public class MyClass { public static void main(String args[]) { Number[] nums = { 10, -10, -0.2, -2.2, 0.2, 3.2, 0.3f, 22.2f, -0.5f, -22.5f, Long.MAX_VALUE, Long.MIN_VALUE, new BigInteger("123123123123123424645645642323423"), new BigInteger("-1234324223423432432425325234234") }; for (Number num : nums) { System.out.println(num + " is negative: " + isNegative(num)); } } public static T extends Number> boolean isNegative(T num) { return num.doubleValue()  0; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14
10 is negative: false -10 is negative: true -0.2 is negative: true -2.2 is negative: true 0.2 is negative: false 3.2 is negative: false 0.3 is negative: false 22.2 is negative: false -0.5 is negative: true -22.5 is negative: true 9223372036854775807 is negative: false -9223372036854775808 is negative: true 123123123123123424645645642323423 is negative: false -1234324223423432432425325234234 is negative: true

Источник

проверить положительный или отрицательный без использования условных операторов в Java

Вопрос интервью, который я задал на прошлой неделе: Мне нужна функция, чтобы распечатать, является ли число положительным или отрицательным, не используя условные выражения типа if else while for switch a? b:c и т.д. Как я могу это сделать. Я сказал интервьюеру, что это невозможно, потому что вопрос носит «условный характер». Он сказал мне, что это возможно, но не сказал мне, как это сделать. Я сделал довольно много поиска, но никаких хороших ответов.

Правильный ответ: «Это не имеет значения, потому что вопрос глупый. Любой, кто использует трюки в производственном коде вместо использования оператора if, заслуживает того, чтобы его уволили».

Какой смысл таких вопросов в интервью? Я сомневаюсь, что работодатель находит лучшего кандидата с этим. Конечно, мышление растянуто, но решение менее читабельно.

@GabeSechan Если это хорошая идея, зависит от характера кода. Такие приемы могут быть полезны в высокопроизводительном коде. А в криптографическом коде они необходимы, чтобы избежать атак по побочным каналам. Многие современные криптографические библиотеки требуют, чтобы не было никаких ветвей в зависимости от секретных данных. Поэтому я категорически не согласен с вашим утверждением в такой общей форме.

a ? b : c не условное выражение, это условное выражение. Фактически, будучи выражением, а не утверждением, весь смысл условного оператора — это прежде всего! Таким образом, вопрос неправильный 😉 (Эй, если вы хотите подшутить над собеседниками, дайте правильные вопросы!)

Это (и другие полезные и по какой-то причине любимые интервьюерами повсюду) манипуляции с числами можно найти, прибегая к помощи трюков с манипулированием битами . Ответ на этот вопрос — первый в списке.

« Какой смысл таких вопросов в интервью? » — они пытаются выяснить, насколько хороши ваши навыки / способности решения проблем. Гейб прав, но тут дело не в этом.

7 ответов

Одно из возможных решений:

String[] responses = ; System.out.println(responses[(i >> 31) & 1]); 

Это также считается нулем в качестве положительного числа.

Поскольку целые числа в Java должны храниться в два дополнения (или вести себя так, как если бы они были), самый старший бит любого отрицательного числа 1, а старший бит любого другого числа равен 0. (i >> 31) копирует самый старший бит на каждый другой бит (поэтому отрицательные числа становятся 11111111 11111111 11111111 11111111 , а положительные/нулевые числа становятся 00000000 00000000 00000000 00000000 ). & 1 устанавливает для всех, кроме младшего разряда, значение 0. Комбинация (i >> 31) & 1 эффективно читает только самый старший бит i .

Если мы собираемся посчитать таблицы switch (i / i) < case -1: . ; break; case 1: . ; break; >, вы можете сказать switch (i / i) < case -1: . ; break; case 1: . ; break; >и надеюсь, что компилятор согласится с вами сделать таблицу переходов.

Вопрос не указывал только целые числа. Вы можете обойти это, int32 i/abs(i) к int32 прежде чем делать вышеописанное.

@ebarr вы можете использовать Double.doubleToLongBits или Float.floatToIntBits а затем то же самое — плавающие и двойные числа также используют старший бит для знака.

Сдвиг вправо на 31 бит перемещает «знаковый бит» к младшему биту; ‘anding’, что с 1 будет производить 1 или 0. Теперь у вас есть индекс в массив строк. Я думаю, что >>> сместил бы его, не расширяя знаковый бит, и исключил бы необходимость для и, так что другим ответом было бы использование responses[i >>> 31)] .

Просто, чтобы подробно остановиться на immibis, ответьте немного:

int index(int i) < return 1 + (i>>31) - (-i>>31); > String[] text = ; private String text(int i)

Подписанный сдвиг i>>31 преобразует каждое отрицательное число в -1 и все остальные в 0 . Вычисление -i>>31 позволяет отличать положительные числа от неположительных. Теперь посмотрим на вычисленный index :

positive: 1 + 0 - (-1) = 2 zero: 1 + 0 - 0 = 1 negative: 1 + (-1) - 0 = 0 

Вот вариант, учитывающий тот факт, что нуль не является ни положительным, ни отрицательным:

 int x = (int)Math.sqrt(Math.pow(n, 2)); try < x = n / x; >catch (ArithmeticException e) < x = 0; >String[] result = ; System.out.println(result[x + 1]); 

@dave_thompson_085 dave_thompson_085 хороший момент. Я должен был использовать Math.pow. Ответ отредактирован соответственно.

Супер простое решение, злоупотребляющее тем, что массивы не могут иметь отрицательный размер:

void printPositive(int i) < try < new int[i]; System.out.println("positive"); >catch( NegativeArraySizeException e) < System.out.println("negative"); >> 

Хорошо, этот ответ может выделять огромный массив, если i положителен, и VM может использовать условные обозначения под его капотом при оценке new int[i] , но по крайней мере это покажет интервьюеру какое-то творчество. Кроме того, это может показать интервьюеру, что вы можете придумать «из коробки» (потому что он может ожидать, что вы будете делать немного магии, как и большинство других ответов) и сделать что-то совершенно другое.

Для числа, близкого к Integer.MAX_VALUE всегда будет Integer.MAX_VALUE как максимальный размер массива немного меньше (JVM требуется место для заголовка). Также обратите внимание, что уклонение от ветвей имеет вескую причину: ветки медленные (а большинство ответов на этот вопрос еще медленнее).

@maaartinus: Правильно, мы тоже должны перехватить OutOfMemoryError . Конечно, это решение — ничего, что можно было бы использовать для реального кода. По умолчанию ветки не медленные; только ветви, которые не могут быть предсказаны хорошо, являются медленными. Поэтому, если вход в вашу функцию положительный в 95% случаев, ветвь будет практически свободна для положительных входов.

Старый ответ. Причина, по которой я делаю этот новый ответ, заключается в том, что я использовал метод Boolean compareTo , который использует тернарный оператор для преобразования булевых выражений в двоичные.

Вот мой новый ответ, который намного нечитабелен.

public static String positiveOrNegative(int n) < ArrayListresponses = new ArrayList(); // first element should be "Zero", so if n is 0, the response is "Zero" responses.add("Zero"); // this populates the ArrayList with elements "Positive" for n elements // so that if n is positive, n will be an index in the ArrayList // and the return will be "Positive" // but still if n is negative, it will never be an index in the ArrayList for (int i = 0; i < n; i++) < responses.add("Positive"); >String response = ""; try < // try to get a response from the ArrayList response = responses.get(n); >catch (Exception e) < // index is out of bounds, so it must have been negative response = "Negative"; >return response; > public static void main(String[] args) < System.out.println(positiveOrNegative(4)); // Positive System.out.println(positiveOrNegative(1)); // Positive System.out.println(positiveOrNegative(0)); // Zero System.out.println(positiveOrNegative(-1)); // Negative System.out.println(positiveOrNegative(-4)); // Negative >

-1, потому что внутренняя реализация compareTo имеет вид: return (x == y) ? 0 : (x ? 1 : -1); который, согласно требованиям, запрещен.

@bbalchev Я знал это, но я просто надеялся, что это будет исключением из правила, потому что мы никогда не видели его в функции. Тем не менее, код все еще используется, так что вы правы. Я отредактировал ответ сейчас, чтобы исключить любое использование условных операторов. Это некрасиво, но, по крайней мере, правильно. Вы можете убрать свой отрицательный голос, если найдете этот ответ подходящим сейчас.

Теоретически правильно, но кроме этого это так плохо, это начинает быть забавным. Попробуйте с 0x7FFFFFFF (32 бита). На всякий случай, если он работает без сбоя OOM или квази-зависания, масштабируйте его до 64 бит и попробуйте снова.

@JensG Это глупый вопрос . Я просто положил свои два цента. Там нет причин, чтобы понизить голосование только потому, что вы находите это «смешным». Я просто изложил свой способ сделать это, как и все остальные.

@DavidWallace Используйте оператор if или решение immibis lol. Конечно, это не будет работать для больших значений. Это не то, что я собирался. Я просто выкладываю что-то другое.

Люди, это не очень сложно, не нужно сдвигать биты или делать странные вызовы, просто используйте метод signum в классе Math!; Р

http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#signum%28float%29 

Источник

Оцените статью