精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

計算機系統對數值類型的編碼、運算、轉換原理介紹2

jf_78858299 ? 來源:元閏子的邀請 ? 作者:元閏子 ? 2023-05-09 16:31 ? 次閱讀

算術運算

整數的算術運算也不總符合我們的常識,比如下面這個例子:

// Java語言
public static void main(String[] args) {
    int i1 = 2147483647;
    int i2 = 1;
    System.out.printf("2147483647+1=%d\\n", i1+i2);
}
// 輸出結果:
2147483647+1=-2147483648

兩個正數 21474836471 相加,實際運行結果卻是一個負數 -2147483648。原因是,運算結果超出了 int 類型的表示范圍,我們把這種現象稱作 溢出

接下來,我們將介紹整數類型常見的幾種算術運算,包括當運算出現溢出時,計算機系統的處理方式。

加法

(1)無符號整數加法運算

對兩個 w 位的無符號整數 ,有 ;如果仍用一個 w 位的整數表示相加結果,那么當結果在 范圍時,也即結果需要 w + 1 位表示時,運算就產生溢出了。

如果出現溢出,系統會對結果進行截斷,只保留低 w 位

比如,w = 4 場景下的一些例子:

圖片

因此,如果用 表示 w 位無符號整數的加法運算,那么它有如下規則:

其中,溢出場景因為對結果的進行截斷,舍去了 位,所以結果需要減去 。

(2)有符號整數加法運算

對兩個 w 位的有符號整數 ,有 ;如果仍用一個 w 位的整數表示相加結果,那么當結果在 和 范圍時,運算就產生溢出了。

比如,w = 4 場景下的一些例子:

圖片

由上述例子可知, 兩個 w 位的負數相加,即使結果需要 w + 1 位表示,也可能是正常場景。這取決于截斷位 w 位后的最高位,為 1 則還屬于正常場景,為 0 則屬于溢出場景

因此,如果用 表示 w 位有符號整數的加法運算,那么它有如下規則:

  • 正溢出場景下 ,原本 ,但按照補碼編碼方式,實際變成了 ,所以就有 。
  • 負溢出場景下 ,w 位一定是 0,原本 ,結果截斷之后,實際變成了 ,所以就有 。

為什么負溢出場景下,w 位一定是 0

負溢出場景出現的條件是 ,也即 :

如果要使上述不等式成立, 必然為 0.

前面很多公式,但記住這個就行, 無符號整數和有符號整數的加法運算規則,本質都是一樣的,可以拆解成 4 步

  1. 先計算出真實加法運算的結果值。
  2. 對結果值用 w + 1 位二進制表示。
  3. 再將 w + 1 位的二進制結果截斷,保留低 w 位。
  4. 將截斷后的 w 位二進制值轉換回十進制整數,得到最終結果。無符號整數用無符號編碼,有符號整數用補碼編碼。

取反

取反,也即求相反數,給定一個整數 ,那么它的相反數 ,也即滿足 。

(1)無符號整數的取反

對一個 w 位的無符號整數 ,對它取反,也即找到一個整數 ,使得 :

  • 當 ,那么很容易得出 ;
  • 當 x > 0,只有在溢出場景才會存在 的可能。由前文可知,無符號整數加法溢出場景下, 時,有,。

因此,如果用 表示 w 位無符號整數的取反運算,那么它有如下規則:

比如,w = 8 場景下的例子:

// C++
int main() {
    uint8_t i1 = 0;
    uint8_t i2 = -i1;
    printf("i1=%u\\n", i1);
    printf("-i1=%u\\n", i2);

    uint8_t i3 = 100;
    uint8_t i4 = -i3;
    printf("i3=%u\\n", i3);
    printf("-i3=%u\\n", i4);
    printf("2^8-i3=256-%u=%u\\n", i3, 256-i3);
    return 0;
}
// 輸出結果
i1=0
-i1=0
i3=100
-i3=156
2^8-i3=256-100=156

(2)有符號整數的取反

對一個 w 位的有符號整數 ,對它取反,也即找到一個整數 ,使得 :

  • 當 ,很容易得出 ,因為此時 ,仍是有效的范圍。
  • 當 ,因為 已經不再有效范圍內,所以只能是溢出場景。而 ,截斷為 w 之后,剛好為 0。所以,此時 。

因此,如果用 表示 w 位有符號整數的取反運算,那么它有如下規則:

比如,w = 8 場景下的例子:

// C++
int main() {
    int8_t i1 = -128;
    int8_t i2 = -i1;
    printf("i1=%d\\n", i1);
    printf("-i1=%d\\n", i2);

    int8_t i3 = 100;
    int8_t i4 = -i3;
    printf("i3=%d\\n", i3);
    printf("-i3=%d\\n", i4);
    return 0;
}
// 輸出結果
i1=-128
-i1=-128
i3=100
-i3=-100

乘法

前面介紹加法時說過,無符號整數和有符號整數的加法運算都可以拆成 4 步,這對乘法運算也適用。

對于無符號整數 ,那么 ,即無符號整數的乘法運算結果最多需要 2w 位來表示。

比如,w = 8 時,無符號整數的例子:

// C++
int main() {
    uint8_t i1 = 100;
    uint8_t i2 = 2;
    uint8_t i3 = i1 * i2;
    printf("normal: i1 * i2 = %d * %d = %d\\n", i1, i2, i3);

    uint8_t i4 = 100;
    uint8_t i5 = 3;
    uint8_t i6 = i4 * i5;
    printf("overflow: i4 * i5 = %d * %d = %d\\n", i4, i5, i6);
    return 0;
}
// 輸出結果
normal: i1 * i2 = 100 * 2 = 200
overflow: i4 * i5 = 100 * 3 = 44

圖片

對于有符號整數 ,那么 ,即有符號整數的乘法運算結果最多也需要 2w 位來表示。

比如,w = 8 時,有符號整數的例子:

// C++
int main() {
    int8_t i1 = -50;
    int8_t i2 = 2;
    int8_t i3 = i1 * i2;
    printf("normal: i1 * i2 = %d * %d = %d\\n", i1, i2, i3);

    int8_t i4 = -128;
    int8_t i5 = 127;
    int8_t i6 = i4 * i5;
    printf("overflow: i4 * i5 = %d * %d = %d\\n", i4, i5, i6);
    return 0;
}
// 輸出結果
normal: i1 * i2 = -50 * 2 = -100
overflow: i4 * i5 = -128 * 127 = -128

圖片

大部分機器上,乘法運算消耗 3 ~ 10 個 CPU 時鐘周期,而加法運算和位運算只消耗 1 個時鐘周期,所以,追求極致性能的程序都會想辦法通過加法運算和位運算來替代乘法運算。

如果不考慮截斷,對 左移 k 位,會得到:

也即,對 左移 k 位 相當于乘以

如果考慮截斷,就會存在溢出場景,對于 w 位的整數,左移 k 位效果也等同于 或 。

比如,w = 8 時,無符號整數的例子:

// C++
int main() {
    uint8_t i1 = 100;
    uint8_t i2 = 4;
    uint8_t i3 = i1 * i2;
    printf("i1 * i2 = %d * %d = %d\\n", i1, i2, i3);

    uint8_t k = 2;
    uint8_t i4 = i1 << k;
    printf("i1 << k = %d << %d = %d\\n", i1, k, i4);
    return 0;
}
// 輸出結果
i1 * i2 = 100 * 4 = 144
i1 << k = 100 << 2 = 144

有符號整數的例子:

// C++
int main() {
    int8_t i1 = -50;
    int8_t i2 = 4;
    int8_t i3 = i1 * i2;
    printf("i1 * i2 = %d * %d = %d\\n", i1, i2, i3);

    int8_t k = 2;
    int8_t i4 = i1 << k;
    printf("i1 << k = %d << %d = %d\\n", i1, k, i4);
    return 0;
}
// 輸出結果
i1 * i2 = -50 * 4 = 56
i1 << k = -50 << 2 = 56

那么,對于與任意常數 K 的相乘,有沒可能轉換為移位操作

任意常數 K,可以表示成 的形式,也即,由一系列連續的 0 和 連續的 1 組成,比如 14 可以表示成 。

假設只存在一個連續的 1 序列,從高到低, 位于 n 到 m 位,比如 14 中,n = 3,m = 1,那么:

比如, 就可以表示成 或者 :

// C++
int main() {
    int8_t x = 5;
    int8_t K = 14;
    printf("x * 14 = %d\\n", x*K);
    printf("(x<<3) + (x<<2) + (x<<1) = %d\\n", (x<<3)+(x<<2)+(x<<1));
    printf("(x<<4) - (x<<1) = %d\\n", (x<<4)-(x<<1));
    return 0;
}
// 輸出結果
x * 14 = 70
(x<<3) + (x<<2) + (x<<1) = 70
(x<<4) - (x<<1) = 70

同理,當 K 的二進制表示,存在多個連續的 1 序列時,也成立。

除法

除法運算比乘法運算更慢,通常需要 30 個 CPU 時鐘以上 。同理, 也可以轉換成右移運算,注意結果的取整:

// C++
int main() {
    int8_t x = -50;
    int8_t K = 4;
    printf("x / 4 = %d\\n", x/K);
    printf("x >> 2 = %d\\n", x>>2);
    printf("(x+(1<<2))>>2 = %d\\n", (x+(1<<2))>>2);

    uint8_t y = 50;
    uint8_t Z = 4;
    printf("y / 4 = %d\\n", y/Z);
    printf("y >>> 2 = %d\\n", y>>2);
    printf("(y+(1<<2))>>>2 = %d\\n", (y+(1<<2))>>2);
    return 0;
}
// 輸出結果
x / 4 = -12
x >> 2 = -13
(x+(1<<2))>>2 = -12

y / 4 = 12
y >>> 2 = 12
(y+(1<<2))>>>2 = 13
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 計算機
    +關注

    關注

    19

    文章

    7425

    瀏覽量

    87722
  • 編程
    +關注

    關注

    88

    文章

    3595

    瀏覽量

    93604
  • 編碼
    +關注

    關注

    6

    文章

    935

    瀏覽量

    54765
  • 數值
    +關注

    關注

    0

    文章

    80

    瀏覽量

    14352
收藏 人收藏

    評論

    相關推薦

    計算機系統結構

    計算機系統結構
    發表于 05-09 19:03

    什么是計算機系統計算機硬件和計算機軟件?

    第一章 計算機系統概論1. 什么是計算機系統計算機硬件和計算機軟件?硬件和軟件哪個更重要?解:P3計算機系統:由
    發表于 07-22 09:06

    什么是計算機系統?硬件和軟件哪個更重要?

    第一章計算機系統概論1 .什么是計算機系統計算機硬件和計算機軟件?硬件和軟件哪個更重要?解: P3計算機系統:由
    發表于 07-26 07:18

    計算機系統中的軟件系統

    專用計算機現代計算機運算速度最高可達每秒幾萬億次幾十億次幾億次幾萬次計算機輔助制造是計算機應用領域之一其英文縮寫是所謂的信息是指基本素材非數值
    發表于 09-13 07:22

    嵌入式計算機系統概述

    硬件子系統和軟件子系統組成的,通過運行程序來協同工作計算機硬件:基本的計算機硬件系統運算器、控
    發表于 12-22 06:08

    簡單介紹微型計算機的組成

    你了解自己的計算機?或者知道單片機的組成嗎?這一小節主要簡單介紹微型計算機的組成,以及微型計算機系統經常用到的概念,包括組成、工作過程、工作原理、
    發表于 01-10 07:11

    計算機系統概論

    1.1 計算機系統簡介1.2 計算機的基本組成1.3 計算機硬件的主要技術指標1.4 本書結構
    發表于 04-11 09:31 ?0次下載

    微型計算機系統

             微型計算機系統與傳統的計算機系統一樣,也是由硬件系統和軟件系統兩大部分組成的。2.1
    發表于 03-03 08:31 ?0次下載

    什么是計算機系統的容錯性

    什么是計算機系統的容錯性             所謂容錯是指在故障存在的情況下計算機系統不失效,仍然能夠正常工作的特性
    發表于 01-08 13:49 ?1628次閱讀

    深入理解計算機系統數值類型

    計算機系統中,整數可以分成 無符號(unsigned)整數 和 有符號(signed)整數 兩大類,這之下,按照類型表示的 bit 位大小,又可細分成 8 位的 char/byte/int8
    的頭像 發表于 08-19 15:17 ?1150次閱讀

    計算機系統對數值類型編碼運算轉換原理介紹1

    。正因太熟悉,我們往往不會深究它們的底層原理。因為平時的工作中,知道個大概,也夠用了。 但,在某些業務場景下,比如金融業務,數值運算不準確會帶來災難性的后果。這時,你就必須清楚數值類型
    的頭像 發表于 05-09 16:30 ?1137次閱讀
    <b class='flag-5'>計算機系統</b><b class='flag-5'>對數值</b><b class='flag-5'>類型</b>的<b class='flag-5'>編碼</b>、<b class='flag-5'>運算</b>、<b class='flag-5'>轉換</b>原理<b class='flag-5'>介紹</b>1

    計算機系統對數值類型編碼運算轉換原理介紹3

    。正因太熟悉,我們往往不會深究它們的底層原理。因為平時的工作中,知道個大概,也夠用了。 但,在某些業務場景下,比如金融業務,數值運算不準確會帶來災難性的后果。這時,你就必須清楚數值類型
    的頭像 發表于 05-09 16:31 ?794次閱讀
    <b class='flag-5'>計算機系統</b><b class='flag-5'>對數值</b><b class='flag-5'>類型</b>的<b class='flag-5'>編碼</b>、<b class='flag-5'>運算</b>、<b class='flag-5'>轉換</b>原理<b class='flag-5'>介紹</b>3

    計算機系統對數值類型編碼運算轉換原理介紹4

    。正因太熟悉,我們往往不會深究它們的底層原理。因為平時的工作中,知道個大概,也夠用了。 但,在某些業務場景下,比如金融業務,數值運算不準確會帶來災難性的后果。這時,你就必須清楚數值類型
    的頭像 發表于 05-09 16:31 ?492次閱讀
    <b class='flag-5'>計算機系統</b><b class='flag-5'>對數值</b><b class='flag-5'>類型</b>的<b class='flag-5'>編碼</b>、<b class='flag-5'>運算</b>、<b class='flag-5'>轉換</b>原理<b class='flag-5'>介紹</b>4

    計算機系統中的關鍵組件有哪些

    計算機系統中,關鍵組件的協同工作構成了其強大的數據處理和運算能力。這些組件不僅決定了計算機的性能,還影響著用戶的使用體驗。以下是對計算機系統中關鍵組件的詳細闡述,包括它們的定義、功能
    的頭像 發表于 07-15 18:18 ?1294次閱讀

    微處理器如何控制計算機系統

    微處理器,作為計算機系統的核心部件,承擔著控制整個計算機系統運行的重要任務。它不僅是計算機運算中心,還是控制中心,負責執行程序指令、處理數據以及協調
    的頭像 發表于 08-22 14:21 ?444次閱讀