Gli operatori matematici *, /, +, -, ^ possono essere utilizzati per convertire un numero diverso da zero in 1?


118

Sto lavorando con il software (Oracle Siebel) che supporta solo le espressioni JavaScript con operatori moltiplicare, dividere, sottrarre, aggiungere e XOR ( *, /, -, +, ^). Non ho altri operatori come !o ? :disponibili.

Utilizzando gli operatori di cui sopra, è possibile convertire un numero in 1 se è diverso da zero e lasciarlo 0 se è già zero? Il numero può essere positivo, zero o negativo.

Esempio:

var c = 55;

var d;  // d needs to set as 1

Ho provato c / c, ma restituisce NaNquando cè 0. ddeve essere 0 quando cè 0.

c è un valore di valuta e avrà un massimo di due cifre finali e 12 cifre iniziali.

Sto cercando di emulare una ifcondizione convertendo un numero in un booleano 0 o 1 e quindi moltiplicando altre parti dell'espressione.


3
I commenti non sono per discussioni estese; questa conversazione è stata spostata nella chat .
Samuel Liew

10
@SamuelLiew Sebbene ci siano molti commenti e alcuni di essi dovrebbero essere rimossi ( discussione , risposta in commento ), la maggior parte di essi sono in realtà richieste di chiarimenti ( ad esempio ). I commenti che chiedono se si tratta di un problema XY sono al limite.
user202729

Oracle Siebel Numeric Operators, sembra essere un esponente: docs.oracle.com/cd/E95904_01/books/VBLANG/…
Derrick Moeller

2
@DerrickMoeller Sembra che ci sia una distinzione tra Siebel VB e Siebel eScript. In quest'ultimo, è un xor bit per bit . Non sono sicuro quale dei due si applichi qui.
CRice

3
@ user202729 una volta che un intero thread di commenti diventa troppo lungo, non tratteremo singolarmente i commenti in modo diverso, poiché l'interfaccia mod creata dagli amministratori / sviluppatori di SE preferisce che le nostre azioni predefinite siano "sposta in chat" o "elimina tutto". Se un commento è utile, dovrebbe essere modificato nella domanda stessa o pubblicato come risposta. Se qualche commento è fuori tema, avrebbe dovuto essere autoalimentato / eliminato. Se desideri discutere di questa "funzionalità" mod e / o dei flag automatici "troppi commenti" che i moderatori ottengono, ti preghiamo di portarlo in discussione su Meta o Meta.SE. Grazie.
Samuel Liew

Risposte:


149

c / (c + 5e-324)dovrebbe funzionare. (La costante 5e-324è Number.MIN_VALUEil numero positivo rappresentabile più piccolo.) Se x è 0, è esattamente 0 e se x è diverso da zero (tecnicamente, se x è almeno 4.45014771701440252e-308, il numero più piccolo diverso da zero consentito nel domanda, 0,01, è), la matematica in virgola mobile di JavaScript è troppo imprecisa perché la risposta sia diversa da 1, quindi risulterà esattamente 1.


1
devi prima convertire l'espressione in bool, poiché l'OP sta tentando di moltiplicare 0 e 1 con other parts of the expressione c / (c + 5e-324) * some_expressionnon funzionerà
phuclv

28
Ho

1
@Medinoc sì, ma la domanda dice anche che non ci saranno mai più di 2 cifre dopo il punto decimale, e 324 è molto più di 2.
Joseph Sible-Reinstate Monica

1
È interessante e potrebbe funzionare per OP, ma mi dispiace davvero incontrare questo tipo di codice quando si lavora in un team. Per lo meno, dovrebbe essere ben documentato e testato.
Eric Duminil

1
@JosephSible Lo so, ma se la prendi davvero in questo modo, la risposta più ovvia dovrebbe essere Number(Boolean(n)), che non utilizza alcun operatore. Non ho detto che questa non è la risposta che l'OP stava cercando, ma questa non è la risposta alla domanda descritta dall'OP. Probabilmente però dovrebbe migliorare la domanda.
user5532169

216

Usa l'espressione n/n^0.

Se nnon è zero:

 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.

Se nè zero:

 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.

Come puoi vedere, tutti i valori diversi da zero vengono convertiti in 1 e 0 rimane a 0. Ciò sfrutta il fatto che in JavaScript, NaN^0 è 0.

demo:

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


45
TIL: Number.NaN ^ n === no_O (dove nè un numero finito)
zerkms

17
Sembra che, se usato come operando bit per bit, NaNvenga convenientemente convertito a zero. Vedi: Operazioni
bit per bit

3
@zerkms Forse ~~NaN === 0sembra più naturale
Bergi

8
@EnricoBorba Non è l'elevazione a potenza (che usa **), è uno XOR bit per bit. Le operazioni bit per bit hanno una precedenza molto bassa in javascript, quindi la divisione avverrà per prima.
CRice

3
^è un operatore xor bit per bit. Dubito che ^nell'OP sia xor bit per bit quando tutti gli altri operatori sono operatori aritmetici. Probabilmente è l'operatore di esponenziazione ( **in JavaScript).
Salman A

17

(((c/c)^c) - c) * (((c/c)^c) - c) restituirà sempre 1 per negativi e positivi e 0 per 0.

È decisamente più confuso della risposta scelta e più lungo. Tuttavia, mi sembra che sia meno hacky e non si basi su costanti.

EDIT: come menziona @JosephSible, una versione più compatta della mia e della versione di @ CRice che non utilizza costanti è:

c/c^c-c

La risposta di CRice non è stata scelta, Joseph Sible sì. In tutta onestà non ho notato la risposta di CRice fino a dopo la pubblicazione.
Kyle Wardle

2
Tuttavia, non utilizza costanti, solo gli operatori e la variabile data.
L3viathan

2
@JosephSible c/c^(c-c)è soloc
Tavian Barnes

2
@ JosephSible stavo leggendo ^come esponenziale come implicito dall'OP "moltiplicare, dividere, sottrarre, aggiungere ed esponente (*, /, -, +, ^ )". Se ^è XOR con la sua precedenza JavaScript, allora mi sbaglio. Ho chiesto chiarimenti sul PO.
Tavian Barnes,

2
@TavianBarnes non è quello che ha scritto OP; qualcuno ha modificato la domanda. L'ho ripristinato nel modo in cui l'OP ha effettivamente chiesto.
Joseph Sible-Reinstate Monica il

2

Una risposta molto complicata, ma che non dipende da una precisione limitata: se prendi x^(2**n), questo sarà sempre uguale a x+2**nse x è zero, ma sarà uguale a x-2**nse x ha uno all'ennesima posizione. Quindi, per x = 0, (x^(2**n)-x+2**n)/(2**(n+1)sarà sempre 1, ma a volte sarà zero per x! = 0. Quindi se prendi il prodotto di (x^(2**n)-x+2**n)/(2**(n+1)oltre tutto n, allora XOR quello con 1, otterrai la funzione desiderata. Tuttavia, dovrai codificare manualmente ogni fattore. E dovrai modificarlo se stai usando i punti mobili.

Se hai l' ==operatore, allora (x==0)^1funziona.


3
**==è disponibile.
Joseph Sible-Reinstate Monica il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.