Can mathematical operators *, /, +, -, ^ be used to convert a non-zero number to 1?

JavascriptSiebel

Javascript Problem Overview


I am working with software (Oracle Siebel) that only supports JavaScript expressions with operators multiply, divide, subtract, add, and XOR (*, /, -, +, ^). I don't have other operators such as ! or ? : available.

Using the above operators, is it possible to convert a number to 1 if it is non-zero and leave it 0 if it's already zero? The number may be positive, zero, or negative.

Example:

var c = 55;

var d;  // d needs to set as 1

I tried c / c , but it evaluates to NaN when c is 0. d needs to be 0 when c is 0.

c is a currency value, and it will have a maximum of two trailing digits and 12 leading digits.

I am trying to emulate an if condition by converting a number to a Boolean 0 or 1, and then multiplying other parts of the expression.

Javascript Solutions


Solution 1 - Javascript

Use the expression n/n^0.

If n is not 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.

If n is 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.

As you can see, all non-zero values get converted to 1, and 0 stays at 0. This leverages the fact that in JavaScript, NaN^0 is 0.

Demo:

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

Solution 2 - Javascript

c / (c + 5e-324) should work. (The constant 5e-324 is Number.MIN_VALUE, the smallest representable positive number.) If x is 0, that is exactly 0, and if x is nonzero (technically, if x is at least 4.45014771701440252e-308, which the smallest non-zero number allowed in the question, 0.01, is), JavaScript's floating-point math is too imprecise for the answer to be different than 1, so it will come out as exactly 1.

Solution 3 - Javascript

(((c/c)^c) - c) * (((c/c)^c) - c) will always return 1 for negatives and positives and 0 for 0.

It is definitely more confusing than the chosen answer and longer. However, I feel like it is less hacky and not relying on constants.

EDIT: As @JosephSible mentions, a more compact version of mine and @CRice's version which does not use constants is:

c/c^c-c

Solution 4 - Javascript

A very complicated answer, but one that doesn't depend on limited precision: If you take x^(2**n), this will always be equal to x+2**n if x is zero, but it will be equal to x-2**n if x has a one in the nth place. Thus, for x=0, (x^(2**n)-x+2**n)/(2**(n+1) will always be 1, but it will sometimes be zero for x !=0. So if you take the product of (x^(2**n)-x+2**n)/(2**(n+1) over all n, then XOR that with 1, you will get your desired function. You'll have to manually code each factor, though. And you'll have to modify this if you're using floating points.

If you have the == operator, then (x==0)^1 works.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionyasView Question on Stackoverflow
Solution 1 - JavascriptCRiceView Answer on Stackoverflow
Solution 2 - JavascriptJoseph Sible-Reinstate MonicaView Answer on Stackoverflow
Solution 3 - JavascriptKyle WardleView Answer on Stackoverflow
Solution 4 - JavascriptAcccumulationView Answer on Stackoverflow