Je travaille avec un logiciel (Oracle Siebel) qui ne prend en charge que les expressions JavaScript dont les opérateurs se multiplient, se divisent, soustraient, ajoutent et XOR (*
, /
, -
, +
, ^
). Je n'ai pas d'autres opérateurs tels que !
ou ? :
disponibles.
En utilisant les opérateurs ci-dessus, est-il possible de convertir un nombre en 1 s'il est différent de zéro et le laisser à 0 s'il est déjà nul? Le nombre peut être positif, nul ou négatif.
Exemple:
var c = 55;
var d; // d needs to set as 1
J'ai essayé c / c
, mais il est évalué à NaN
lorsque c
vaut 0. d
doit être 0 lorsque c
est 0.
c est une valeur monétaire et il aura un maximum de deux derniers chiffres et 12 premiers chiffres.
J'essaie d'émuler une condition if
en convertissant un nombre en un booléen 0 ou 1, puis en multipliant d'autres parties de l'expression.
c / (c + 5e-324)
devrait fonctionner. (La constante _5e-324
_ est Number.MIN_VALUE
, le plus petit nombre positif représentable.) Si x est égal à 0, cela signifie exactement 0 et si x est différent de zéro (techniquement, si x est au moins 4.45014771701440252e-308, dont le plus petit nombre non nul autorisé dans la question, 0,01, est), le calcul en virgule flottante de JavaScript est trop imprécis pour que la réponse soit différente de 1, elle sera donc exactement égale à 1.
Utilisez l'expression n/n^0
.
Si n
n'est pas zéro:
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.
Si n
est zéro:
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.
Comme vous pouvez le constater, toutes les valeurs non nulles sont converties en 1 et 0 reste à 0. Cela tient compte du fait qu'en JavaScript, NaN^0
vaut 0.
Démo:
[0, 1, 19575, -1].forEach(n => console.log(`${n} becomes ${n/n^0}.`))
(((c/c)^c) - c) * (((c/c)^c) - c)
retournera toujours 1 pour les négatifs et les positifs et 0 pour 0.
C'est certainement plus déroutant que la réponse choisie et plus long. Cependant, j'ai l'impression que c'est moins hacky et ne repose pas sur des constantes.
EDIT: Comme @JosephSible le mentionne, une version plus compacte de la mienne et la version de @ CRice qui n'utilise pas de constantes est:
c/c^c-c
Une réponse très compliquée, mais qui ne dépend pas d'une précision limitée: si vous prenez x^(2**n)
, ce sera toujours égal à x+2**n
si x est égal à zéro, mais égal à x-2**n
si x en a un à la nième place. Ainsi, pour x = 0, (x^(2**n)-x+2**n)/(2**(n+1)
sera toujours égal à 1, mais il sera parfois nul pour x! = 0. Donc, si vous prenez le produit de (x^(2**n)-x+2**n)/(2**(n+1)
sur tout n, alors XOR avec 1, vous obtiendrez la fonction désirée. Vous devrez cependant coder manuellement chaque facteur. Et vous devrez modifier cela si vous utilisez des points flottants.
Si vous avez l'opérateur ==
, alors (x==0)^1
fonctionne.