出于好奇,是否有办法获得数字的符号,任何类型(但显然是签名类型),而不仅仅是使用某种按位/屏蔽或其他类型的操作的整数? 这是不使用任何条件语句或调用Math.Sign()函数。
提前致谢!
编辑:我认为这是一个误导性的问题。我想到的更像是:"得到Math.Sign()的相同输出,或者,如果x< = 0则简化得到0,否则为#34;
编辑#2 :对于所有要求代码的人,我在发布问题时没有考虑过一些问题,但这是我提出的一个例子,只是为了给出一个可能的应用程序的上下文:
x = (x < 0) ? 0 : x;
将符号转换为变量可能会导致:
x = sign * x; //where sign = 0 for x <= 0, otherwise sign = 1;
目标是获得与上述相同的结果:)
// THIS IS NOT MEANT TO BE PLAIN C#!
// Returns 0 if x <= 0, 1 otherwise.
int SignOf(x)
{
return (1+x-(x+1)%x)/x;
}
感谢大家!
答案 0 :(得分:2)
有没有办法得到一个数字的符号(任何种类,而不仅仅是整数)
不是任何数字类型,不是。对于整数,您可以测试最高位:如果为1,则该数字为负。理论上,您可以使用浮点数执行相同操作,但按位运算符不适用于float
或double
。
答案 1 :(得分:0)
要获取符号,您可以避免使用条件运算符,如下面的int32结构的符号扩展中所示。但要获得名称我不认为你可以避免条件运算符
class Program
{
static void Main(string[] args)
{
Console.WriteLine(0.Sign());
Console.WriteLine(0.SignName());
Console.WriteLine(12.Sign());
Console.WriteLine(12.SignName());
Console.WriteLine((-15).Sign());
Console.WriteLine((-15).SignName());
Console.ReadLine();
}
}
public static class extensions
{
public static string Sign(this int signedNumber)
{
return (signedNumber.ToString("+00;-00").Substring(0, 1));
}
public static string SignName(this int signedNumber)
{
return (signedNumber.ToString("+00;-00").Substring(0, 1)=="+"?"positive":"negative");
}
}
答案 2 :(得分:0)
这取决于您定位的数字值类型。
对于签名 Integers C#,大多数计算机系统使用所谓的Ones' complement表示。
这意味着符号存储在值的第一位。
所以你可以提取这样的符号:
Int16 number = -2;
Int16 sign = (number & Int16.MinValue) >> 16;
Boolean isNegative = Convert.ToBoolean(sign);
请注意,到目前为止,我们还没有使用任何条件运算符(显然无论如何)
但是:你仍然不知道这个数字是否有迹象。
你问题的逻辑等价物:“我怎么知道,如果我的号码是否定的?”在所有条件。
之后,明确要求使用条件运算符所以你将无法躲闪:
if(isNegative)
doThis();
else
doThat();
答案 3 :(得分:0)
这是一个适用于所有值类型(int、float、double、decimal...等)的“零安全”解决方案:
(value.GetHashCode() >> 31) + 1;
输出:1 = 1, -1 = 0, 0.5 = 1, -0.5 = 0, 0 = 1
它也比 C# 中的 (1+x-(x+1)%x)/x;
便宜大约 10%。此外,如果“value”是一个整数,您可以删除 GetHashCode() 函数调用,在这种情况下,(1+x-(x+1)%x)/x;
的成本高 127%((value >> 31) + 1;
的成本低 56%)。
由于 0 是正数,因此对于正数的结果为 1 而对于 0 的结果为 0 是不合逻辑的。如果您可以参数化 -0,您将得到 0 的输出。
我知道 GetHashCode() 是一个函数调用,但该函数在 C# 语言实现中的内部工作完全是“算术”。基本上 GetHashCode() 函数读取内存部分,将您的浮点类型存储为整数类型:
*((int*)&singleValue);
GetHashCode 函数的工作原理(我能快速找到的最佳来源)- https://social.msdn.microsoft.com/Forums/vstudio/en-US/3c3fde60-1b4a-449f-afdc-fe5bba8fece3/hash-code-of-floats?forum=netfxbcl
如果您希望输出值为 1 且与输入的符号相同,请使用:
((float.GetHashCode() >> 31) * 2) + 1;
上述浮点方法比 System.Math.Sign(float)
便宜大约 39%(System.Math.Sign(float)
大约贵 65%)。 System.Math.Sign(float)
为 float.NaN 抛出异常,((float.NaN.GetHashCode() >> 31) * 2) + 1;
不会并且将返回 -1 而不是崩溃。
或整数:
((int >> 31) * 2) + 1;
上述整数方法比 System.Math.Sign(int)
便宜大约 56%(System.Math.Sign(int)
大约贵 125%)。
答案 4 :(得分:-1)
if x==0
,您将有divby0 exception
,其中包含您发布的代码:
int SignOf(x) {
return (1+x-(x+1)%x)/x; }