Можно ли использовать математические операторы *, /, +, -, ^ для преобразования ненулевого числа в 1?

Я работаю с программным обеспечением (Oracle Siebel), которое поддерживает только выражения JavaScript с операторами умножения, деления, вычитания, сложения и XOR (*, /, -, +, ^). У меня нет других операторов, таких как ! или же ? : имеется в наличии.

Используя приведенные выше операторы, можно ли преобразовать число в 1, если оно не равно нулю, и оставить 0, если оно уже равно нулю? Число может быть положительным, нулевым или отрицательным.

Пример:

var c = 55;

var d;  // d needs to set as 1

Я старался c / c, но это оценивает NaN когда c это 0. d должен быть 0, когда c это 0.

c является значением валюты, и оно будет иметь максимум две завершающие цифры и 12 начальных цифр.

Я пытаюсь подражать if условие путем преобразования числа в логическое значение 0 или 1, а затем умножения других частей выражения.

4 ответа

Решение

c / (c + 5e-324) должно сработать. (Постоянная 5e-324 является Number.MIN_VALUE наименьшее представимое положительное число.) Если x равно 0, то это точно 0, и если x ненулевое (технически, если x не меньше 4.45014771701440252e-308, что наименьшее ненулевое число, допустимое в вопросе, 0,01, is), математика JavaScript с плавающей точкой слишком неточна, чтобы ответ отличался от 1, поэтому он будет иметь значение ровно 1.

Используйте выражение n/n^0,

Если n не ноль:

 Step    Explanation
------- -------------------------------------------------------------------------------
 n/n^0   Original expression.
 1^0     Any number divided by itself equals 1. Therefore n/n becomes 1.
 1       1 xor 0 equals 1.

Если n ноль:

 Step    Explanation
------- -------------------------------------------------------------------------------
 n/n^0   Original expression.
 0/0^0   Since n is 0, n/n is 0/0.
 NaN^0   Zero divided by zero is mathematically undefined. Therefore 0/0 becomes NaN.
 0^0     In JavaScript, before any bitwise operation occurs, both operands are normalized.
         This means NaN becomes 0.
 0       0 xor 0 equals 0.

Как видите, все ненулевые значения преобразуются в 1, а 0 остается равным 0. Это использует тот факт, что в JavaScript, NaN^0 это 0.

Демо-версия:

[0, 1, 19575, -1].forEach(n => console.log(`${n} becomes ${n/n^0}.`))

(((c/c)^c) - c) * (((c/c)^c) - c) всегда будет возвращать 1 для негативов и позитивов и 0 для 0.

Это определенно более запутанно, чем выбранный ответ и дольше. Тем не менее, я чувствую, что он менее хакерский и не полагается на константы.

РЕДАКТИРОВАТЬ: Как упоминает @JosephSible, более компактная моя версия и версия @CRice, которая не использует константы:

c/c^c-c

Очень сложный ответ, но тот, который не зависит от ограниченной точности: если вы берете x^(2**n), это всегда будет равно x+2**n если х равен нулю, но он будет равен x-2**n если х имеет единицу на n-м месте. Таким образом, для х =0, (x^(2**n)-x+2**n)/(2**(n+1) всегда будет 1, но иногда будет нулем для x!=0. Так что, если вы берете продукт (x^(2**n)-x+2**n)/(2**(n+1) по всем n, затем XOR, что с 1, вы получите желаемую функцию. Однако вам придется вручную кодировать каждый фактор. И вам придется изменить это, если вы используете плавающие точки.

Если у вас есть == оператор, то (x==0)^1 работает.

Другие вопросы по тегам