在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

計(jì)算機(jī)系統(tǒng)對(duì)數(shù)值類型的編碼、運(yùn)算、轉(zhuǎn)換原理介紹1

jf_78858299 ? 來源:元閏子的邀請(qǐng) ? 作者:元閏子 ? 2023-05-09 16:30 ? 次閱讀

前言

在日常編程中, 數(shù)值類型numeric types )是我們打交道最多的類型,可能沒有之一。除了最熟悉的 int,還有 longfloatdouble 等。正因太熟悉,我們往往不會(huì)深究它們的底層原理。因?yàn)槠綍r(shí)的工作中,知道個(gè)大概,也夠用了。

但,在某些業(yè)務(wù)場(chǎng)景下,比如金融業(yè)務(wù),數(shù)值運(yùn)算不準(zhǔn)確會(huì)帶來災(zāi)難性的后果。這時(shí),你就必須清楚數(shù)值類型的二進(jìn)制表示、截?cái)唷⑥D(zhuǎn)型等原理,否則很難保證運(yùn)算結(jié)果的正確性。

另外,數(shù)值類型也是一個(gè)容易被黑客攻擊的點(diǎn),考慮如下一段代碼:

// C++
/* Declaration of library function memcpy */
void *memcpy(void *dest, void *src, size_t n);
/* Kernel memory region holding user-accessible data */
#define KSIZE 1024
char kbuf[KSIZE];
/* Copy at most maxlen bytes from kernel region to user buffer */
int copy_from_kernel(void *user_dest, int maxlen) {
    /* Byte count len is minimum of buffer size and maxlen */
    int len = KSIZE < maxlen ? KSIZE : maxlen;
    memcpy(user_dest, kbuf, len);
    return len;
}

如果你熟悉數(shù)值類型的原理,一定會(huì)敏銳察覺出第 10 行存在 intsize_t 的類型轉(zhuǎn)換。在 64 位系統(tǒng)中,size_t 通常被定義為 unsigned long 類型,如果攻擊者在調(diào)用 copy_from_kernel 時(shí),特意傳入一個(gè)負(fù)數(shù)的 maxlen,轉(zhuǎn)型到 memcpy 中的 n 將會(huì)是一個(gè)很大的正數(shù),從而導(dǎo)致了內(nèi)存拷貝的越界!

數(shù)值類型是計(jì)算機(jī)編程的基礎(chǔ),用的很多,也很重要,理解它的底層原理,有助于寫出正確的代碼,避免一些意料之外的錯(cuò)誤

每個(gè)計(jì)算機(jī)系統(tǒng)都有固定的 word size ,也即常說的 xx 位,它也是指針的大小,跟 虛擬內(nèi)存 相關(guān),比如一個(gè) w 位系統(tǒng)上的應(yīng)用程序,最多能夠訪問 byte 大小的虛擬內(nèi)存。

最常用的是 32 位 和 64 位 系統(tǒng),某些數(shù)值類型在它們之上會(huì)有些差異,比如 long 類型 在 32 位系統(tǒng)上是 32 bit 大小,在 64 位系統(tǒng)上是 64 bit 大小。 考慮如今 64 位系統(tǒng)逐漸成為主流,本文會(huì)以它作為基礎(chǔ),進(jìn)行數(shù)值類型的介紹

整數(shù)

在計(jì)算機(jī)系統(tǒng)中,整數(shù)可以分成 無符號(hào)unsigned )整數(shù) 和 有符號(hào)signed )整數(shù) 兩大類,這之下,按照類型表示的 bit 位大小,又可細(xì)分成 8 位的 char/byte/int8 、16 位的 short/innt16、32 位的 int/int32 和 64 位的 long/int64,它們的取值范圍如下:

類型 最小值 最大值
[signed] char -128 127
unsigned char 0 255
short -32,768 32,767
unsigned short 0 65,535
int ?2,147,483,648 2,147,483,647
unsigned int 0 4,294,967,295
long ?9,223,372,036,854,775,808 9,223,372,036,854,775,807
unsigned long 0 18,446,744,073,709,551,615

死記這個(gè)表不容易,下面我們將試圖從二進(jìn)制編碼層面去理解它。

二進(jìn)制編碼

整數(shù)在計(jì)算機(jī)系統(tǒng)上都是以二進(jìn)制存儲(chǔ)的,對(duì)于一個(gè) w 位的整數(shù) ,它的二進(jìn)制表示寫成這樣:

其中, 取值 或 。

無符號(hào)編碼(Unsigned Encodings)

在二進(jìn)制表示的基礎(chǔ)上,無符號(hào)編碼 是這樣:

比如,w = 4 場(chǎng)景下的一些例子:

圖片

由上述可知, 無符號(hào)編碼無法表示負(fù)數(shù),因此只能表示無符號(hào)整數(shù) 。為了表示有符號(hào)整數(shù),還要探尋另一種編碼方式。

原碼編碼(True Form Encodings)

為了區(qū)分正數(shù)和負(fù)數(shù),很容易想到使用一個(gè) bit 位作為 符號(hào)位 , 表示正數(shù), 表示負(fù)數(shù)。在無符號(hào)編碼的基礎(chǔ)上,使用最高位作為符號(hào)位,其他位含義不變,得出 原碼編碼 形式:

比如,w = 4 場(chǎng)景下的一些例子:

圖片

雖然原碼編碼方式簡(jiǎn)單直觀,但它還存在兩個(gè)問題:

(1) 存在兩種編碼形式

原碼編碼方式下, 存在兩種編碼形式, 和 。同一個(gè)整數(shù)值,卻有兩種編碼,這對(duì)計(jì)算機(jī)系統(tǒng)來說沒什么意義,反而是一種浪費(fèi)。

(2)帶負(fù)數(shù)的加法運(yùn)算不正確

原碼編碼方式下,兩個(gè)正數(shù)的加法沒問題,一旦帶上負(fù)數(shù),結(jié)果就出錯(cuò)了:

圖片

所以,原碼編碼方式,注定不會(huì)被使用。

補(bǔ)碼編碼(Two's-complement Encodings)

于是,補(bǔ)碼編碼 被發(fā)明,它也是建立在無符號(hào)編碼的基礎(chǔ)上,仍然取最高位為符號(hào)位,編碼方式是這樣:

它與無符號(hào)編碼的唯一區(qū)別是,最高位的取值從 變成了

比如,w = 4 場(chǎng)景下的一些例子:

圖片

補(bǔ)碼編碼很巧妙地解決了原碼編碼的兩個(gè)問題:

首先,0 在補(bǔ)碼編碼下只有一種編碼形式, 。

此外,帶負(fù)數(shù)的加法運(yùn)算,也正確了。

圖片

因?yàn)檠a(bǔ)碼編碼的簡(jiǎn)單和正確性,目前,幾乎所有的計(jì)算機(jī)系統(tǒng),都采用補(bǔ)碼編碼來表示有符號(hào)整數(shù)

位運(yùn)算

位運(yùn)算主要包含 取反異或移位 等幾種,我們?cè)跇I(yè)務(wù)開發(fā)時(shí)用得比較少,但如果你有閱讀開源代碼的習(xí)慣,就會(huì)經(jīng)常發(fā)現(xiàn)它們的蹤跡。如果碰巧對(duì)位運(yùn)算不熟悉,那么閱讀這些代碼,就同讀天書一般。

取反(~)、與(&)、或(|)、異或(^)的規(guī)則比較簡(jiǎn)單:

圖片

移位運(yùn)算,可以分成 左移右移 兩種,其中,右移又可分為 邏輯右移算術(shù)右移

左移(<<)運(yùn)算,是對(duì)二進(jìn)制整數(shù),向左移若干位,高位丟棄,低位補(bǔ)零 。也即,對(duì) 左移 位,得到 。

比如,對(duì) int i = -1 左移 10 位,會(huì)得到 i = -1024 的結(jié)果:

// Java語言
public static void main(String[] args) {
    int i = -1;
    System.out.println("Before << , i's value is " + i);
    System.out.println("i's binary string is " + Integer.toBinaryString(i));
    i <<= 10;
    System.out.println("After << , i's value is " + i);
    System.out.println("i's binary string is " + Integer.toBinaryString(i));
}
// 輸出結(jié)果:
Before << , i's value is -1
i's binary string is 11111111111111111111111111111111
After << , i's value is -1024
i's binary string is 11111111111111111111110000000000

圖片

在 C/C++ 中,兩種右移操作符都是 >>,對(duì)無符號(hào)整數(shù)用的是邏輯右移,對(duì)有符號(hào)整數(shù)用的是算術(shù)右移;在 Java 中,邏輯右移的操作符是 >>>,算術(shù)右移的操作符是 >>。為了方便區(qū)分,下文統(tǒng)一用 Java 的表示方法。

邏輯右移(>>>)運(yùn)算,是對(duì)二進(jìn)制整數(shù),向右移若干位,高位補(bǔ)零,低位丟棄 。也即,對(duì) 邏輯左移 k 位,得到 。

比如,對(duì) int i = -1 邏輯右移 10 位,會(huì)得到 i = 4194303 的結(jié)果:

// Java語言
public static void main(String[] args) {
    int i = -1;
    System.out.println("Before >>> , i's value is " + i);
    System.out.println("i's binary string is " + Integer.toBinaryString(i));
    i >>>= 10;
    System.out.println("After >>> , i's value is " + i);
    System.out.println("i's binary string is " + Integer.toBinaryString(i));
}
// 輸出結(jié)果:
Before >>> , i's value is -1
i's binary string is 11111111111111111111111111111111
After >>> , i's value is 4194303
i's binary string is 1111111111111111111111

圖片

算術(shù)右移(>>)運(yùn)算,是對(duì)二進(jìn)制整數(shù),向右移若干位,高位補(bǔ)符號(hào)位,低位丟棄 。也即,對(duì) 邏輯左移 k 位,得到 。

比如,對(duì) int i = -1 算術(shù)右移 10 位,仍會(huì)得到 i = -1 的結(jié)果:

// Java語言
public static void main(String[] args) {
    int i = -1;
    System.out.println("Before >> , i's value is " + i);
    System.out.println("i's binary string is " + Integer.toBinaryString(i));
    i >>= 10;
    System.out.println("After >> , i's value is " + i);
    System.out.println("i's binary string is " + Integer.toBinaryString(i));
}
// 輸出結(jié)果:
Before >> , i's value is -1
i's binary string is 11111111111111111111111111111111
After >> , i's value is -1
i's binary string is 11111111111111111111111111111111

圖片

目前為止,介紹移位運(yùn)算的原理時(shí),我們都默認(rèn) k < w,如果 k >= w 會(huì)怎樣

比如, 左移 w 位,結(jié)果會(huì)是 嗎:

// Java語言
public static void main(String[] args) {
    int i1 = -1;
    System.out.println("Before << 31, i1's value is " + i1);
    System.out.println("i1's binary string is " + Integer.toBinaryString(i1));
    i1 <<= 31;
    System.out.println("After << 31, i1's value is " + i1);
    System.out.println("i1's binary string is " + Integer.toBinaryString(i1));

    int i2 = -1;
    System.out.println("Before << 32, i2's value is " + i2);
    System.out.println("i2's binary string is " + Integer.toBinaryString(i2));
    i2 <<= 32;
    System.out.println("After << 32, i2's value is " + i2);
    System.out.println("i2's binary string is " + Integer.toBinaryString(i2));
}
// 輸出結(jié)果:
Before << 31, i1's value is -1
i1's binary string is 11111111111111111111111111111111
After << 31, i1's value is -2147483648
i1's binary string is 10000000000000000000000000000000
Before << 32, i2's value is -1
i2's binary string is 11111111111111111111111111111111
After << 32, i2's value is -1
i2's binary string is 11111111111111111111111111111111

圖片

上述例子中, w = 32,我們發(fā)現(xiàn) k = 31 時(shí),結(jié)果還符合預(yù)期;當(dāng) k = 32 時(shí),結(jié)果不是 0,而是 -1,也即相當(dāng)于 k = 0 時(shí)的結(jié)果。

原因是這樣,對(duì) w 位整數(shù) x,當(dāng)執(zhí)行 x << k 時(shí),實(shí)際執(zhí)行的是 x << (k % w)。所以,當(dāng) i2 << 32 時(shí),實(shí)際是 i2 << 32 % 32 = i2 << 0

右移操作也遵循同樣的規(guī)則,也即 x >> k = x >> (k % w)x >>> k = x >>> (k % w)

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 二進(jìn)制
    +關(guān)注

    關(guān)注

    2

    文章

    804

    瀏覽量

    42168
  • 計(jì)算機(jī)
    +關(guān)注

    關(guān)注

    19

    文章

    7636

    瀏覽量

    90251
  • 編程
    +關(guān)注

    關(guān)注

    88

    文章

    3685

    瀏覽量

    94907
  • 數(shù)值
    +關(guān)注

    關(guān)注

    0

    文章

    80

    瀏覽量

    14539
收藏 人收藏

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    計(jì)算機(jī)系統(tǒng)結(jié)構(gòu)

    計(jì)算機(jī)系統(tǒng)結(jié)構(gòu)
    發(fā)表于 05-09 19:03

    什么是計(jì)算機(jī)系統(tǒng)計(jì)算機(jī)硬件和計(jì)算機(jī)軟件?

    第一章 計(jì)算機(jī)系統(tǒng)概論1. 什么是計(jì)算機(jī)系統(tǒng)計(jì)算機(jī)硬件和計(jì)算機(jī)軟件?硬件和軟件哪個(gè)更重要?解:P3計(jì)算
    發(fā)表于 07-22 09:06

    什么是計(jì)算機(jī)系統(tǒng)?硬件和軟件哪個(gè)更重要?

    第一章計(jì)算機(jī)系統(tǒng)概論1 .什么是計(jì)算機(jī)系統(tǒng)計(jì)算機(jī)硬件和計(jì)算機(jī)軟件?硬件和軟件哪個(gè)更重要?解: P3計(jì)算
    發(fā)表于 07-26 07:18

    計(jì)算機(jī)系統(tǒng)中的軟件系統(tǒng)

    專用計(jì)算機(jī)現(xiàn)代計(jì)算機(jī)運(yùn)算速度最高可達(dá)每秒幾萬億次幾十億次幾億次幾萬次計(jì)算機(jī)輔助制造是計(jì)算機(jī)應(yīng)用領(lǐng)域之一其英文縮寫是所謂的信息是指基本素材非數(shù)值
    發(fā)表于 09-13 07:22

    嵌入式計(jì)算機(jī)系統(tǒng)概述

    硬件子系統(tǒng)和軟件子系統(tǒng)組成的,通過運(yùn)行程序來協(xié)同工作計(jì)算機(jī)硬件:基本的計(jì)算機(jī)硬件系統(tǒng)運(yùn)算器、控
    發(fā)表于 12-22 06:08

    簡(jiǎn)單介紹微型計(jì)算機(jī)的組成

    你了解自己的計(jì)算機(jī)?或者知道單片機(jī)的組成嗎?這一小節(jié)主要簡(jiǎn)單介紹微型計(jì)算機(jī)的組成,以及微型計(jì)算機(jī)系統(tǒng)經(jīng)常用到的概念,包括組成、工作過程、工作原理、數(shù)
    發(fā)表于 01-10 07:11

    計(jì)算機(jī)系統(tǒng)概論

    1.1 計(jì)算機(jī)系統(tǒng)簡(jiǎn)介1.2 計(jì)算機(jī)的基本組成1.3 計(jì)算機(jī)硬件的主要技術(shù)指標(biāo)1.4 本書結(jié)構(gòu)
    發(fā)表于 04-11 09:31 ?0次下載

    微型計(jì)算機(jī)系統(tǒng)

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

    什么是計(jì)算機(jī)系統(tǒng)的容錯(cuò)性

    什么是計(jì)算機(jī)系統(tǒng)的容錯(cuò)性             所謂容錯(cuò)是指在故障存在的情況下計(jì)算機(jī)系統(tǒng)不失效,仍然能夠正常工作的特性
    發(fā)表于 01-08 13:49 ?1689次閱讀

    深入理解計(jì)算機(jī)系統(tǒng)數(shù)值類型

    計(jì)算機(jī)系統(tǒng)中,整數(shù)可以分成 無符號(hào)(unsigned)整數(shù) 和 有符號(hào)(signed)整數(shù) 兩大類,這之下,按照類型表示的 bit 位大小,又可細(xì)分成 8 位的 char/byte/int8
    的頭像 發(fā)表于 08-19 15:17 ?1488次閱讀

    計(jì)算機(jī)系統(tǒng)對(duì)數(shù)值類型編碼運(yùn)算轉(zhuǎn)換原理介紹2

    。正因太熟悉,我們往往不會(huì)深究它們的底層原理。因?yàn)槠綍r(shí)的工作中,知道個(gè)大概,也夠用了。 但,在某些業(yè)務(wù)場(chǎng)景下,比如金融業(yè)務(wù),數(shù)值運(yùn)算不準(zhǔn)確會(huì)帶來災(zāi)難性的后果。這時(shí),你就必須清楚數(shù)值類型
    的頭像 發(fā)表于 05-09 16:31 ?1078次閱讀
    <b class='flag-5'>計(jì)算機(jī)系統(tǒng)</b><b class='flag-5'>對(duì)數(shù)值</b><b class='flag-5'>類型</b>的<b class='flag-5'>編碼</b>、<b class='flag-5'>運(yùn)算</b>、<b class='flag-5'>轉(zhuǎn)換</b>原理<b class='flag-5'>介紹</b>2

    計(jì)算機(jī)系統(tǒng)對(duì)數(shù)值類型編碼運(yùn)算轉(zhuǎn)換原理介紹3

    。正因太熟悉,我們往往不會(huì)深究它們的底層原理。因?yàn)槠綍r(shí)的工作中,知道個(gè)大概,也夠用了。 但,在某些業(yè)務(wù)場(chǎng)景下,比如金融業(yè)務(wù),數(shù)值運(yùn)算不準(zhǔn)確會(huì)帶來災(zāi)難性的后果。這時(shí),你就必須清楚數(shù)值類型
    的頭像 發(fā)表于 05-09 16:31 ?1027次閱讀
    <b class='flag-5'>計(jì)算機(jī)系統(tǒng)</b><b class='flag-5'>對(duì)數(shù)值</b><b class='flag-5'>類型</b>的<b class='flag-5'>編碼</b>、<b class='flag-5'>運(yùn)算</b>、<b class='flag-5'>轉(zhuǎn)換</b>原理<b class='flag-5'>介紹</b>3

    計(jì)算機(jī)系統(tǒng)對(duì)數(shù)值類型編碼運(yùn)算轉(zhuǎn)換原理介紹4

    。正因太熟悉,我們往往不會(huì)深究它們的底層原理。因?yàn)槠綍r(shí)的工作中,知道個(gè)大概,也夠用了。 但,在某些業(yè)務(wù)場(chǎng)景下,比如金融業(yè)務(wù),數(shù)值運(yùn)算不準(zhǔn)確會(huì)帶來災(zāi)難性的后果。這時(shí),你就必須清楚數(shù)值類型
    的頭像 發(fā)表于 05-09 16:31 ?681次閱讀
    <b class='flag-5'>計(jì)算機(jī)系統(tǒng)</b><b class='flag-5'>對(duì)數(shù)值</b><b class='flag-5'>類型</b>的<b class='flag-5'>編碼</b>、<b class='flag-5'>運(yùn)算</b>、<b class='flag-5'>轉(zhuǎn)換</b>原理<b class='flag-5'>介紹</b>4

    計(jì)算機(jī)系統(tǒng)中的關(guān)鍵組件有哪些

    計(jì)算機(jī)系統(tǒng)中,關(guān)鍵組件的協(xié)同工作構(gòu)成了其強(qiáng)大的數(shù)據(jù)處理和運(yùn)算能力。這些組件不僅決定了計(jì)算機(jī)的性能,還影響著用戶的使用體驗(yàn)。以下是對(duì)計(jì)算機(jī)系統(tǒng)中關(guān)鍵組件的詳細(xì)闡述,包括它們的定義、功能
    的頭像 發(fā)表于 07-15 18:18 ?2405次閱讀

    微處理器如何控制計(jì)算機(jī)系統(tǒng)

    微處理器,作為計(jì)算機(jī)系統(tǒng)的核心部件,承擔(dān)著控制整個(gè)計(jì)算機(jī)系統(tǒng)運(yùn)行的重要任務(wù)。它不僅是計(jì)算機(jī)運(yùn)算中心,還是控制中心,負(fù)責(zé)執(zhí)行程序指令、處理數(shù)據(jù)以及協(xié)調(diào)
    的頭像 發(fā)表于 08-22 14:21 ?903次閱讀
    主站蜘蛛池模板: 日韩免费看 | 丁香综合五月 | 午夜看看 | 亚洲青草视频 | 黄www色 | 国产精品一区电影 | 三级黄色片免费观看 | dy888午夜秋霞影院不卡 | 精彩视频一区二区三区 | 天天艹夜夜 | 91视频精品 | 天天澡天天摸天天爽免费 | 国产伦理一区二区三区 | 激情免费视频 | 色欧美在线视频 | 欧美色香蕉 | 欧美一级视频免费观看 | 久久国产精品免费观看 | 666精品国产精品亚洲 | 五月婷婷色播 | 国产免费的野战视频 | 久久性感美女视频 | 五月天情网 | 少妇被按摩 | 成人欧美一区二区三区的电影 | 五月六月伊人狠狠丁香网 | 综合欧美一区二区三区 | 777色狠狠一区二区三区香蕉 | 久久人人网| 天天色天天碰 | 国产一区二区高清在线 | 免费a级午夜绝情美女视频 免费jlzzjlzz在线播放视频 | luxu259在线中文字幕 | 狂捣猛撞侍卫攻双性王爷受 | 亚洲视频一区二区 | 色婷婷在线观看视频 | 日韩加勒比在线 | 中文字幕一区二区三区视频在线 | 午夜免费体验 | 看黄免费在线 | 亚洲欧美日韩在线精品2021 |