可以使用数学运算符 *、/、+、-、^ 将非零数转换为 1 吗?
Posted
技术标签:
【中文标题】可以使用数学运算符 *、/、+、-、^ 将非零数转换为 1 吗?【英文标题】:Can mathematical operators *, /, +, -, ^ be used to convert a non-zero number to 1? 【发布时间】:2019-03-29 11:48:58 【问题描述】:我正在使用的软件 (Oracle Siebel) 仅支持带有运算符乘法、除法、减法、加法和 XOR 的 javascript 表达式(*
、/
、-
、+
、^
) .我没有其他可用的运算符,例如 !
或 ? :
。
使用上述运算符,是否可以将一个非零的数字转换为 1,如果它已经为零,则将其保留为 0?该数字可以是正数、零或负数。
例子:
var c = 55;
var d; // d needs to set as 1
我试过 c / c
,但当 c
为 0 时,它的计算结果为 NaN
。当 c
为 0 时,d
需要为 0。
c 是一个货币值,最多有两个尾数和 12 个前导数。
我试图通过将数字转换为布尔值 0 或 1,然后将表达式的其他部分相乘来模拟 if
条件。
【问题讨论】:
评论不用于扩展讨论;这个对话是moved to chat。 @SamuelLiew 虽然有很多 cmets,其中一些应该删除(discussion,answer in comment),但其中大部分是真的要求澄清(for example)。 Comments asking whether it's an XY problem 是边界。 Oracle Siebel 数字运算符,似乎是指数:docs.oracle.com/cd/E95904_01/books/VBLANG/… @DerrickMoeller 似乎 Siebel VB 和 Siebel eScript 之间存在区别。 In the latter, it is a bitwise xor。我不确定这两者中的哪一个适用于此。 @user202729 一旦整个评论线程变得太长,我们不会单独对待 cmets,因为 SE 管理员/开发人员创建的 mod 界面更喜欢我们的默认操作是“移动到聊天” ”或“全部删除”。如果任何评论有用,则应将其编辑到问题本身或作为答案发布。如果任何评论偏离主题,它们应该已经被自我修剪/删除。如果您想讨论这个模组“功能”和/或版主获得的“太多 cmets”自动标记,请在 Meta 或 Meta.SE 上提出讨论。谢谢。 【参考方案1】:使用表达式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.`))
【讨论】:
TIL:Number.NaN ^ n === n
o_O(其中n
是一个有限数)
似乎当用作按位操作数时,NaN
很方便地转换为零。见:Bitwise operations on non numbers
@zerkms 也许~~NaN === 0
看起来更自然
@EnricoBorba 这不是求幂(使用**
),它是按位异或。按位运算在 javascript 中的优先级非常低,因此首先会发生除法。
^
是按位异或运算符。当所有其他运算符都是算术运算符时,我怀疑 OP 中的 ^
是否是按位异或。它可能是幂运算符(JavaScript 中的**
)。【参考方案2】:
c / (c + 5e-324)
应该可以工作。 (常数5e-324
是Number.MIN_VALUE
,可表示的最小正数。)如果x 为0,那正好是0,如果x 不为零(从技术上讲,如果x 至少为4.45014771701440252e-308,其中最小的非- 问题中允许的零数字,0.01,是),JavaScript 的浮点数学太不精确,以至于答案与 1 不同,所以它会准确地得出 1。
【讨论】:
您需要先将表达式转换为 bool,因为 OP 试图将 0 和 1 与other parts of the expression
相乘,而 c / (c + 5e-324) * some_expression
将不起作用
发现了一个错误并将其变成了一个功能
@Medinoc 是的,但问题也说小数点后永远不会超过2位,而324比2多得多。
这很有趣,它可能适用于 OP,但我真的很讨厌在团队工作时遇到这种代码。至少,它应该有很好的文档记录和测试。
@JosephSible 我知道,但如果你真的这么认为,最明显的答案应该是Number(Boolean(n))
,它不使用任何运算符。我没有说这不是 OP 正在寻找的答案,但这不是 OP 所描述问题的答案。不过可能应该改进这个问题。【参考方案3】:
(((c/c)^c) - c) * (((c/c)^c) - c)
将始终返回 1 表示负数和正数,0 表示 0。
它肯定比选择的答案更令人困惑并且更长。但是,我觉得它不那么 hacky 并且不依赖于常量。
编辑:正如@JosephSible 提到的,我的一个更紧凑的版本和@CRice 的不使用常量的版本是:
c/c^c-c
【讨论】:
CRice 的答案未被选中,Joseph Sible 被选中。老实说,直到发布后我才注意到 Crice 的回答。 它不使用常量,只使用运算符和给定的变量。 @JosephSiblec/c^(c-c)
只是 c
@JosephSible 我正在阅读 ^
为 OP 所暗示的指数“乘、除、减、加和 指数(*、/、-、+、 ^)”。如果^
与其 JavaScript 优先级是异或,那么我错了。我要求澄清 OP。
@TavianBarnes 这不是 OP 写的;有人编辑了这个问题。我将其恢复为 OP 实际要求的方式。【参考方案4】:
一个非常复杂的答案,但不依赖于有限的精度:如果你取x^(2**n)
,如果 x 为零,这将始终等于 x+2**n
,但如果 x 为零,它将等于 x-2**n
x 在第 n 位有一个。因此,对于 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 进行异或运算,您将获得所需的函数。不过,您必须手动编码每个因素。如果您使用浮点数,则必须对其进行修改。
如果您有 ==
运算符,则 (x==0)^1
有效。
【讨论】:
**
和 ==
都不可用。以上是关于可以使用数学运算符 *、/、+、-、^ 将非零数转换为 1 吗?的主要内容,如果未能解决你的问题,请参考以下文章