Чи можна використовувати математичні оператори *, /, +, -, ^ для перетворення ненульового числа в 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
Коментарі не для розширеного обговорення; ця розмова була переміщена до чату .
Самуель Liew

10
@SamuelLiew Хоча коментарів дуже багато, і деякі з них слід видалити ( обговорення , відповідь у коментарі ), більшість із них дійсно вимагають роз'яснення ( наприклад ). Коментарі, які запитують, чи це проблема XY є прикордонною.
користувач202729

Числові оператори Oracle Siebel, схоже, є експонентами: docs.oracle.com/cd/E95904_01/books/VBLANG/…
Derrick Moeller

2
@DerrickMoeller Схоже, існує відмінність між Siebel VB і Siebel eScript. В останньому він є побітним xor . Я не впевнений, що з двох стосується тут.
CRice

3
@ user202729, коли будь-який весь потік коментарів стає занадто довгим, ми не збираємось по-різному ставитися до коментарів, оскільки модний інтерфейс, створений SE admins / devs, вважає за краще, щоб наші дії за замовчуванням були або "перейти до чату", або "видалити всі". Якщо будь-який коментар корисний, його слід відредагувати в самому запитанні або опублікувати як відповідь. Якщо будь-який коментар поза темою, їх слід було б саморізати / видалити. Якщо ви хочете обговорити цю модну "функцію" та / або отримати "занадто багато коментарів", авторизовані модераторами, будь ласка, піднесіть її для обговорення на Meta чи Meta.SE. Дякую.
Самуель Liew

Відповіді:


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, оскільки ОП намагається помножити 0 і 1 на other parts of the expression, і c / (c + 5e-324) * some_expressionне вийде
phuclv

28
Взяті помилку і перетворили його в особливості там
Чираг Bhatia - chirag64

1
@Medinoc так, але запитання також говорить про те, що після десяткової крапки ніколи не буде більше двох цифр, а 324 - це набагато більше, ніж 2.
Джозеф Сибл-Поновити Моніку

1
Це цікаво, і це може працювати для ОП, але я дуже ненавиджу зустріти такий код, коли працюю в команді. Як мінімум, він повинен бути добре задокументований і перевірений.
Ерік Дюмініл

1
@JosephSible Я знаю, але якщо ви дійсно так сприймете, слід отримати найбільш очевидну відповідь Number(Boolean(n)), яка не використовує жодного оператора. Я не казав, що це не відповідь, яку шукала ОП, але це не відповідь на питання, описане ОП. Напевно, слід покращити питання.
користувач5532169

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}.`))


45
TIL: Number.NaN ^ n === no_O (де nкінцеве число)
zerkms

17
Здається, що при використанні як побітовий операнд, NaNзручно перетворюватися на нуль. Дивіться: Побітові операції на не числах
CRice

3
@zerkms Можливо ~~NaN === 0здається більш природним
Бергі

8
@EnricoBorba Це не експоненція (яка використовує **), це побіт XOR. Бітові операції мають дуже низький пріоритет у JavaScript, тому поділ відбудеться першим.
CRice

3
^є побітовим оператором xor. Сумніваюсь, чи є ^в ОП побітовий xor, коли всі інші оператори є арифметичними операторами. Ймовірно, це оператор експоненції ( **в JavaScript).
Салман

17

(((c/c)^c) - c) * (((c/c)^c) - c) завжди поверне 1 за негативом та позитивом і 0 за 0.

Це, безумовно, більш заплутано, ніж обрана відповідь і довше. Однак я відчуваю, що він менш хакітний і не покладається на константи.

EDIT: Як згадує @JosephSible, більш компактна версія шахти та версії @ CRice, яка не використовує константи, є:

c/c^c-c

Відповідь Крісі не була обрана, Джозеф Сибл. Чесно кажучи, я не помітив відповіді Крісі до після публікації.
Кайл Уордл

2
Він не використовує константи, однак лише оператори та задану змінну.
L3viathan

2
@JosephSible c/c^(c-c)простоc
Тавіан Барнс

2
@JosephSible Я читав ^як експоненцію, яку мав на увазі ОП "множити, ділити, віднімати, додавати і експонент (*, /, -, +, ^ )". Якщо ^це XOR з його перевагою JavaScript, то я помиляюся. Я попросив роз'яснень щодо ОП.
Тавіан Барнс

2
@TavianBarnes - це не те, що написав ОП; хтось редагував питання. Я відновив її так, як насправді запитував ОП.
Джозеф Сибл-Відновити Моніку

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працює.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.