(Translated by https://www.hiragana.jp/)
位操作 - 维基百科,自由的百科全书 とべ转到内容ないよう

くらい操作そうさ

本页使用了标题或全文手工转换
维基百科ひゃっか自由じゆうてき百科ひゃっかぜん
重定しげさだこう按位ある

くらい操作そうさこれほどじょ设计ちゅうくらいすうある进制すうてきいちげんもと操作そうさざい许多古老ころうてきほろ处理うえ运算减运さんりゃくかい通常つうじょう运算乘除じょうじょほう运算ようかい很多。ざい现代构中,运算てき运算速度そくど通常つうじょうあずか加法かほう运算しょうどう(仍然かい于乘ほう运算),ただし通常つうじょうこう耗较しょういん为资げん使用しよう减少。[1]

くらい运算

[编辑]

下面かめんてきかい释中,にんなん二进制位的表示都从右侧(最低さいてい)开始计数,こうひだり进。举个れい进制值0001(じゅう进制1)じょだいいちそくさいみぎ边)まいうえ0。

はん(NOT)

[编辑]

はんこれ一元いちげん运算,对一个二进制数的每一位执行逻辑はん操作そうさ使つかい数字すうじ1なり为0,0なり为1。れい如:

NOT 0111(じゅうしん7)
  = 1000(じゅうしん8)
NOT 10101011  (じゅう进制 171)
  = 01010100  (じゅう进制 84)

结果とう于该值的补码减一。如果使用しよう补码さん术,则 NOT x = -x − 1

对于无符ごう整数せいすうすうてき按位补码其在无符ごう整数せいすう范围てき中点ちゅうてん另一边的“镜像”。れい如,对于8无符ごう整数せいすうNOT x = 255 - x以在图上はた其可视化为いちじょうむこうてき线,相当そうとう于把从 0 いた 255 递增てき范围,“こぼし转”いた从 255 いた 0 递减てき范围。一个简单而有说明性的使用例子是反转灰度图像,其中ごと个像もとそん储为无符ごう整数せいすう

许多ほどじょ设计语言(包括ほうかつC语言家族かぞく),はん操作そうさよう波浪はろう线"~"表示ひょうじ。值得注意ちゅういてき操作そうさあずか“逻辑!)”操作そうさ不同ふどうざいC++ちゅう,逻辑しょう数字すうじ整体せいたい做一个ぬの尔类がた——はた值转为假,はたかり值转为真;而C语言しょう0转化为1,はたれい值转为0。“逻辑”并不いち个位操作そうさ

thumb
4整数せいすう按位ある

按位ある(OR)

[编辑]

按位ある处理两个长度しょうどうてき进制すう,两个しょう应的二进位中只要有一个为1,该位てき结果值就为1。れい

   0101じゅう进制5)
OR 0011じゅう进制3)
 = 0111じゅう进制7)

ざいC类程じょ设计语言ちゅう,按位ある操作そうさ"|"。这一操作符需要与逻辑或运算符(||)别开らい

按位あるのう够将ごといちはたざい二进制数中的每一位可以表示不同的布尔变量。应用按位ある操作そうさ以将二进制数的某一位设为1。れい

0010(じゅう进制2)

のう够看做包含ほうがん4个旗标的组合。だい1,2,4はた标为0;だい3个旗标为1。利用りよう按位ある以将だい1个旗标设おけ为1,而其はた标不变。

   0010(じゅう进制2)
OR 1000(じゅう进制8)
 = 1010(じゅう进制10)

这一技巧通常用来保存程序中的大量布尔变量。

thumb
4整数せいすう按位异或

按位异或(XOR)

[编辑]

按位异或运算,对等长二进制模式或二进制数的每一位执行逻辑异或操作そうさ操作そうさてき结果如果ぼう不同ふどう则该为1,いや则该为0。れい

    0101
XOR 0011
  = 0110

ざい类C语言ちゅう,按位异或运算"^"。

汇编语言てきほどじょ员们ゆう使用しよう按位异或运算さく为将よせそんてき值设为0てき捷径しょうけいよう值的自身じしん对其执行按位异或运算はたいた0。并且ざい许多构中,あずか直接ちょくせつ载0值并はた保存ほぞんいたよせそんしょう,按位异或运算需要じゅよう较少てき中央ちゅうおう处理单元时钟周期しゅうき

按位异或也可以用于在特集とくしゅうあいちゅうきりはた标。给出一个比特模式,

0010

だい一和第三位能够通过按位异或运算使用同时切换。

    0010
XOR 1010
  = 1000

这一技巧可用于操作表示布尔变量的比特模式。

thumb
4整数せいすう按位あずか

按位あずか(AND)

[编辑]

按位あずか处理两个长度しょうどうてき进制すう,两个しょう应的二进位都为1,该位てき结果值才为1,いや则为0。れい如:

    0101
AND 0011
  = 0001

操作そうさ以被ようらい检查一个特定的位是1还是0。れい如,给定一个二进制模式0011(じゅう进制3),わが们用按位あずか一个仅在第二位为1てき二进制模式来确定第二位是否为1:

    0011 (じゅう进制 3)
AND 0010 (じゅう进制 2)
  = 0010 (じゅう进制 2)

いん为结はて0010是非ぜひれいてき所以ゆえんわが们知道原どうばらしきちゅうてきだい1。这通常つうじょうしょうくらい掩码。(类似てき使用しよう纸胶带くつがえ盖不应更改こうかいてき部分ぶぶんある不感ふかん兴趣てき部分ぶぶんざい这种じょう况下,0 值会へい蔽不かん兴趣てき。)

按位あずか可用かよう于清じょよせそんてき定位ていいあるはた),其中ごと个位代表だいひょういち个单どくてきぬのじょう态。 这种わざ术是一种使用尽可能少的内存来存储大量布尔值的有效方法。

れい如,0110(じゅう进制 6)以被认为一组四个旗标,其中だい一个和第四个旗标是清除 (0),だい二和第三个旗标是设置 (1)。 だい三个旗标可以通过按位与仅在第三位具有零的模式来清除:

    0110 (じゅう进制 6)
AND 1011 (じゅう进制 11)
  = 0010 (じゅう进制 2)

いん为这じょうせい质,つう过查询最低位ていいてき值检查一个二进制数的奇偶きぐうせい变得容易よういよう以上いじょうてきれい

    0110 (じゅう进制 6)
AND 0001 (じゅう进制 1)
  = 0000 (じゅう进制 0)

いん为6按位あずか10,6以被2整除せいじょ所以ゆえん6偶数ぐうすう

ざい类C语言ちゅう,按位あずかよう'&'表示ひょうじ

数学すうがくとう价物

[编辑]

かり,对于负整すう,按位运算以被うつしなり如下形式けいしき

所有しょゆう二元逻辑运算符的真值表

[编辑]

两个进制变量えいBinary dataゆう16种可能かのうてき值函すう;这定义了いち值表

这是两位 P Q てき按位とうこう运算:

p q 矛盾むじゅん0 逻辑ある1 ぎゃく蕴含えいConverse nonimplication2 p3 实质蕴涵4 q5 逻辑异或6 逻辑あずか7 逻辑あずか8 逻辑异或えいLogical biconditional9 qえいProjection (set theory)10 实质条件じょうけん11 pえいProjection (set theory)12 ぎゃくいのち13 逻辑ある14 つねしんしき15
1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
1 0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
0 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1
0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
按位

とうこう

0 NOT
(p OR q)
(NOT p)
AND q
NOT
p
p AND
(NOT q)
NOT
q
p XOR q NOT
(p AND q)
p AND q NOT
(p XOR q)
q (NOT p)
OR q
p p OR
(NOT q)
p OR q 1

うつり

[编辑]

うつり一个二元运算符,ようらいはた一个二进制数中的每一位全部都向一个方向移动指定位,溢出てき部分ぶぶんはたしゃ弃,而空かけてき部分ぶぶんはまにゅう一定いっていてき值。ざい类C语言ちゅうひだりうつり使用しよう两个しょう于符ごう"<<"表示ひょうじみぎうつり使用しよう两个だい于符ごう">>"表示ひょうじ

くらい寻址

[编辑]
thumb
さん术左うつり
thumb
さん术右うつり

如果よせそんてき宽度(通常つうじょう为 32 甚至 64)だい最小さいしょう寻址单元(通常つうじょうしょう为字节)てきすう通常つうじょう为 8),则移操作そうさかい促使从字节到てき寻址策略さくりゃくよし此,进位せいてき标准数字すうじ书写ちゅうひだりかずみぎ方向ほうこう使つかいとくひだりうつり增加ぞうか数字すうじてき值,みぎうつり减少数字すうじてき值——如果さき读取ひだりすう,这就だいはし节序。ゆるがせりゃくよせそん两端てき边界こう应,さん术和逻辑うつり操作そうさてきぎょう为相どううつり动 8 しょうしき转移 1 个字节位置いち方式ほうしき如下:

  • しょうはしじょひだりうつり 8 个位置いち节地 1;みぎうつり 8 个位置いち节地减 1。
  • だいはしじょひだりうつり 8 个位置いち节地减 1;みぎうつり 8 个位置いち节地 1。

さん术移

[编辑]

ざいさん术移なか,溢出两端てき丢弃。さん术左うつりちゅうみぎ侧补じょう0;ざん术右うつりちゅうひだり侧补じょう符号ふごうえいSign bit(补码ちゅうてき最高さいこう),以保持ほじばらすうてき符号ふごう变。

这个れい使用しよういち个8よせそんかい释为补码:

   00010111 (じゅう进制 +23) LEFT-SHIFT
=  00101110 (じゅう进制 +46)
thumb
逻辑ひだりうつり
thumb
逻辑みぎうつり
   10010111 (じゅう进制 −105) RIGHT-SHIFT
=  11001011 (じゅう进制 −53)

ざいだいいち种情况下,さいひだり边的数字すうじうつりいたよせそんてき末尾まつびしんてき 0 うつりいたさいみぎ边的位置いちざいだい种情况下,さいみぎ边的 1 移出いしゅつ可能かのう进入りょう进位标志えいCarry flag),いち个新てき 1 复制いたさいひだり边的位置いち保留ほりゅうりょう数字すうじてき符号ふごう个移ゆう时会缩短为一个移,减少りょう几位。 れい如:

   00010111 (decimal +23) LEFT-SHIFT-BY-TWO
=  01011100 (decimal +92)

さん术左うつりnとう价与じょう以2n (前提ぜんてい值没ゆう整数せいすう溢出)。いち补码てき值算术右うつりn とう价与じょ以2n 下取したどりせい。如果二进制数被视为いちてき补码,则相どうてきみぎうつり运算かい导致じょ以2n こうれいしゃいれ

逻辑うつり

[编辑]

应用逻辑うつり时,うつりきさきそらかけてき部分ぶぶん全部ぜんぶはま0。よし此,逻辑ひだりうつり和算わさん术左うつり完全かんぜんしょうどう

ただしゆかり于逻辑右うつりしょう值 0 插入そうにゅう最高さいこう,而不复制符号ふごういん此它适用于无符号ふごう进制すう,而算术右うつり适用于有符号ふごう补码进制すう

   0001(じゅう进制1)
<<    3(ひだりうつり3)
 = 1000(じゅう进制8)
   1010(じゅう进制10)
>>    2(みぎうつり2)
 = 0010(じゅう进制2)

循环うつり

[编辑]

另一种移位是循环移位。

thumb
循环ひだりうつある旋转
thumb
循环みぎうつある旋转

旋转

[编辑]

ざい此操作中さくちゅうゆう时称为循环无进“旋转”,就好ぞうよせそんてき左端ひだりはしみぎはし连接ざいいちおこりいち样。 ざいひだりうつり移入いにゅうみぎ侧的值是从左侧移出いしゅつてきにんなん值,みぎうつり操作そうさ时反またしか。 如果需要じゅよう保留ほりゅう所有しょゆう现有,这很有用ゆうよう,并且它经常用じょうよう数字すうじみつ码学なか

thumb
进位ひだり
thumb
进位みぎ

进位旋转

[编辑]

进位旋转一种旋转操作的变种,其中移入いにゅう在任ざいにんいちはしてき进位标志てききゅう值,移出いしゅつてきざい另一はしなり为进标志てきしん值。

一个简单的进位旋转可以模拟逻辑和算术移位,ただ需提ぜん设置こう进位标志。如,如果进位标志0,x RIGHT-ROTATE-THROUGH-CARRY-BY-ONE逻辑みぎうつりいち;如果进位标志さと符号ふごうてき拷贝,x RIGHT-ROTATE-THROUGH-CARRY-BY-ONEさん术右うつりいちよし为这些原因げんいん,一些微控制器像低端PICほろひかえせいただゆう旋转进位旋转,并不担心さん术或逻辑うつり

とう对大于处てきほんつくえてき数字すうじ执行うつり时,进位旋转とく别有よういん为如はて一个大数存储在两个寄存器中,从第いち个寄そんてき一端移出的位必须在另一端进入第二个寄存器。使用しよう循环进位时,该位ざいだい一次移位期间“保存ほぞんざい进位标志ちゅうじゅん备在だい二次移位期间移入而无需任何额外准备。

在高ありだか级语ごとちゅう

[编辑]

类C语言Python

[编辑]

ざいるいCげんPythonなか,逻辑うつり运算ひだりうつり<<かずみぎうつり>>”。うつりてき位置いちすうさく为运さんてきだい个参すう给出。れい如,

x = y << 2;

はたx赋值为yひだりうつり两位てき结果,其等价于じょう以四。

うつり可能かのう导致实现てい义的ぎょう为或未定みてい义行为いん此在使用しよう它们时必须小しんざい C C++ ちゅううつりだい于或とう于字大小だいしょうてきすう未定みてい义的ぎょう为。[2]みぎうつり负值实现てい义的,ただし良好りょうこうてき编码实践けん议这样做;[3]如果结果无法ざい结果类型ちゅう表示ひょうじ,则左うつりゆう符号ふごう值的结果未定みてい义的。[4]

ざい C# ちゅうとうだい一个操作数是整形或长整形时,みぎうつりさん术移。 如果だい一个操作数是无符号整形或无符号长整形,则右うつり逻辑うつり[5]

Java

[编辑]

JAVA中有ちゅうう一个特有的无符号右移操作符“>>>”。此操さくはたゆるがせりゃく操作そうさすうてき符号ふごうどう样的还有“>>>=”。

JavaScript

[编辑]

JavaScript使用しよう按位运算はた两个ある数字すうじなかてきごといち个求值为 1 ある 0。[6]

Pascal

[编辑]

ざい Pascal 及其所有しょゆう方言ほうげんちゅう(如 Object Pascal Standard PascalえいGNU Pascal),逻辑ひだりうつり运算みぎうつり运算ぶん别是“shlかずshr”。 そく使つかい对于ゆう符号ふごう整数せいすうshr てきぎょう为也类似于逻辑移,并且かい复制符号ふごうよううつり动的位置いちすうさく为第个参すう给出。 れい如,下面かめんしょう y ひだりうつり两位てき结果赋值给 x:

x := y shl 2;

其他

[编辑]

应用

[编辑]

くらい运算必要ひつようてきゆう其是ざい设备驱动ほどじょてい级图がた通信つうしん协议つつみ组装和解わかい码等てい级编ほどちゅう

つきかんつくえ通常つうじょう具有ぐゆう执行さん术和逻辑运算てき有效ゆうこうないおけ指令しれいただし所有しょゆう这些运算以通过以かく种方しき组合按位运算れい测试らい执行。[7]れい如,这里埃及えじぷと乘法じょうほうえいAncient Egyptian multiplicationてき伪代码实现,展示てんじりょう如何いか使用しよううつり加法かほうはた两个任意にんい整数せいすう a ba だいb相乘そうじょう

c  0
while b  0
    if (b and 1)  0
        c  c + a
    left shift a by 1
    right shift b by 1
return c

另一个例子是加法的伪代码实现,展示てんじりょう如何いか使用しよう按位运算れい测试计算两个整数せいすう a b てき

while a  0
    c  b and a
    b  b xor a
    left shift c by 1
    a  c
return b

参考さんこう

[编辑]
  1. ^ CMicrotek Low-power Design Blog. CMicrotek. [2015-08-12]. (原始げんし内容ないようそん于2015-08-20). 
  2. ^ Arithmetic operators - cppreference.com. en.cppreference.com. [2016-07-06]. (原始げんし内容ないようそん于2022-08-08). 
  3. ^ INT13-C. Use bitwise operators only on unsigned operands. CERT: Secure Coding Standards. Software Engineering Institute, Carnegie Mellon University. [2015-09-07]. (原始げんし内容ないようそん于2016-04-22). 
  4. ^ JTC1/SC22/WG14 N843 "C programming language"页面そん档备份そん互联网档あん), section 6.5.7
  5. ^ Operator (C# Reference). Microsoft. [2013-07-14]. (原始げんし内容ないようそん于2017-07-06). 
  6. ^ "JavaScript Bitwise"页面そん档备份そん互联网档あん). W3Schools.com.
  7. ^ Synthesizing arithmetic operations using bit-shifting tricks. Bisqwit.iki.fi. 2014-02-15 [2014-03-08]. (原始げんし内容ないようそん于2014-03-08).