Math 位运算符(移位除外)在10进制中有数学意义吗?

Math 位运算符(移位除外)在10进制中有数学意义吗?,math,bit-manipulation,Math,Bit Manipulation,根据班次可用于计算2的功率: 左算术移位n为 等于乘以2^n (前提是该值不 溢出),而这是一个正确的算法 2的补码值移位n 等于除以2^n和 向负无穷大舍入 我一直在想,当应用于base-10时,是否有任何其他位运算符(~,|,&,^)具有数学意义?我了解它们是如何工作的,但这些运算的结果可以用来计算十进制世界中有用的任何东西吗?您可以只使用位运算符来计算对数 是的,还有其他有用的操作,但它们往往面向涉及2次幂的操作(出于明显的原因),例如奇数/偶数测试、2次幂测试、向上/向下取整到最接近的2

根据班次可用于计算2的功率:

左算术移位n为 等于乘以2^n (前提是该值不 溢出),而这是一个正确的算法 2的补码值移位n 等于除以2^n和 向负无穷大舍入


我一直在想,当应用于base-10时,是否有任何其他位运算符(
~
|
&
^
)具有数学意义?我了解它们是如何工作的,但这些运算的结果可以用来计算十进制世界中有用的任何东西吗?

您可以只使用位运算符来计算对数


是的,还有其他有用的操作,但它们往往面向涉及2次幂的操作(出于明显的原因),例如奇数/偶数测试、2次幂测试、向上/向下取整到最接近的2次幂等


请参见Henry S.Warren。

在我使用的每种语言中(必须承认,几乎完全是C和C-导数),按位运算符都是完全的整数运算(当然,除非重写该运算)

虽然您可以旋转十进制数的位(毕竟它们有自己的位),但不一定会得到与旋转整数位相同的结果。有关十进制数中位的说明,请参见和。有关位旋转十进制数的有利用法示例,请参见

n << 1 == n * 2
n << 2 == n * 4
n << 3 == n * 8

n >> 1 == n / 2
n >> 2 == n / 4
n >> 3 == n / 8

n & 1 == {0, 1}       // Set containing 0 and 1
n & 2 == {0, 2}       // Set containing 0 and 2
n & 3 == {0, 1, 2, 3} // Set containing 0, 1, 2, and 3

n | 1 == {1, n, n+1}
n | 2 == {2, n, n+2}
n | 3 == {3, n, n+1, n+2, n+3}
编辑

对于整数,按位操作总是有意义的。按位运算是为整数设计的

n << 1 == n * 2
n << 2 == n * 4
n << 3 == n * 8

n >> 1 == n / 2
n >> 2 == n / 4
n >> 3 == n / 8

n & 1 == {0, 1}       // Set containing 0 and 1
n & 2 == {0, 2}       // Set containing 0 and 2
n & 3 == {0, 1, 2, 3} // Set containing 0, 1, 2, and 3

n | 1 == {1, n, n+1}
n | 2 == {2, n, n+2}
n | 3 == {3, n, n+1, n+2, n+3}
n>2==n/4
n>>3==n/8
n&1=={0,1}//包含0和1的集
n&2=={0,2}//包含0和2的集
n&3=={0,1,2,3}//包含0,1,2和3的集
n | 1=={1,n,n+1}
n | 2=={2,n,n+2}
n | 3=={3,n,n+1,n+2,n+3}

以此类推。

有时您可以用按位运算代替布尔运算。例如,以下代码:

if ((a < 0) && (b < 0) { do something { 如果((a<0)和&(b<0) { 做点什么 { 在C中,这可以替换为:

if ((a & b) < 0) { do something { 如果((a&b)<0) { 做点什么 { 这是因为整数中的一位用作符号位(1表示负数)。and运算(a&b)将是一个无意义的数字,但其符号将是数字符号的按位and,因此检查结果的符号将起作用

这可能对性能有好处,也可能没有好处。在许多体系结构和编译器上执行两个布尔测试/分支会更糟糕。现代x86编译器可能会使用一些较新的指令生成一个分支,即使使用正常语法

和往常一样,如果它确实导致性能提高……对代码进行注释——也就是说,在注释中使用“正常”的方式,并说它是等效的,但速度更快

同样地,~|和^也可以以类似的方式使用,所有条件都是(x) 以10为基数的等价物为(再次注意,这些数字是按位数计算的,而不是按整数计算的)

a&b=a*b(模块10) a^b=a+b(模块10) ~a=9-a(模10) a | b=~(a&~b)=9-(9-a)*(9-b)(mod 10)
在设计使用(
~a
作为,例如非图形计算器,尽管我们只是使用
*
+
而不是
&
^
来编写方程。第一个显然也用于中。

在不使用临时变量的情况下交换两个整数的有趣技巧是使用位异或:

void swap(int &a, int &b) {
   a = a ^ b;
   b = b ^ a; //b now = a
   a = a ^ b; //knocks out the original a
}

这是因为XOR是可交换的,所以a^b^b=a。

是的。您可以使用按位and和(2^n-1)计算2(2^n)幂的余数。我把这个问题理解为“按位运算符在基数10中有任何有意义的表示吗?”但似乎其他人都认为这是关于浮点数的。@BlueRaja yep base-10是我的意思,也许这个问题的措辞不好?@serg没有真正回答你的问题,但每当我需要使用十进制快速计算二进制运算符时,我都会使用这个网站:我想你把十进制和浮点混淆了——它们是不一样的事情-整数可以是十进制。你提出了一个有趣的观点。实际上,有更好的理由来拆分
浮点的位,而不是
int
。@Paul R:我假设serg谈论的是非整数,因为你可以输入十进制、十六进制、八进制或二进制的整数在许多语言中,二进制表示是相同的,它们仍然是整数。(如果您在没有任何特殊考虑的情况下输出值,大多数语言将使用十进制,无论您为输入编写了什么)布莱恩:是的,我想这个问题有点模棱两可。通常人们会说“浮点”(或“定点”或其他什么)如果他们谈论的是整数以外的数字类型。那么,是的,逐位运算总是有意义的。逐位运算是为整数设计的,而不考虑基数。
n或者,你也可以将&视为最小值,|视为最大值,~又视为补码。从数学上讲,这会给你一个晶格而不是一个环。Al遗憾的是,大多数类型化语言不允许您对非整数执行XOR。这很遗憾……否则,它会允许您交换任何内容。@SamDufel:实际上它只交换任何内容的按位表示。任何包含内部指针的结构(例如,在字符串类型的短字符串优化中,数据结构的一部分指向另一部分)会中断,因为现在指针会指向另一个对象。@SamDufel:我想说的是,你声称“它可以让你交换任何东西”是错的。我相信你错了,但我不认为关于什么是“交换”的学究式争论
x = ((a < b) << 2) | ((b < c) << 1) | (c < a);
switch (x):
"yep base-10 is what I mean"
a & b = a * b (mod 2)
a ^ b = a + b (mod 2)
   ~a = 1-a   (mod 2)
a | b = ~(~a & ~b) = 1 - (1-a)*(1-b) (mod 2)
a & b = a * b (mod 10)
a ^ b = a + b (mod 10)
   ~a = 9-a   (mod 10)
a | b = ~(~a & ~b) = 9 - (9-a)*(9-b) (mod 10)
void swap(int &a, int &b) {
   a = a ^ b;
   b = b ^ a; //b now = a
   a = a ^ b; //knocks out the original a
}