原碼反碼補碼

来源:https://www.cnblogs.com/burner/archive/2022/03/26/yuan-ma-fan-ma-bu-ma.html
-Advertisement-
Play Games

3 原碼、反碼、補碼 3.1 知識點補充 在電腦內部,所有信息都是用二進位數串的形式表示的。整數通常都有正負之分,電腦中的整數分為無符號的和帶符號的。無符號的整數用來表示0和正整數,即自然數;帶符號的正數可以表示所有的整數。 由於電腦中符號和數字一樣,都必須用二進位數串來表示,因此,正負號也必 ...


3 原碼、反碼、補碼

3.1 知識點補充

在電腦內部,所有信息都是用二進位數串的形式表示的。整數通常都有正負之分,電腦中的整數分為無符號的和帶符號的。無符號的整數用來表示0和正整數,即自然數;帶符號的正數可以表示所有的整數。

由於電腦中符號和數字一樣,都必須用二進位數串來表示,因此,正負號也必須用0、1來表示。通常我們用最高的有效位來 表示數的符號(當用8位來表示一個整數時,第8位即為最高有效位,當用16位來表示一個整數時,第16位即為最高有效位。)0表示正號、1表示負號。

這種正負號數字化(0表示正號、1表示負號)的機內表示形式就稱為機器碼或者機器數,而相應的機器外部用正負號表示的數稱為真值。將一個真值表示成二進位字串的機器數的過程就稱為編碼

無符號數沒有原碼、反碼和補碼一說。只有帶符號數才存在不同的編碼方式。帶符號整數有原碼、反碼、補碼等幾種編碼方式。

**原碼即直接將真值轉換為其相應的二進位形式,而反碼和補碼是對原碼進行某種轉換編碼方式。**正整數的原 碼、反碼和補碼都一樣,負數的反碼是對原碼的除符號位外的其他位進行取反後的結果(取反即如果該位為0則變為1,而該位為1則變為0的操作)。而補碼是先求原碼的反碼,然後在反碼的末尾位加1 後得到的結果,即補碼是反碼+1。IBM-PC中帶符號整數都採用補碼形式表示。

註意,只是帶符號的整數採用補碼存儲表示的,浮點數另有其存儲方式。

  1. 正數的補碼是其本身
  2. 負數的反碼,符號位不變,其餘的按位取反
  3. 負數的補碼,反碼加1

對於字長為8位有符號的int,因為最高為符號位,占1位,所以最小為(1111111)2 = (-127)10,最大為(0111111)2 = (127)10;即其原碼範圍為:-127~127

有符號的8位二進位的原值表達範圍為:-127至127,此時共255個數字;然而,8位二進位 的補碼排列共有$A_{2}^{8}$ = 256個,0000 0000 至1111 1111 。

補碼組合 範圍 個數
0000 0000 - 0111 1111 0 ~+127 128
10000000 多餘的一種組合待定 1
1000 0001 - 1111 1111 -1~-127 127

**10000000 **看似要被浪費掉了啊!其實不然,( 100000000 ) 2 = ( 2^7 ) 10 = ( 128 ) 10,這個組合要利用起來,不能太偏離數值意義,表示128,顯得更直觀。

**從大到小,依次減1看一下規律:**
十進位 (字長8bit) 原碼 反碼 補碼
127 0111 1111 0111 1111 0111 1111
126 0111 1110 0111 1110 0111 1110
…… …… …… ……
10 0000 1010 0000 1010 0000 1010
…… …… …… ……
2 0000 0010 0000 0010 0000 0010
1 0000 0001 0000 0001 0000 0001
+0 0000 0000 0000 0000 0000 0000
-1 1000 0001 1111 1110 1111 1111
-2 1000 0010 1111 1101 1111 1110
…… …… …… ……
-10 10001010 11110101 11110110
…… …… …… ……
-127 11111111 10000000 10000001
待定 10000000 10000000 10000000

從遞減規律中,發現,**10000000 **表示-128更合適。

即規定:-128的補碼為 10000000

求10 -10 0 -128 127 的原碼、反碼、補碼

十進位 (字長8bit) 原碼 反碼 補碼
10 00001010 00001010 00001010
-10 10001010 11110101 11110110
-1 1000 0001 1111 1110 1111 1111
+0 00000000 00000000 00000000
-0 10000000 11111111 00000000
-128 10000000
127 01111111 01111111 01111111
-127 11111111 10000000 10000001

+0和-0的補碼是一樣的。即 0的補碼只有一種表示,0的補碼是0000 0000,

# 四 輸出結果,解釋為什麼是這樣的
char c = 128;
printf("%d\n",c);
printf("%hhd\n",c);
printf("%hd\n",c);
printf("%hu\n",c);

4.1 格式輸出符

格式符號 意義
%a 浮點數、十六進位數字和p-記數法 (C99)
%A 浮點數、十六進位數字和P-記數法 (C99)
%c 一個字元
%d 有符號十進位整數
%e 浮點數、e-記數法
%E 浮點數、E-記數法
%f 浮點數,十進位記數法
%g 根據數值不同自動選擇%f或者%e。%e格式在指數小於-4或者大於等於精度時使用
%G 根據數值不同自動選擇%f或者%E。%E格式在指數小於-4或者大於等於精度時使用
%i 有符號十進位整數 (與%d相同)
%o 無符號八進位整數
%p 指針(就是指地址)
%s 字元串
%u 無符號十進位整數
%x 使用十六進位數字0f 的無符號十六進位整數
%X 使用十六進位數字0F的無符號十六進位整數
%% 列印一個百分號
## 4.2 格式輸出其修飾符
修飾符 意義 示例
h 和整數轉換說明符一起使用,表示一個short int 或者 unsigned short int 類型數值。 "%hd
hh 和整數轉換說明符一起使用,表示一個signed char 或者unsigned char類型數值。 "%hhd"
j 和整數轉換說明符一起使用,表示一個intmax_t或uintmax_t值。 "%jd"
l 和整數說明符一起使用,表示一個long int 或者unsigned long int 類型值。 "%8lu"
ll 和整數說明符一起使用,表示一個long long int或 unsigned long long int 類型值 (C99)。 "%lld"
L 和浮點轉換說明符一起使用,表示一個long double值。 "%8.4Le"
t 和整數轉換說明符一起使用,表示一個ptrdiff_t值(與兩個指針之間的差相對應的類型) (C99) "%td"
- 項目是左對齊的,也就是說,會把項目列印在欄位的左側開始處 "%-20s"
+ 有符號的值若為正,則顯示帶加號的符號;若為負,則帶減號的符號。 "%+3.2"
(空格) 有符號的值若為正,則顯示時帶前導空格(但是不顯示符號);若為負,則帶減號符號。+標誌會覆蓋空格標誌。 "% 3.2"
# 使用轉換說明的可選形式。若為%o格式,則以0開始;若為%x和%X格式,則以0x或0X開始,對於所有的浮點形式,#保證了即使不限任何數字,也列印一個小數點字元。對於%g和%G格式,它防止尾隨零被刪除。 "%#o"
0 對於所有的數字格式,用前導零而不是用空格填充欄位寬度。如果出現-標誌或者指定了精度(對於整數)則忽略該標誌。 "%010d"
## 4.3 機器碼求解
char c = 128;

此處是將一個int賦值給一個char類型變數,進行隱式類型轉換.int型數值賦給char型變數時,只保留其最低8位,高位部分捨棄。

首先,整型128在一個字長為4個位元組的的原碼為00000000 00000000 00000000 10000000,當把一個int類型賦值給一個有符號的char類型時,高位被捨棄。實際給c的是10000000,此時,被系統認為是一個負數,補碼為10000000,結合上面的分析,其值就是**-128**。

4.4 格式化輸出

char c = 128;

4.4.1 結論

先給出通過這次作業得出的一個不完全歸納法結論吧,也是我做出的解釋。最後會給出原碼驗證

1、正數的原碼的反碼、補碼是其本身,擴展時,高位補0;

2、負數擴展為有符號的高位補1,無符號的高位補0。

2、負數擴展時,高位補 1。格式化輸出無符號的數據時,機器碼即為原碼;格式化輸出有符號數據時,要先求其原碼,然後求得真值。

c 的機器碼為10000000

4.4.2 輸出32位有符號int:

printf("%d\n",c);//預設的 int ,32位

1000 0000 轉為有符號的32位機器碼:1111 1111 1111 1111 1111 1111 1000 0000

反碼:1111 1111 1111 1111 1111 1111 0111 1111

原碼:1000 0000 0000 0000 0000 0000 1000 0000

有符號,其值為:-128.

4.4.3 輸出8位有符號signed char:

printf("%hhd\n",c);//signed char,  8位

8位機器碼:1000 0000

此機器碼沒有反碼和源碼,機器碼即為真值:-128.

4.4.4 輸出16位有符號 short int

printf("%hd\n",c);//short int,16 位

1000 0000 轉為有符號的16位機器碼:1111 1111 1000 0000

反碼:1111 1111 0111 1111 原碼:1000 0000 1000 0000

有符號,其值為:-128.

4.4.5 輸出16位無符號 short int

printf("%hu\n",c);

1000 0000 轉為16位機器碼:1111 1111 1000 0000

格式化輸出無符號十進位數據,此碼即為原碼。

原碼:1111 1111 1000 0000

做無符號運算,其值:65408

4.5 源碼

#include <iostream>
#include <bitset>

int main() {
    using namespace std;
    cout << "Hello Biter !" << endl;
    char c = 128;
    cout << "---------------- -" << int(c) << "-----------------------  " << endl;
    cout << "char 型 機器碼 =  " << bitset<sizeof(char) * 8>(c) << endl;
    cout << "int 型 機器碼 =  " << bitset<sizeof(int) * 8>(c) << endl;
    cout << "signed char 型 機器碼 =  " << bitset<sizeof(signed char) * 8>(c) << endl;
    cout << "short int 型 機器碼 =  " << bitset<sizeof(short int) * 8>(c) << endl;
    cout << "unsigned short int 型 機器碼 =  " << bitset<sizeof(unsigned short int) * 8>(c) << endl;
    cout << "char 二進位形式為 =  " << bitset<sizeof(char) * 8>(c) << endl;
    cout << "--------------------------------------------  " << endl;
//    printf("將 char 直接 輸出 128 超範圍了 = %c\n", c);
//    cout << "--------------------------------------------  " << endl;
    printf("有符號的 int 輸出 = %d\n", c);
    cout << "--------------------------------------------  " << endl;
    printf("有符號的 signed char 輸出 = %hhd\n", c);//1000,0000
    cout << "--------------------------------------------  " << endl;
    printf("有符號的 short int 輸出= %hd\n", c);//0000,0000 1000,0000
    cout << "--------------------------------------------  " << endl;
    printf("無符號的 unsigned short int 輸出= %hu\n", c);// 1111,1111 1000,0000
    cout << "--------------------------------------------  " << endl;

    return 0;
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 裝飾器模式是什麼 是一種結構型設計模式,它允許你將對象放入包含行為的特殊封裝對象中來為原對象綁定新的行為。由於目標對象和裝飾器遵循同一介面,所以你可以對目標進行多次裝飾,最後結果為所有裝飾器疊加的行為。 為什麼用裝飾器模式 需要動態的給一個對象增加功能,並且可以動態的撤銷的時候。當系統需要添加新的功 ...
  • 編寫一個程式,獲取10個1至20的隨機數,要求隨機數不能重覆。 * * 分析: * A:創建隨機數對象 * B:創建一個HashSet集合 * C:判斷集合的長度是不是小於10 * 是:就創建一個隨機數添加 * 否:不搭理它 * D:遍歷HashSet集合 */ package Day17; imp ...
  • 在項目中需要用到group by進行聚合計算,在計算的同時也要查出一些其他欄位來返回給前端。於是就有了這個錯誤的出現。 先簡單復現我所寫的sql,其實sql非常簡單。 select channel_name as channelName, brand_name as brandName, sum(a ...
  • 在項目開發過程中,不可避免的會碰到需要強制增加審計日誌的需求,那具體如何做呢,本文將告訴你答案! ...
  • IO多路復用通過某種機制使進程監聽某些文件描述符,當文件描述符中有讀或寫就緒時,進程能夠收到系統內核發送的相應通知從而進行相應的IO操作;IO多路復用有:select、poll、epoll等模式,這裡主要介紹select;select本質上也是同步IO,調用時阻塞自己,IO事件就緒後被喚醒返回負責讀 ...
  • TreeSet:能夠對元素按照某種規則進行排序。 * 排序有兩種方式 * A:自然排序 * B:比較器排序 * * TreeSet集合的特點:排序和唯一 * * 通過觀察TreeSet的add()方法,我們知道最終要看TreeMap的put()方法 A:自然排序 1 public class Tre ...
  • 周末不能出去玩多無聊啊,那就來幾個小游戲給大家助助興,,可以自己復現玩玩,研究下裡面的編程邏輯,對學習編程(特別是初學者)應該會有很大幫助。學會了別忘記教你的小伙伴,好的東西大家要學會分享。 由於文章較長,大家可以先點贊收藏後再慢慢看哦~ 1、吃金幣 源碼分享: #####Python學習Q群:90 ...
  • 枚舉 對於一些簡單的題目,我們或許不需要用什麼太巧妙的方法,只需要把所有的可能性列舉出來,然後逐一試驗就可以了。 總的來說,枚舉就是通過列舉所有的可能性進行一一判斷檢查。 方法 通過事先把各種可能發生的事情都列舉一遍,為後面求解提供結果。 總的來說,兩種方法: 遞歸枚舉,這種方法往往更直觀; 遞推( ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...