為什麼int8的範圍是[-128,127]

2021-03-02 庫裡的深夜食堂

今天這篇文章非常基礎。

忘了前幾天在哪看到的一道題目。

func main() {  var a int8 = -1  var b int8 = -128 / a  fmt.Println("b的值是:", b)}

問b的值是多少?如果直接說 128,那可能還需要再去補補,畢竟 int8 的範圍在 『-128,127』。

這道題的正確答案是 -128。那麼問題來了:



在開始之前,我們先來個簡單介紹。

一個數在計算機中的二進位表示方式,叫做這個數的機器數。機器數是帶符號的,計算機用最高數位存放符號,正數為0,負數為1。

打個比方

我們定義一個 number 的變量,它的類型是 int8,轉換成二進位就是 00000011,如果是 -3,那麼二進位就是 10000011。這裡的00000011 和 10000011 就是機器數。


因為機器數的第一位是符號位,所以機器數的形式值就不等於真正的數值,比如上面的 10000011 最高位 1 表示負,真正的值是 -3 ,而不是 131(10000011 二進位轉為十進位等於131)。所以,為了區分,就把帶符號位的機器數真正對應的數值稱為機器數的真值。

0000 0001 的真值是 +000 0001 = +11000 0011 的真值是 -000 0011 = -3


我們接著去了解原碼,反碼以及補碼。

原碼

原碼就是符號位加上真值的絕對值。比如下面這個

[+1]原 = 0000 0001[-1]原 = 1000 0001 

原碼是最容易理解的。因為第一位是符號位,所以 8 位的二進位原碼的取值範圍是

[11111 1111,0111 1111] 即 [-127,127]

反碼

正數的反碼是它本身,負數的反碼是在其原碼的基礎上,符號位不變,其餘各個位取反

[+1] = [0000 0001]原 = [0000 0001]反[-1] = [1000,0001]原 = [1111,1110]反


這樣的話,如果一個反碼表示的是負數,你無法直觀的看出它的數值,通常需要轉化成原碼再進行計算。

補碼

正數的補碼就是它本身。負數的補碼是在其原碼的基礎上,符號位不變,其餘位取反,最後 +1。也就是在反碼的基礎上 +1。

同理,補碼表示形式也是人腦無法直觀看出數值的,也需要轉化成原碼再計算其數值。

從上面可以看出,原碼,反碼和補碼是完全不同的,只有原碼才是被人腦直接識別並用於計算表達方式的。為什麼還需要反碼和補碼?

對於計算機來說,加減乘除已經是基礎的運算了,要設計的儘量簡單,計算機識別 「符號位」顯然會讓計算機的基礎電路設計變得複雜。於是想到把符號位也參與到運算中。我們知道,根據運算法則,減去一個數等於加上一個負數。1-1 = 1+(-1) = 0 因此計算機可以只有加法沒有減法。

我們先看原碼,十進位的表達式:1-1=0

如果用原碼表示,讓符號位也參與運算,顯然對於減法來說,結果不是正確的。這也就是為何計算機內部不使用原碼表示一個數。

接著,為了解決原碼做減法的問題,出現了反碼:

可以發現,如果使用反碼計算減法,結果的真值的部分是正確的,但是引發了新的問題,雖然在理解上 +0 和 -0 是一樣的,但是 0 帶符號是沒有任何意義的。而且會有 [0000 0000] 和 [1000 0000] 兩個編碼表示0。

補碼終於要閃亮登場了。

這樣,0用[0000 0000] 表示,之前的 -0 問題就不存在了,而且可以用[1000,0000] 表示-128:

在用補碼運算的結果中,[1000 0000]補 的值就是 -128。實際上是使用之前的 -0的補碼來表示 -128,所以 -128 並沒有原碼和反碼的表示。這也是為什麼 int8 使用原碼或者反碼表示的範圍為[-127,127]。使用補碼,不僅僅修復了 0 的符號以及存在兩個編碼的問題,而且還能多表示一個最低數。

好了,我們再回到問題的本身。因為 var b int8 = -128 / a 不是常量表達式,因此 untyped 常量 -128 隱式轉換為 int 8類型(和a一樣),所以 -128 / a 的結果是 int8 類型,值是 128。超出了 int8 的範圍,因為結果不是常量,允許溢出,128的二進位表達式是[1000 0000],正好是 -128 的補碼,因此答案是 -128。

參考文章

相關焦點

  • 關於java中byte取值範圍最小值為什麼是-128而不是-127引發的思考
    那麼一個byte表示的二進位應該為0000 0000 -1111 1111,又因為最高位代表符號位,那麼一個byte表示的範圍就應該為(-2^7-1)-(2^7-1)即-127到127怎麼會有-128呢?其實也沒有什麼好說的,這就是規定的,包括short,int,long這些都是一樣!那麼為什麼這麼規定呢?有興趣的可以繼續往下看。
  • C語言中signed char類型,能表示-128到127,為什麼負數多一位?
    因此按理說,signed char 類型能夠表示的數值範圍為 -0b111111到 +0b1111111,也即 -127 到 127。但是很多教科書上卻說 signed char 類型能夠表示的數值範圍為 -128 到 127,類似的還有 signed short 類型能夠表示的數值範圍為 -32768 到 32767,signed int 類型能夠表示的數值範圍為 -2147483648 到 2147483647,為什麼有符號的整數類型,負數部分總是比整數部分多出一個數呢?
  • Byte字節的最小值為什麼是-128?
    hi,大家好歡迎來到大熊實驗室,今天在看書的時候突然間意識到一個嚴重的問題,那就是byte字節的最小值是-128,為什麼會這樣呢?今天就來研究一下。字節是我們在開發中使用的除了bit以外最小粒度的單位,但是關於字節的最小值是-128我一直都沒搞懂究竟是為什麼,按照我的理解一個字節最小值應該是-127,那怎麼來的-128呢?在計算機系統中,最小單位是1位,也就是1bit。
  • 雙色球128期和127期對比,中獎號碼和一等獎是有哪些不同
    今天我們要先說128期的,雙色球20012的開獎結果是08 10 15 16 23 26藍碼10,中獎結果是一等獎:14注,二等獎:137注,三等獎:2252注,四等獎:102352注,五等獎:1676644注,六等獎:15148292注。
  • 吊打面試官系列:說說Integer緩存範圍
    * JLS協議要求緩存在-128到127之間(包含邊界值)     *     * The cache is initialized on first usage.                      // 如果該值配置錯誤則忽略該參數配置的值,使用默認範圍-128~127                }            }            high = h;            cache = new Integer[(high - low) + 1];            int
  • 萬界仙蹤127-128:葉星雲三大後宮齊聚一堂,穿幫鏡頭出現
    葉星雲自然不是被嚇大的,催動斬仙飛刀攻向魔主,但是魔主只用了一根手指就輕鬆瓦解了攻勢,接著制住了葉星雲……三美齊聚時的穿幫128集之前,羽音、葉嫣然、葉雪雲三人兩兩同框出現過。葉嫣然和羽音互相看不順眼,葉嫣然和葉雪雲互為競爭對手,羽音對葉雪雲無感,葉雪雲視羽音為情敵。
  • labview之如何獲取數據類型的取值範圍
    的最大值為255,最小值為0,所以U8的取值範圍是0-255。  今天我們要討論的是如何獲取整數數據類型的取值範圍的方法:  一、計算法  我們知道U8是由一個字節(8位)構成的,U16是由2個字節(16位)構成的,以此類推,U64由8個字節構成(64位)。因此對於整型無符號數的取值範圍很容易計算出來,無符號整數的最小值均為0,最大值可以通過計算得到。
  • 通過本質看現象:關於Integer受內部初始範圍而出現的有趣現象
    通常情況兩者默認初始化為IntegerCache.high=127,IntegerCache.low=-128,同時,Integer內部還有一個靜態static代碼塊,它會在類被加載時被執行,該代碼塊如下:static {int h = 127;String integerCacheHighPropValue =sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high
  • 第127期雙色球開獎結果
    第127期雙色球開獎結果如下:紅球:1,26,18,19,4,31籃球:7總和:106現在我們來分析一下本期開獎號碼與本人預測的號碼分布位置的比較與差別本人預測的127期號碼在投注單上的分布位置如下圖一所示:
  • 為什麼阿里巴巴Java開發手冊強制整型包裝類對象值用equals比較?
    會緩存 -128 到 127 之間的賦值?為什麼會緩存這個範圍的賦值?如何學習和分析類似的問題?那麼為什麼答案是這樣?結合《阿里巴巴Java開發手冊》的描述很多人可能會回答:因為緩存了 -128 到 127 之間的數值,就沒有然後了。那麼為什麼會緩存這一段區間的數值?緩存的區間可以修改嗎?其它的包裝類型有沒有類似緩存?
  • 為什麼Java中1000==1000為false而100==100為true?
    如果你看去看 Integer.Java 類,你會發現有一個內部私有類,IntegerCache.java,它緩存了從-128到127之間的所有的整數對象。我們可以看到:public static Integer valueOf(int i) { if (i >= IntegerCache.low && i     return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i);}如果值的範圍在
  • 華為暢享10S(8GB/128GB)雲南1729元
    【中關村在線雲南行情】華為暢享10S(8GB/128GB/全網通)手機,近日在商家「糖兜數碼(送貨以舊換新)」特價促銷,優惠價為1729元,好物好價,值得您入手!華為暢享10S(8GB/128GB/全網通)產品亮點為超廣角AI三攝,AI逆光美拍,光感屏幕指紋。感興趣的朋友可直接前往昆明市五華區圓通北路127號佰騰數碼廣場B座13樓1311室詳詢,關於華為暢享10S(8GB/128GB/全網通)手機的促銷信息也可諮詢(聯繫電話:13888773000 0871-65310367 QQ:237886683 )該商家。
  • 問號臉為什麼 Java 中1000==1000 為 false而 100==100 為 true
    如果你看去看 Integer.java 類,你會發現有一個內部私有類,IntegerCache.java,它緩存了從-128到127之間的所有的整數對象。IntegerCache.low && i return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }如果值的範圍在
  • 為什麼 Java 中 100==100 為 true?
    如果你看去看 Integer.java 類,你會發現有一個內部私有類,IntegerCache.java,它緩存了從 - 128 到 127 之間的所有的整數對象。Integer valueOf(int i) {      if (i >= IntegerCache.low && i          return IntegerCache.cache\[i + (-IntegerCache.low)\];      return new Integer(i);    }如果值的範圍在
  • 漲姿勢:為什麼Java中「1000==1000」為false,而」100==100「為true?
    來源:程式設計師曉夢為什麼 Java 中「1000==1000」為false,而」100==100「為true?
  • 為什麼 Java 中「1000==1000」為false,而」100==100「為true?
    來自: 碼農網譯文連結:http://www.codeceo.com/article/why-java-1000-100.html英文原文:https://dzone.com/articles/why-1000-1000-returns-false-but-100-100-returns-tr為什麼
  • 榮耀X10(6GB/128GB/全網通/5G版) 雲南
    榮耀X10(6GB/128GB/全網通/5G版)產品亮點為5G雙模,麒麟820,4300mAh續航,4000萬高感光影像。感興趣的朋友可直接前往昆明市五華區圓通北路127號佰騰數碼廣場B座13樓1311室詳詢,關於榮耀X10(6GB/128GB/全網通/5G版)手機的促銷信息也可諮詢(聯繫電話:13888773000 0871-65310367 QQ:237886683 )該商家。
  • 為什麼Java中1000==1000為false,而100==100為true?
    如果你看去看 Integer.java 類,你會發現有一個內部私有類,IntegerCache.java,它緩存了從 - 128 到 127 之間的所有的整數對象。IntegerCache.low && i return IntegerCache.cache\[i + (-IntegerCache.low)\]; return new Integer(i); }如果值的範圍在
  • 福彩3D2011240期:百位落點128 精選碼237
    福彩3D2011240期:百位落點128 精選碼237 2011-09-04 14:42:14.0來源:愛彩票作者:愛彩四眼哥已瀏覽: 次 福彩3D2011239