Können mathematische Operatoren *, /, +, -, ^ verwendet werden, um eine Zahl ungleich Null in 1 umzuwandeln?

118

Ich arbeite mit Software (Oracle Siebel) , die nur mehrfach JavaScript Ausdrücke mit Operatoren unterstützt, teilen, subtrahieren, addieren, und XOR ( *, /, -, +, ^). Ich habe keine anderen Operatoren wie !oder ? :verfügbar.

Ist es mit den obigen Operatoren möglich, eine Zahl in 1 umzuwandeln, wenn sie nicht Null ist, und sie bei 0 zu lassen, wenn sie bereits Null ist? Die Zahl kann positiv, null oder negativ sein.

Beispiel:

var c = 55;

var d;  // d needs to set as 1

Ich habe es versucht c / c, aber es wird ausgewertet, NaNwann c0 ist. Muss d0 sein, wenn c0 ist.

c ist ein Währungswert und hat maximal zwei nachfolgende und 12 führende Ziffern.

Ich versuche, eine ifBedingung zu emulieren , indem ich eine Zahl in eine boolesche 0 oder 1 konvertiere und dann andere Teile des Ausdrucks multipliziere.

Dave
quelle
3
Kommentare sind nicht für eine ausführliche Diskussion gedacht. Dieses Gespräch wurde in den Chat verschoben .
Samuel Liew
10
@SamuelLiew Obwohl es viele Kommentare gibt und einige davon entfernt werden sollten ( Diskussion , Antwort im Kommentar ), sind die meisten von ihnen wirklich um Klarstellung gebeten ( zum Beispiel ). Kommentare, in denen gefragt wird, ob es sich um ein XY-Problem handelt, sind grenzwertig.
user202729
Oracle Siebel Numeric Operators, scheint Exponent zu sein: docs.oracle.com/cd/E95904_01/books/VBLANG/…
Derrick Moeller
2
@DerrickMoeller Es scheint einen Unterschied zwischen Siebel VB und Siebel eScript zu geben. In letzterem ist es ein bitweises xor . Ich bin mir nicht sicher, welche der beiden hier zutrifft.
CRice
3
@ user202729 Sobald ein ganzer Kommentarthread zu lang wird, werden wir Kommentare nicht einzeln anders behandeln, da die von SE-Administratoren / Entwicklern erstellte Mod-Oberfläche unsere Standardaktionen entweder "In Chat verschieben" oder "Alle löschen" bevorzugt. Wenn ein Kommentar nützlich ist, sollte er in der Frage selbst bearbeitet oder als Antwort veröffentlicht werden. Wenn ein Kommentar nicht zum Thema gehört, sollte er selbst beschnitten / gelöscht worden sein. Wenn Sie dieses Mod "Feature" und / oder die "zu viele Kommentare" diskutieren möchten, die Moderatoren für automatische Flags erhalten, bringen Sie es bitte zur Diskussion auf Meta oder Meta.SE. Danke dir.
Samuel Liew

Antworten:

149

c / (c + 5e-324)sollte arbeiten. (Die Konstante 5e-324ist Number.MIN_VALUEdie kleinste darstellbare positive Zahl.) Wenn x 0 ist, ist das genau 0, und wenn x ungleich Null ist (technisch, wenn x mindestens 4,45014771701440252e-308 ist, wobei die kleinste Zahl ungleich Null in der Frage, 0,01, ist), JavaScript's Gleitkomma-Mathematik ist zu ungenau, als dass die Antwort von 1 abweichen könnte, sodass sie als genau 1 herauskommt.

Joseph Sible-Reinstate Monica
quelle
1
Sie müssen den Ausdruck zuerst in bool konvertieren, da das OP versucht, 0 und 1 mit zu multiplizieren other parts of the expression, und c / (c + 5e-324) * some_expressionnicht funktioniert
phuclv
28
Habe einen Fehler gemacht und ihn dort in ein Feature verwandelt
Chirag Bhatia - chirag64
1
@Medinoc ja, aber die Frage sagt auch, dass es nie mehr als 2 Stellen nach dem Dezimalpunkt geben wird, und 324 ist viel mehr als 2.
Joseph Sible-Reinstate Monica
1
Es ist interessant und könnte für OP funktionieren, aber ich würde es wirklich hassen, auf diese Art von Code zu stoßen, wenn ich in einem Team arbeite. Zumindest sollte es gut dokumentiert und getestet sein.
Eric Duminil
1
@ JosephSible Ich weiß, aber wenn Sie es wirklich so sehen, sollte die naheliegendste Antwort sein Number(Boolean(n)), die keinen Operator verwendet. Ich habe nicht gesagt, dass dies nicht die Antwort ist, nach der das OP gesucht hat, aber dies ist nicht die Antwort auf die Frage, die das OP beschrieben hat. Wahrscheinlich sollte sich die Frage aber verbessern.
user5532169
216

Verwenden Sie den Ausdruck n/n^0.

Wenn nnicht Null ist:

 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.

Wenn nNull ist:

 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.

Wie Sie sehen können, werden alle Werte ungleich Null in 1 konvertiert, und 0 bleibt bei 0. Dies nutzt die Tatsache, dass in JavaScript NaN^00 ist.

Demo:

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

CRice
quelle
45
TIL: Number.NaN ^ n === no_O (wo nist eine endliche Zahl)
Zerkms
17
Es scheint, dass es bei Verwendung als bitweiser Operand NaNbequem in Null konvertiert wird. Siehe: Bitweise Operationen auf Nicht-Zahlen
CRice
3
@ Zerkms Vielleicht ~~NaN === 0scheint natürlicher
Bergi
8
@EnricoBorba Es ist keine Potenzierung (die verwendet **), es ist ein bitweises XOR. Bitweise Operationen haben in Javascript eine sehr niedrige Priorität, sodass die Teilung zuerst erfolgt.
CRice
3
^ist bitweiser xor-Operator. Ich bezweifle, dass ^im OP bitweise x ist oder wenn alle anderen Operatoren arithmetische Operatoren sind. Es ist wahrscheinlich der Potenzierungsoperator ( **in JavaScript).
Salman A
17

(((c/c)^c) - c) * (((c/c)^c) - c) gibt immer 1 für Negative und Positive und 0 für 0 zurück.

Es ist definitiv verwirrender als die gewählte Antwort und länger. Ich denke jedoch, dass es weniger hackig ist und sich nicht auf Konstanten verlässt.

BEARBEITEN: Wie @JosephSible erwähnt, ist eine kompaktere Version von mir und der Version von @ CRice, die keine Konstanten verwendet ,:

c/c^c-c
Kyle Wardle
quelle
CRices Antwort wurde nicht gewählt, Joseph Sible war es. Ehrlich gesagt habe ich die Antwort von CRice erst nach dem Posten bemerkt.
Kyle Wardle
2
Es werden jedoch keine Konstanten verwendet, nur die Operatoren und die angegebene Variable.
L3viathan
2
@ JosephSible c/c^(c-c)ist nurc
Tavian Barnes
2
@JosephSible Ich habe ^als Exponentiation gelesen, wie dies durch das OP "Multiplizieren, Dividieren, Subtrahieren, Addieren und Exponieren (*, /, -, +, ^ )" impliziert wird . Wenn ^XOR mit seiner JavaScript-Priorität ist, dann irre ich mich. Ich bat um Klarstellung zum OP.
Tavian Barnes
2
@TavianBarnes das hat OP nicht geschrieben; jemand hat die Frage bearbeitet. Ich habe es so wiederhergestellt, wie OP es tatsächlich verlangt hat.
Joseph Sible-Reinstate Monica
2

Eine sehr komplizierte Antwort, die jedoch nicht von begrenzter Genauigkeit abhängt: Wenn Sie nehmen x^(2**n), ist dies immer gleich, x+2**nwenn x Null ist, aber es ist gleich, x-2**nwenn x an der n-ten Stelle eine Eins hat. Somit ist für x = 0 (x^(2**n)-x+2**n)/(2**(n+1)immer 1, aber manchmal ist es für x! = 0 Null. Wenn Sie also das Produkt von (x^(2**n)-x+2**n)/(2**(n+1)über allen n nehmen, dann XOR, dass mit 1, erhalten Sie Ihre gewünschte Funktion. Sie müssen jedoch jeden Faktor manuell codieren. Und Sie müssen dies ändern, wenn Sie Gleitkommazahlen verwenden.

Wenn Sie den ==Operator haben, dann (x==0)^1funktioniert.

Akkumulation
quelle
3
Weder **noch ==verfügbar.
Joseph Sible-Reinstate Monica