可以使用数学运算符 *、/、+、-、^ 将非零数转换为 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-324Number.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 的回答。 它不使用常量,只使用运算符和给定的变量。 @JosephSible c/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 吗?的主要内容,如果未能解决你的问题,请参考以下文章

[AI开发]零数学公式告诉你什么是(卷积)神经网络

为啥 C# 允许在浮点类型中将非零数除以零?

[转] Unity Mathf 数学运算(C#)

CF Educational Round 83

Shell 基本运算符(转)

(转)Shell——基本运算符