¿Se pueden usar los operadores matemáticos *, /, +, -, ^ para convertir un número distinto de cero en 1?

118

Estoy trabajando con el software (Oracle Siebel) que sólo admite expresiones de JavaScript con los operadores de multiplicar, dividir, restar, sumar y XOR ( *, /, -, +, ^). No tengo otros operadores como !o ? :disponibles.

Usando los operadores anteriores, ¿es posible convertir un número a 1 si no es cero y dejarlo en 0 si ya es cero? El número puede ser positivo, cero o negativo.

Ejemplo:

var c = 55;

var d;  // d needs to set as 1

Lo intenté c / c, pero se evalúa NaNcuando ces 0.Necesita dser 0 cuandoc es 0.

c es un valor de moneda y tendrá un máximo de dos dígitos finales y 12 dígitos iniciales.

Estoy tratando de emular una ifcondición convirtiendo un número en un booleano 0 o 1 y luego multiplicando otras partes de la expresión.

Dave
fuente
3
Los comentarios no son para una discusión extensa; esta conversación se ha movido al chat .
Samuel Liew
10
@SamuelLiew Aunque hay muchos comentarios, y algunos de ellos deberían eliminarse ( discusión , respuesta en comentario ), la mayoría de ellos son realmente una solicitud de aclaración ( por ejemplo ). Los comentarios que preguntan si se trata de un problema XY están en el límite.
user202729
Operadores numéricos de Oracle Siebel, parece ser un exponente: docs.oracle.com/cd/E95904_01/books/VBLANG/…
Derrick Moeller
2
@DerrickMoeller Parece que hay una distinción entre Siebel VB y Siebel eScript. En este último, es un xor bit a bit . No estoy seguro de cuál de los dos se aplica aquí.
CRice
3
@ user202729 una vez que todo el hilo de comentarios se vuelve demasiado largo, no vamos a tratar los comentarios individualmente de manera diferente, ya que la interfaz de mod creada por los administradores / desarrolladores de SE prefiere que nuestras acciones predeterminadas sean "mover al chat" o "eliminar todo". Si algún comentario es útil, debe editarse en la propia pregunta o publicarse como respuesta. Si algún comentario está fuera de tema, debería haber sido podado / eliminado. Si desea discutir esta "característica" del mod y / o los "demasiados comentarios" que reciben los moderadores de banderas automáticas, por favor, póngalo en discusión en Meta o Meta.SE. Gracias.
Samuel Liew

Respuestas:

149

c / (c + 5e-324)Deberia trabajar. (La constante 5e-324es Number.MIN_VALUE, el número positivo más pequeño representable.) Si x es 0, eso es exactamente 0, y si x es distinto de cero (técnicamente, si x es al menos 4.45014771701440252e-308, que es el número más pequeño distinto de cero permitido en el pregunta, 0.01, es), la matemática de punto flotante de JavaScript es demasiado imprecisa para que la respuesta sea diferente de 1, por lo que saldrá exactamente como 1.

Joseph Sible-Reincorporar a Monica
fuente
1
primero debe convertir la expresión a bool, ya que el OP está tratando de multiplicar 0 y 1 con other parts of the expression, y c / (c + 5e-324) * some_expressionno funcionará
phuclv
28
Tomó un error y lo convirtió en una característica allí
Chirag Bhatia - chirag64
1
@Medinoc sí, pero la pregunta también dice que nunca habrá más de 2 dígitos después del punto decimal, y 324 es mucho más que 2.
Joseph Sible-Reinstate Monica
1
Es interesante y podría funcionar para OP, pero realmente odiaría encontrarme con este tipo de código cuando trabajo en equipo. Como mínimo, debe estar bien documentado y probado.
Eric Duminil
1
@JosephSible Lo sé, pero si realmente lo toma de esa manera, la respuesta más obvia debería ser Number(Boolean(n)), que no usa operador. No dije que esta no es la respuesta que estaba buscando el OP, pero esta no es la respuesta a la pregunta que describió el OP. Sin embargo, probablemente debería mejorar la pregunta.
user5532169
216

Usa la expresión n/n^0 .

Si nno es cero:

 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 nes cero:

 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.

Como puede ver, todos los valores distintos de cero se convierten en 1 y 0 permanece en 0. Esto aprovecha el hecho de que en JavaScript, NaN^0 es 0.

Manifestación:

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

CRice
fuente
45
TIL: Number.NaN ^ n === no_O (donde nes un número finito)
zerkms
17
Parece que cuando se usa como operando bit a bit, NaNse convierte convenientemente a cero. Ver: Operaciones
bit a bit
3
@zerkms Quizás ~~NaN === 0parece más natural
Bergi
8
@EnricoBorba No es exponenciación (que usa **), es un XOR bit a bit. Las operaciones bit a bit tienen una precedencia muy baja en javascript, por lo que la división ocurrirá primero.
CRice
3
^es el operador xor bit a bit. Dudo que ^en el OP sea xor bit a bit cuando todos los demás operadores son operadores aritméticos. Probablemente sea el operador de exponenciación ( **en JavaScript).
Salman A
17

(((c/c)^c) - c) * (((c/c)^c) - c) siempre devolverá 1 para negativos y positivos y 0 para 0.

Definitivamente es más confuso que la respuesta elegida y más largo. Sin embargo, siento que es menos hacky y no depende de constantes.

EDITAR: Como menciona @JosephSible, una versión más compacta de la mía y la versión de @ CRice que no usa constantes es:

c/c^c-c
Kyle Wardle
fuente
La respuesta de CRice no fue elegida, Joseph Sible sí. Honestamente, no me di cuenta de la respuesta de CRice hasta después de la publicación.
Kyle Wardle
2
Sin embargo, no usa constantes, solo los operadores y la variable dada.
L3viathan
2
@JosephSible c/c^(c-c)es soloc
Tavian Barnes
2
@JosephSible Estaba leyendo ^como exponenciación como lo implica el OP "multiplicar, dividir, restar, sumar y exponente (*, /, -, +, ^ )". Si ^es XOR con su precedencia de JavaScript, entonces estoy equivocado. Pedí una aclaración sobre el PO.
Tavian Barnes
2
@TavianBarnes eso no es lo que escribió OP; alguien editó la pregunta. Lo restauré a la forma en que OP realmente lo pidió.
Joseph Sible-Reinstate Monica
2

Una respuesta muy complicada, pero que no depende de una precisión limitada: si toma x^(2**n), esto siempre será igual a x+2**nsi x es cero, pero será igual a x-2**nsi x tiene un uno en el enésimo lugar. Por lo tanto, para x = 0, (x^(2**n)-x+2**n)/(2**(n+1)siempre será 1, pero a veces será cero para x! = 0. Entonces, si toma el producto de (x^(2**n)-x+2**n)/(2**(n+1)todo n, entonces XOR eso con 1, obtendrá la función deseada. Sin embargo, tendrá que codificar manualmente cada factor. Y tendrás que modificar esto si estás usando puntos flotantes.

Si tiene el ==operador, entonces (x==0)^1funciona.

Acumulación
fuente
3
Ni **tampoco ==está disponible.
Joseph Sible-Reinstate Monica