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

118

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

Можно ли с помощью указанных выше операторов преобразовать число в 1, если оно не равно нулю, и оставить его 0, если оно уже равно нулю? Число может быть положительным, нулевым или отрицательным.

Пример:

var c = 55;

var d;  // d needs to set as 1

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

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

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

Дейв
источник
3
Комментарии не предназначены для расширенного обсуждения; этот разговор был перемещен в чат .
Сэмюэл Лью
10
@SamuelLiew Хотя комментариев много, и некоторые из них следует удалить ( обсуждение , ответ в комментариях ), большинство из них действительно являются просьбой о разъяснении ( например ). Комментарии с вопросом, не проблема ли это XY, являются пограничными.
user202729
Числовые операторы Oracle Siebel, похоже, экспоненты: docs.oracle.com/cd/E95904_01/books/VBLANG/…
Деррик Мёллер,
2
@DerrickMoeller Кажется, есть различие между Siebel VB и Siebel eScript. В последнем случае это побитовый xor . Я не уверен, какой из двух здесь применим.
CRice
3
@ user202729, если вся цепочка комментариев становится слишком длинной, мы не собираемся отдельно обрабатывать комментарии по-разному, поскольку интерфейс мода, созданный администраторами / разработчиками SE, предпочитает, чтобы наши действия по умолчанию были либо «перейти в чат», либо «удалить все». Если какой-либо комментарий окажется полезным, его следует отредактировать в самом вопросе или опубликовать в качестве ответа. Если какой-либо комментарий не по теме, его следовало удалить / удалить самостоятельно. Если вы хотите обсудить эту «особенность» мода и / или «слишком много комментариев», которые получают модераторы автоматических флагов, пожалуйста, поднимите его для обсуждения на Meta или Meta.SE. Спасибо.
Сэмюэл Лью

Ответы:

149

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

Джозеф Сибл-Восстановить Монику
источник
1
вам нужно сначала преобразовать выражение в bool, так как OP пытается умножить 0 и 1 на other parts of the expressionи c / (c + 5e-324) * some_expressionне будет работать
phuclv
28
Взял ошибку и превратил ее в фичу там
Чираг Бхатия - chirag64
1
@Medinoc: да, но в вопросе также говорится, что после десятичной запятой никогда не будет больше двух цифр, а 324 - это намного больше, чем 2.
Джозеф Сибл-Восстановите Монику
1
Это интересно, и это может сработать для OP, но мне очень не хотелось бы сталкиваться с таким кодом при работе в команде. По крайней мере, это должно быть хорошо задокументировано и протестировано.
Эрик Думинил
1
@JosephSible Я знаю, но если вы действительно так считаете, наиболее очевидным ответом будет то Number(Boolean(n)), что оператор не использует. Я не сказал, что это не тот ответ, который искал OP, но это не ответ на вопрос, описанный OP. Вероятно, это должно улучшить вопрос.
user5532169
216

Используйте выражение 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}.`))

CRice
источник
45
TIL: Number.NaN ^ n === no_O (где nконечное число)
zerkms
17
Кажется, что при использовании в качестве побитового операнда NaNудобно конвертировать в ноль. См .: Побитовые операции с не числами
CRice
3
@zerkms Может быть, ~~NaN === 0кажется более естественным
Берги
8
@EnricoBorba Это не возведение в степень (которое использует **), это побитовое XOR. Побитовые операции имеют очень низкий приоритет в javascript, поэтому деление происходит первым.
CRice
3
^- побитовый оператор xor. Я сомневаюсь, что ^в OP есть побитовый xor, когда все остальные операторы являются арифметическими операторами. Вероятно, это оператор возведения в степень ( **в JavaScript).
Salman A
17

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

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

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

c/c^c-c
Кайл Уордл
источник
Ответ CRice не был выбран, был выбран Джозеф Сибл. Честно говоря, я не заметил ответа CRice до момента публикации.
Кайл Уордл
2
Однако он не использует никаких констант, только операторы и данную переменную.
L3viathan
2
@JosephSible c/c^(c-c)простоc
Тавиан Барнс
2
@JosephSible Я читал ^как возведение в степень, подразумеваемое OP «умножение, деление, вычитание, добавление и экспонента (*, /, -, +, ^ )». Если ^это XOR с приоритетом JavaScript, тогда я ошибаюсь. Я попросил разъяснений по ОП.
Тавиан Барнс
2
@TavianBarnes это не то, что написал OP; кто-то редактировал вопрос. Я восстановил его так, как на самом деле попросил OP.
Джозеф Сибл-Восстановите Монику
2

Очень сложный ответ, но тот, который не зависит от ограниченной точности: если вы возьмете x^(2**n), он всегда будет равен, x+2**nесли x равен нулю, но он будет равен, x-2**nесли x имеет единицу на n-м месте. Таким образом, для x = 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работает.

Acccumulation
источник
3
Ни то, **ни ==доступно.
Джозеф Сибл-Восстановите Монику