可以使用数学运算符*,/,+,-,^将非零数字转换为1吗?


118

我与软件(Oracle Siebel软件)仅支持与运营商JavaScript表达式乘法,除法,减,再加上工作,和XOR( ,*/-,)。+ ^我没有其他运营商,例如!? :没有。

使用上面的运算符,是否可以将数字转换为非零数字,如果已经为零,则将其保留为0?该数字可以为正,零或负。

例:

var c = 55;

var d;  // d needs to set as 1

我尝试过c / c,但它的计算结果是NaN何时c为0。何时为0 d需要c为0。

c是货币值,它将最多包含两个尾随数字和12个前导数字。

我试图if通过将数字转换为布尔值0或1 来模拟条件,然后将表达式的其他部分相乘。


3
评论不作进一步讨论;此对话已转移至聊天
塞缪尔·刘

10
@SamuelLiew尽管有很多评论,但其中一些应删除(讨论在评论中回答),但其中大多数实际上是需要澄清的(例如)。询问是否是XY问题的注释是边界。
user202729 '18 -10-26

甲骨文的Siebel数值运算,似乎是指数:docs.oracle.com/cd/E95904_01/books/VBLANG/...
德里克·默勒

2
@DerrickMoeller似乎Siebel VB和Siebel eScript之间存在区别。在后者中,它是按位异或。我不确定两者中的哪一个适用于此处。
CRice

3
@ user202729,一旦任何完整的注释线程过长,我们就不会分别对待注释,因为SE管理员/开发人员创建的mod界面更喜欢我们的默认操作为“移动聊天”或“全部删除”。如果有任何评论有用,则应将其编辑为问题本身或作为答案发布。如果有任何评论不合时宜,则应将其自行修剪/删除。如果您想讨论此mod“功能”和/或自动标记版主获得的“太多评论”,请务必在Meta或Meta.SE上进行讨论。谢谢。
塞缪尔·刘

Answers:


149

c / (c + 5e-324)应该管用。(常数5e-324Number.MIN_VALUE,最小的可表示正数。)如果x为0,则正好为0,并且x为非零值(从技术上讲,如果x至少为4.45014771701440252e-308,即x中允许的最小非零数)问题(0.01,是),JavaScript的浮点数学太不精确,以至于答案不能等于1,因此得出的结果恰好是1。


1
您需要先将表达式转换为bool,因为OP尝试将0和1与进行乘法运算other parts of the expression,但c / (c + 5e-324) * some_expression将不起作用
phuclv

28
抓住

1
@Medinoc没错,但问题也说,绝不会有小数点后超过2个位数,而324是一个很多比2多
约瑟夫锡布尔赫丁-恢复莫妮卡

1
这很有趣,并且可能适用于OP,但是我非常讨厌在团队中工作时遇到这种代码。至少应该对它进行充分的记录和测试。
埃里克·杜米尼尔

1
@JosephSible我知道,但是如果您真的那样做,最明显的答案应该是Number(Boolean(n)),它不使用任何运算符。我不是说这不是OP所寻找的答案,但这不是OP描述的问题的答案。也许应该改善问题。
user5532169

216

使用表达式n/n^0

如果n不为零:

 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.

如果n为零:

 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.

如您所见,所有非零值都转换为1,0保持为0。这利用了JavaScript中的NaN^0值为0 的事实。

演示:

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


45
TIL:Number.NaN ^ n === no_O(其中n是一个有限数)
zerkms,

17
似乎当用作按位操作数时,NaN很方便地将其转换为零。请参阅:对非数字进行按位运算
-CRice

3
@zerkms也许~~NaN === 0看起来更自然
Bergi

8
@EnricoBorba不是幂运算(使用**),它是按位XOR。按位运算在javascript中的优先级非常低,因此除法将首先发生。
CRice

3
^是按位异或运算符。^当所有其他运算符都是算术运算符时,我怀疑在OP中是否按位异或。它可能是幂运算符(**在JavaScript中)。
Salman A

17

(((c/c)^c) - c) * (((c/c)^c) - c) 将始终为负数和正数返回1,为0则返回0。

这肯定比选择的答案更混乱,而且时间更长。但是,我觉得它不太hacky,不依赖常量。

编辑:正如@JosephSible所提到的,我的更紧凑版本和不使用常量的@CRice版本是:

c/c^c-c

没有选择CRice的答案,约瑟夫·西布尔则选择了答案。老实说,直到发帖后我才注意到CRice的回答。
凯尔·沃德

2
但是,它不使用任何常量,仅使用运算符和给定的变量。
L3viathan

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

2
@JosephSible我正在阅读^OP所隐含的幂“乘,除,减,加和(*,/,-,+,^)”。如果^XOR具有JavaScript优先级,那么我错了。我要求对OP进行澄清。
塔维安·巴恩斯

2
@TavianBarnes不是OP写的;有人编辑了问题。我将其还原为OP实际要求的方式。
约瑟夫·西布尔-恢复莫妮卡

2

这是一个非常复杂的答案,但并不取决于精度的限制:如果采用x^(2**n),则总是等于x+2**nx如果为零,但是等于x-2**nx在第n位为1。因此,对于x = 0,(x^(2**n)-x+2**n)/(2**(n+1)将始终为1,但对于x!= 0,有时将为零。因此,如果取(x^(2**n)-x+2**n)/(2**(n+1)全部n 的乘积,然后将其与1进行XOR,则将获得所需的功能。不过,您必须手动编码每个因素。如果使用浮点数,则必须进行修改。

如果您有==运营商,那就(x==0)^1可以了。


3
无论是**也不==可用。
约瑟夫·西布尔-恢复莫妮卡
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.