【问题标题】:Imparting a number's sign onto another number?将一个数字的符号赋予另一个数字?
【发布时间】:2019-01-17 19:33:10
【问题描述】:

我正在寻找一种简洁的方法来获取一个数字的符号(正或负),并将其传递给另一个数字。

例如:

我们有两个数字,第一个是整数 1,第二个直到执行时才知道。
如果未知数小于0,我们的数就变成-1。
如果未知数大于等于0,我们的数就变成1。

如果我们的未知数是 X:


作为代码:

int before = AnyNonzeroInt(); //for this example we will choose 1.
int X = rand(Int32.Min, Int32.Max);
int after = ...

我个人使用的是 C# 4.5,但我相信一个好的解决方案是与语言无关的。

我可以想到几种方法,但都涉及 if-else-case 语句或三元运算符。我想要一种数学方法。

编辑:

我不反感三元运算符。但是,我正在处理的代码库有一套代码指南,不允许使用三元运算符,因为它们使代码更复杂(我知道我知道.. 我没有制定这个规则)。

但是,我相信我会在下一次团队会议上回答这个问题及其答案,这样我就可以展示我认为三元运算符的必要性。

【问题讨论】:

  • 我不明白你对三元组的厌恶。像(X < 0) ? -1 : 1 这样的表达式几乎不会编译成代码(汇编语言会在早餐时吃这样的比较(并将事情设置为 1 或 -1)。做浮点数学会掩盖你的意图,并且会慢得多
  • 未知数变零怎么办?
  • @RufusL,根据规则,之后将是1
  • 强制零的符号为正在数学上似乎不一致,但我知道您希望无论输入如何都设置结果的大小。您正在强制一种特殊情况(当X=0 时),但是要避免在这种情况下使用分支语句。 BTW Fortran 有两个参数 sign(x,y) 就是这样做的。

标签: c# math


【解决方案1】:
var after = (X < 0) ? -1 : 1;

这比一个部门便宜,你的意图也更清楚

【讨论】:

  • 我也喜欢这个,它也处理 X 为 0。虽然对于我来说,它应该是 gte 0。
  • 如果允许使用三进制,我会选择这个。 OP 专门要求一个数学函数
  • @Dylan >= 与
  • 这很容易成为一个函数(或Func&lt;double, int&gt;
【解决方案2】:
var after = X / Math.Abs(X);

将一个数除以自身得到 1,除以绝对值可确保符号不变。注意这里不处理 0 的情况(不想除以 0!)。可能需要一个 if 语句或三元组。

OP 注意到他的集合没有介于 0 和 -0.01 之间的数字,因此在除法之前将 0.00001 之类的小数添加到 X 可以解决 0 问题。

此外,正如其他答案/cmets 所提到的,这里对三元组的厌恶是奇怪的。一个简单的分支分配比加法和除法便宜得多。

【讨论】:

  • 太棒了!谢谢,我没有想到这个!
  • 如果我们正在寻找一种纯粹的数学方式来做到这一点(我就是这样)。我相信您可以通过事先向 X 添加一个非常小的浮点数来处理 0。比如X += .000001F
  • 我的计算只需要得到符号,它们不需要超过百分之一,因为我处理的数据是百分之一。
  • @Dylan 当 X 为 -.0000001F 时会发生什么? :)
  • Math.Abs 也使用了if 语句,不过...:D
【解决方案3】:

为什么不:

var after = Math.Sign(x)*before;

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-04
  • 2016-08-16
  • 2017-01-04
相关资源
最近更新 更多