第十七天:原碼、反碼、補碼與位運算

原碼、反碼、補碼與位運算

一、原碼、反碼、補碼

1、原碼

  • 定義:原碼是一種簡單的機器數表示法。對于一個有符號整數,最高位為符號位, 0 表示正數, 1 表示負數,其余位表示數值的絕對值。
  • 示例:以 8 位二進制為例, +5 的原碼是 00000101 , -5 的原碼是 10000101 。
  • 問題:原碼在進行加減法運算時比較復雜,因為要根據符號位判斷是加法還是減法,并且對于 0 有兩種表示形式( +0 : 00000000 , -0 : 10000000 ),這給計算機處理帶來不便。

2、反碼

  • 定義:正數的反碼與原碼相同;負數的反碼是在原碼的基礎上,符號位不變,其余各位取反。
  • 示例:還是以 8 位二進制為例, +5 的反碼是 00000101 , -5 的原碼是 10000101 ,其反碼則為 11111010 。
  • 作用:反碼主要是作為從原碼到補碼的過渡。雖然它解決了 0 的表示不唯一問題( +0 和 -0 的反碼都是 00000000 ),但在加減法運算上仍不夠理想。

3、補碼

  • 定義:正數的補碼與原碼相同;負數的補碼是在反碼的基礎上,末位加 1 。

  • 示例:同樣 8 位二進制, +5 的補碼是 00000101 , -5 的反碼是 11111010 ,其補碼則為 11111011 。

  • 優勢:補碼在計算機中得到廣泛應用,它解決了原碼和反碼在運算上的不足。在補碼系統中, 0 只有一種表示形式( 00000000 )。而且使用補碼進行加減法運算時,不需要額外判斷符號位,可以直接將符號位和數值位一起參與運算,簡化了運算規則,提高了運算效率。例如,計算 5 + (-3) , 5 的補碼是 00000101 , -3 的補碼是 11111101 ,兩者相加:

    00000101

  • 11111101

100000010

由于是 8 位二進制,最高位的 1 溢出被舍棄,結果為 00000010 ,即 2 ,運算結果正確。

  • 原碼是最直觀的有符號數表示方法,但運算復雜且 0 的表示不唯一。
  • 反碼是從原碼到補碼的過渡,一定程度上解決了 0 的表示問題,但運算仍不夠簡便。
  • 補碼克服了原碼和反碼的缺點,成為計算機中表示有符號整數的標準方式,極大地簡化了運算邏輯,提高了計算機處理有符號整數運算的效率。

二、位運算

1. 位與( & )

  • 運算規則:對兩個整數的二進制表示中每一位進行比較,只有當兩個對應位都為 1 時,結果位才為 1 ,否則為 0 。
  • 示例代碼:
 
#include <iostream>int main() {int num1 = 10; // 二進制: 1010int num2 = 6;  // 二進制: 0110int result = num1 & num2;std::cout << num1 << " & " << num2 << " = " << result << std::endl;// 計算過程://  1010// & 0110// ------//  0010  結果為2return 0;
}
  • 應用場景:
  • 掩碼操作:通過與一個特定的掩碼值進行位與操作,可以提取或保留某些位。例如,要獲取一個字節(8位)的低4位,可以與掩碼 0x0F (二進制 00001111 )進行位與操作。
  • 判斷奇偶性:與 1 進行位與操作,如果結果為 1 ,則該數為奇數;如果結果為 0 ,則為偶數。因為奇數的二進制最低位是 1 ,偶數的二進制最低位是 0 。

2. 位或( | )

  • 運算規則:對兩個整數的二進制表示中每一位進行比較,只要兩個對應位中有一個為 1 ,結果位就為 1 ,只有當兩個對應位都為 0 時,結果位才為 0 。
  • 示例代碼:
#include <iostream>int main() {int num1 = 10; // 二進制: 1010int num2 = 6;  // 二進制: 0110int result = num1 | num2;std::cout << num1 << " | " << num2 << " = " << result << std::endl;// 計算過程://  1010// | 0110// ------//  1110  結果為14return 0;
}

應用場景:

  • 設置標志位:如果要將一個整數的某些位設置為 1 ,可以與一個相應位為 1 的掩碼進行位或操作。例如,要將一個整數的第3位和第5位設置為 1 ,可以與掩碼 0x28 (二進制 00101000 )進行位或操作。
  • 合并數據:在處理一些標志集合時,可以通過位或操作將不同的標志合并到一個整數中。

3. 異或( ^ )

  • 運算規則:對兩個整數的二進制表示中每一位進行比較,當兩個對應位不同時,結果位為 1 ,當兩個對應位相同時,結果位為 0 。
  • 示例代碼:
#include <iostream>int main() {int num1 = 10; // 二進制: 1010int num2 = 6;  // 二進制: 0110int result = num1 ^ num2;std::cout << num1 << " ^ " << num2 << " = " << result << std::endl;// 計算過程://  1010// ^ 0110// ------//  1100  結果為12return 0;
}

應用場景:

  • 數據加密與解密:簡單的異或加密算法中,通過將數據與一個密鑰進行異或操作來加密數據,解密時再次與相同的密鑰異或即可還原數據。
  • 交換兩個數:不使用臨時變量交換兩個整數的值。例如:
#include <iostream>int main() {int a = 5;int b = 7;a = a ^ b;b = a ^ b;a = a ^ b;std::cout << "a = " << a << ", b = " << b << std::endl;return 0;
}
  • 利用了異或操作的特性, a ^ b ^ b 等于 a , a ^ b ^ a 等于 b ,從而實現了兩個數的交換。

4. 按位取反( ~ )

  • 運算規則:對一個整數的二進制表示中的每一位進行取反操作,即將 0 變為 1 , 1 變為 0 。
  • 示例代碼:
#include <iostream>int main() {int num = 5; // 二進制: 0000 0101int result = ~num;std::cout << "~" << num << " = " << result << std::endl; // 計算過程:// 原: 0000 0101// 取反: 1111 1010 // 在有符號整數中,這是 -6 的補碼表示return 0;
}

應用場景:

  • 創建掩碼:通過對特定值進行按位取反可以生成用于位操作的掩碼。例如,要創建一個除了第 3 位為 0 其余位都為 1 的掩碼,可以對 1 << 3 (即 0000 1000 )進行按位取反,得到 1111 0111 。
  • 在特定算法中反轉位模式:某些加密算法或數據處理算法中可能需要對數據的位模式進行反轉。

5. 左移( << )

  • 運算規則:將一個整數的二進制表示向左移動指定的位數,右邊空出的位用 0 填充。每左移一位,相當于該數乘以 2 (在不溢出的情況下)。
  • 示例代碼:
#include <iostream>int main() {int num = 5; // 二進制: 0000 0101int result = num << 2;std::cout << num << " << 2 = " << result << std::endl; // 計算過程:// 原: 0000 0101// 左移2位: 0001 0100  結果為20return 0;
}

應用場景:

  • 快速乘法:當需要將一個數乘以 2 的冪次方時,使用左移操作比乘法操作更高效。例如, a * 8 可以寫成 a << 3 ,因為 8 = 2^3 。
  • 設置標志位:通過左移操作可以將 1 移動到特定位置來設置標志位。例如, 1 << 5 得到 0010 0000 ,可用于設置第 5 位的標志。

6. 右移( >> )

  • 運算規則:將一個整數的二進制表示向右移動指定的位數。對于無符號整數,左邊空出的位用 0 填充;對于有符號整數,如果原數為正數,左邊空出的位用 0 填充,如果原數為負數,左邊空出的位用符號位(即最高位)填充,這稱為算術右移。每右移一位,相當于該數除以 2 (向下取整)。
  • 示例代碼(無符號整數):
#include <iostream>int main() {unsigned int num = 20; // 二進制: 0001 0100unsigned int result = num >> 2;std::cout << num << " >> 2 = " << result << std::endl; // 計算過程:// 原: 0001 0100// 右移2位: 0000 0101  結果為5return 0;
}
  • 示例代碼(有符號整數):
#include <iostream>int main() {int num = -20; // 二進制補碼: 1110 1100int result = num >> 2;std::cout << num << " >> 2 = " << result << std::endl; // 計算過程:// 原: 1110 1100// 右移2位: 1111 1011  結果為 -5return 0;
}

應用場景:

  • 快速除法:當需要將一個數除以 2 的冪次方時,使用右移操作比除法操作更高效。例如, a / 4 可以寫成 a >> 2 ,因為 4 = 2^2 。
  • 提取特定部分:可以通過右移操作將需要的位移動到最低位,然后通過與操作提取。例如,要獲取一個整數二進制表示的低 4 位,可以先右移 n 位( n 為需要丟棄的高位數),然后與 0x0F 進行與操作。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/94430.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/94430.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/94430.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

一次完整的 Docker 啟動失敗排錯之旅:從 `start-limit` 到 `network not found

一次完整的 Docker 啟動失敗排錯之旅&#xff1a;從 start-limit 到 network not found 你是否也曾自信地敲下 sudo systemctl start docker&#xff0c;卻只得到一個冰冷的 failed&#xff1f;這是一個開發者和運維工程師都可能遇到的場景。本文將通過一個真實的排錯案例&…

Tdengine 時序庫年月日小時分組匯總問題

年月分組select to_char(collection_time ,"yyyy-mm") AS date, cast(SUM(a.stage_value)as DOUBLE) as stage_value from TABLE GROUP BY date年月日分組select to_char(collection_time ,"yyyy-mm-dd") AS date, SUM(a.stage_value)as DOUBLE) as stage_…

數據結構(01)—— 數據結構的基本概念

408前置學習C語言基礎也可以看如下專欄&#xff1a;打怪升級之路——C語言之路_ankleless的博客-CSDN博客 目錄 1. 基本概念 1.1 數據 1.2 數據元素 1.3 數據項 1.4 組合項 1.5 數據對象 1.6 數據類型 2. 數據結構 2.1 邏輯結構 2.2 存儲結構 2.3 數據的運算 在學…

什么是模型并行?

模型并行c 簡單來說&#xff0c;就是把一個模型拆開來放到多個 GPU 上&#xff0c;一起訓練&#xff0c;從而化解“顯存塞不下模型”的問題!更多專業課程內容可以聽取工信部電子標準院《人工智能大模型應用工程師》課程獲得詳解&#xff01;

跑yolov5的train.py時,ImportError: Failed to initialize: Bad git executable.

遇到的問題&#xff1a; Traceback (most recent call last):File "D:\miniconda\envs\yolov5\lib\site-packages\git\__init__.py", line 296, in <module>refresh()File "D:\miniconda\envs\yolov5\lib\site-packages\git\__init__.py", line 287…

TCP如何實現可靠傳輸?實現細節?

TCP如何實現可靠傳輸&#xff1f;實現細節&#xff1f;如何實現可靠傳輸&#xff1f;擁塞控制的主要機制TCP流量控制怎么實現的&#xff1f;如何實現可靠傳輸&#xff1f; TCP通過自身的序列號、確認應答、數據效驗、超時重傳、流量控制、擁塞避免&#xff0c;確保了數據傳輸的…

Linux 服務器性能監控、分析與優化全指南

Linux 服務器性能監控、分析與優化在現代 IT 架構中&#xff0c;Linux 服務器作為承載業務系統的核心載體&#xff0c;其性能表現直接決定了服務的穩定性、響應速度與用戶體驗。無論是高并發的 Web 服務、數據密集型的數據庫集群&#xff0c;還是承載虛擬化平臺的宿主機&#x…

基于wenet和模型做企業直播敏感語音屏蔽技術

本文介紹了基于Wenet語音識別工具包的實時敏感詞屏蔽技術方案。該方案通過客戶端緩存25秒直播內容&#xff0c;利用Wenet的流式識別和斷句檢測功能&#xff0c;實時檢測講師語音中的敏感詞&#xff0c;并將對應位置的語音替換為"嗶"聲。文章詳細闡述了Wenet的兩種識別…

42.MySQL視圖

1.一個需求emp 表的列信息很多&#xff0c;有些信息是個人重要信息 (比如 sal, comm, mgr, hiredate)&#xff0c;如果我們希望某個用戶只能查詢 emp 表的 (empno、ename, job 和 deptno ) 信息&#xff0c;有什么辦法&#xff1f;表的數據&#xff1a;想讓用戶查詢到的&#x…

MinIO01-入門

零、文章目錄 MinIO01-入門 1、介紹 &#xff08;1&#xff09;介紹 MinIO 是一款基于 Apache License v2.0 的開源對象存儲系統&#xff0c;專為海量非結構化數據&#xff08;如圖片、視頻、日志文件等&#xff09;設計&#xff0c;兼容 Amazon S3 API&#xff0c;支持高性…

*Docker數據卷(Volume)核心機制剖析:持久化與共享的終極解決方案

根本問題當容器被刪除時&#xff0c;其內部產生的所有文件&#xff08;包括配置文件、數據庫、日志&#xff09;都會不可逆丟失。數據卷&#xff08;Volume&#xff09;通過外置存儲方案徹底解決此痛點。一、數據卷與普通容器存儲對比實驗 場景1&#xff1a;無卷模式下的寫入悲…

原型模式在C++中的實現與面向對象設計原則

引言 在軟件開發中&#xff0c;原型模式是一種常用的設計模式&#xff0c;主要用于創建對象的克隆。通過原型模式&#xff0c;我們可以避免復雜的對象創建過程&#xff0c;尤其是當對象的初始化需要大量資源或復雜操作時。本文將通過一個具體的例子&#xff0c;詳細介紹如何在C…

SpringCloud學習------Gateway詳解

在微服務架構中&#xff0c;隨著服務數量的激增&#xff0c;如何統一管理服務入口、實現請求路由、保障服務安全等問題日益突出。SpringCloud Gateway 作為 Spring 官方推出的網關組件&#xff0c;憑借其強大的功Gateway 是 Spring 官方基于 Spring、SpringBoot 和 Project Rea…

計算機網絡:子網掩碼在路由轉發中的關鍵作用

在路由表中,子網掩碼是一個不可或缺的組成部分,其核心作用是精確界定IP地址中“網絡位”和“主機位”的邊界,從而實現路由器對數據包的準確轉發。以下從多個角度詳細解釋其必要性: 1. 區分網絡位與主機位,定位目標網絡 IP地址由“網絡標識”(網絡位)和“主機標識”(主…

14.Home-新鮮好物和人氣推薦實現

新鮮好物實現1.準備模板<script setup>import HomePanel from ./HomePanel.vue</script><template><homePanel></HomePanel><!-- 下面是插槽主體內容模版<ul class"goods-list"><li v-for"item in newList" :ke…

Linux 系統重置用戶密碼指南

Linux 系統重置用戶密碼指南 在 Linux 系統運維中&#xff0c;重置用戶密碼&#xff08;尤其是 root 密碼&#xff09;是一項核心技能。當您忘記密碼時&#xff0c;可以通過進入單用戶模式或恢復模式來修改密碼。此方法適用于大多數 Linux 發行版&#xff0c;如 RHEL/CentOS、D…

[自動化Adapt] GUI交互(窗口/元素) | 系統配置 | 非侵入式定制化

第三章&#xff1a;GUI交互&#xff08;窗口/元素&#xff09; 各位OpenAdapt探索者&#xff0c;歡迎回來~ 在第一章&#xff1a;錄制引擎中&#xff0c;我們揭示了OpenAdapt如何通過"眼睛和耳朵"捕捉所有操作細節。接著在第二章&#xff1a;數據模型中&#xff0c…

Java 模版進階

文章目錄模版通配符模版 通配符 實例 import java.util.ArrayList; import java.util.List;class Message<T> {private T message ;public T getMessage() {return message;}public void setMessage(T message) {this.message message;} } public class test {public …

統計魚兒分布情況 Java

假設有一個池塘&#xff0c;管理員在池塘中添加隨機數量的魚類&#xff0c;為了統計魚類的分布情況&#xff0c;他將池塘劃分為8*8的二維網格&#xff0c;魚兒隨機游動&#xff0c;但是每個網格中最多容納100條魚&#xff0c;要求編寫程序顯示魚兒分布情況&#xff0c;并計算魚…

【HUST】計算機|大學計算機基礎內容(純科普向)+數據結構數組、樹、隊列【舊文搬運】

最初發布時間&#xff1a;2020-09-19 23:17:48 以前寫這篇文章&#xff0c;主要是接觸到一些非計算機學院的同學&#xff0c;為了交流方便我寫下了這篇文章……雖然現在回過頭來看寫得也比較草率&#xff0c;但確實是我對電腦的基礎操作的最早的認識&#xff0c;放到現在我絕對…