类似于Math.Abs()的概念 - 我正在寻找一个函数,当给定正整数时将返回相同的整数。如果给出否定,则返回零。
所以:
f(3) = 3
f(0) = 0
f(-3) = 0
是的,这很简单,可以自己写,但我想知道.NET Math类是否已经内置了这个内容,或者是否可以通过巧妙地链接一些Math。*调用来实现相同的功能?
它被称为Math.Max
:
Math.Max(0, x)
这似乎是你想要的,不是吗?
Math.Max(0, num);
我认为
Math.Max(0, x)
是你想要的。
看起来像Math.Max是要走的路,但这也会起作用......;)
(num + Math.Abs(num)) / 2
Math.Max是最好的,但是没有Math和VB
(num >= 0) * -num
给定32位有符号整数num
,如果它是负数,则以下表达式返回零,否则返回原始未更改的值:
(~num >> 31) & num
这种操作有时称为夹紧;小于零的值被钳制为零。
只有正整数(和零)的符号位有0
,这是最左边的,或“最重要的位”(a.ka。,“MSB”)。让我们考虑一下32位的情况。由于位位置从0开始从左到右编号,因此符号位为“位31”。通过翻转该位然后将其传播到31个其他位位置中的每一个,您将获得以下结果:
0xFFFFFFFF
,-1
),或0x00000000
,0
)。通过masking得到这个结果的原始值,你已经将该值归零,但前提是它只是负数。
备注
&
(bitwise-AND
)在C#中的优先级非常低,因此通常必须用外括号括起这些表达式:
((~num >> 31) & num)
num
未签名(例如,uint ui
),则必须使用强制转换以确保转移已签名。这称为右算术移位,它确保MSB复制到每个向右移位的位置:
((int)~ui >> 31) & ui
/* signed */ long v; (~v >> 63) & v
/* unsigned */ ulong ul; ((long)~ul >> 63) & ul
~
(bitwise-NOT
)运算符来翻转符号位。如果您尝试使用“一元减去”-
,您将得到值0x80000000
的错误答案,因为这是两个整数值之一,不受应用减号影响。 (另一个是零,但无论哪种方式都可以正常工作)。另一方面,Bitwise-NOT
保证可以翻转任何/每个值的每一位。public static int Clamp0(this int v) => v & ~v >> 31;
public static long Clamp0(this long v) => v & ~v >> 63;
了解有关非分支代码的更多信息!
上面提供的这个代码示例是演示bit-twiddling的最简单的branchless code示例之一。如果您不熟悉它,该术语通常指的是各种微优化技术,这些技术试图最小化用户代码中的条件分支,以减少CPU管道中的错误预测停顿。