1. 程式人生 > >int、short、char 型別超出範圍賦值

int、short、char 型別超出範圍賦值

以下使用g++編譯器,win32平臺)。 轉載:http://blog.csdn.net/bladeandmaster88/article/details/52903510 具體流程如下: 00000000 00000000 00000000 00000000                 |65535 1.100000 % 65535 = 34464. 2.由於short為有符號數,所以值在-32768 ~ +32768,而此時34464已經超出32768,所以最高位是1,所以為負數。 3.所以34464 - 32768 = 1696. 4.所以此時代表的值為-(32768 - 1696) = -31072

假設short型別的大小是2位元組,int型別的大小是4個位元組。short能表示-32768~32767之間的整數。

以下程式碼:

short s=100000;

能通過編譯,s中的值是多少呢?

實際上,上面的程式碼等價於short s=(short)100000,

也就是說,編譯器對100000強制轉化為short型別,一般是擷取最後16位的值(假設編譯器將100000當int型別看待)。

現在要手算,s的值到底是多少呢?

第一步100000%65536=34464,34464就是100000最後16位的值。

34464大於32767。如果用無符號的short型別儲存34464,那是足夠的(unsigned short的範圍是0~65536)。

但是,同樣的16位的值,用有符號的short型別儲存,就超出範圍了,它表示的就是另外一個值,是一個負數。

第二步,這個負數是多少呢?先看看有關原碼、反碼、補碼的內容。

這裡需要舉一個例子。負數在計算機中使用補碼錶示的。

拿一個位元組的char型別來說,-1,原碼是1000,0001,

反碼是1111,1110(第一位是符號位,不取反,其他7為都取反),反碼加1就是補碼了。因此,-1的補碼是1111,1111。

這8位二進位制,剛好等於unsigned char  a=2^8-1(2^8表示2的8次方)的8位二進位制(1,0000,0000-0000,0001=1111,1111)。

這會不會是個巧合呢?再來看-2,原碼是1000,0010,反碼是1111,1101,補碼是1111,1110。

這8位二進位制,剛好等於unsigned char b=2^8-2的二進位制表示(1,0000,0000-0000,0010=1111,1110)。

再看-127,原碼是1111,1111,反碼是1000,0000,補碼就是1000,0001。

也就是說,-127在計算機中用1000,0001這八位二進位制儲存。

這等價於unsigned char c=2^8-127的二進位制表示,(1,0000,0000-0111,1111=1000,0001)。

特殊的,-128的原碼是什麼?它沒有原碼,因為7位二進位制只能表示到127, 對128沒法表示。

實際上,在計算機中,-128是用1000,0000表示的。這是補碼錶示形式,不是負零。

為什麼呢?因為,1000,0000=2^8-128=1,0000,0000-1000,0000=1000,0000。這符合上面的規律。

那麼,計算機為什麼採用補碼來表示負數呢?是因為補碼可以方便計算,把減法變成加法。

比如,1-2=1+(-2)=0000,0001+1111,1110=1111111=-1。結果也是補碼的形式,很方便。

再比如,-1-2=(-1)+(-2)=1111,1111+1111,1110=1111,1101。

細心的讀者會發現,1111,1111+1111,1110產生了溢位。補碼的好處在於,可以不考慮溢位,結果照樣正確。

為什麼呢?-1-2=(2^8-1)+(2^8-2)=2^8-3+2^8,而2^8-3恰恰是-3的記憶體表示,另外的那個2^8就是進位了。

從這裡可以看出,把這個進位扔掉,結果剛好正確。

第三步,回到原來的問題,34464所表示的16為二進位制,儲存在一個short型別中,結果是多少?

假設這個結果是-a,注意a是一個正數。

那麼,2^16-a=34464(仔細回顧第二步的內容)。

所以,-a=34464-2^16=-31072。

相關推薦

intshortchar 型別超出範圍

以下使用g++編譯器,win32平臺)。 轉載:http://blog.csdn.net/bladeandmaster88/article/details/52903510 具體流程如下: 00000000 00000000 00000000 00000000  

C語言中基本型別charshortintlong等型別的取範圍

        在C語言中,有時候會想知道這些基本型別的取值範圍。用邏輯位操作的方法是可以,比如把整型變數的所有位都賦值1,然後把最高位賦值為0,就可以得到整型的最大值了。         其實,還有一個更簡單的方法獲取這些基本型別的取值範圍。那就是使用系統標頭檔案limi

ARM中charshortintlongfloatdouble資料型別佔多少位

arm是32位微控制器: char:1位元組 short:2位元組 int:4位元組 long:4位元組 float:4位元組 double:8位元組 如果遇到其他微控制器,可以用sizeof測量: printf("char: %d\n", s

弄懂進位制bitjava基本資料型別(byteshortint char String)ASCIIUnicodeUTF-8UTF-16的關聯關係及UTF-8UTF-16編碼原理

首先普及一下基本概念: 1.數值(百度百科):指的是用數目表示的一個量的多少; 2.進位制(百度百科):也就是進位計數制,是人為定義的帶進位的計數方法。對於任何一種進位制---X進位制,就表示每一位置上的數運算時都是逢X進一位。 十進位制是逢十進一,十六進位制是逢十六進一,二進位制就是逢二進

java中byteshortintlongfloatdoublechar基本資料類型範圍

基本型別,在Java中所有數字都是帶符號的。 型別 長度 範圍 byte       8bit/1byte         -27至27-1short     16bit/2byte        -215至215-1int          32bit/4byte       -231至231-1long

java byteshortintlongfloatdoublechar基本資料類型範圍

基本型別,在Java中所有數字都是帶符號的。 型別 長度 範圍 byte 8bit/1byte 負2的7次方,至2的7次方-1 short 16b

在CC++中char short int各占多少個字節

結果 class int c++ namespace div color name names 在C\C++中char 、short 、int各占多少個字節 : #include <bits/stdc++.h> using namespace std; i

java中byteshortcharint的轉換

java中byte、short、 char和Int“字面值”之間可以不加強制型別轉換,只要int型別的“字面值”不超過byte、short、char型別的範圍。如: byte i = 10(java中預設為int型別);可以轉換;byte i = 128;不可以轉換,128

charshortlongdouble佔幾個位元組,32位機中

char佔1位元組,short佔 2 位元組,int 、float、long 都佔 4 位元組,double 佔8 位元組 指標長度和地址匯流排有關。因為指標記錄的就是一個地址,那麼32位的就是4位元組,64位的就是8位元組。 發現一個問題,以下程式碼是在win10 64位系統下跑的

Java基礎之數據比較IntegerShortintshort

類型 lean system ref 拆箱 ots padding and 引用 基礎很重要,基礎很重要,基礎很重要。重要的事情說三遍,。 今天聊一聊Java的數據比較,這個範圍比較大,基礎類型的比較、引用類型的比較。 前提: 1、Java和c#都提供自動裝箱和自動拆

Java基礎之資料比較IntegerShortintshort

基礎很重要,基礎很重要,基礎很重要。重要的事情說三遍。 今天聊一聊Java的資料比較,這個範圍比較大,基礎型別的比較、引用型別的比較。 前提: 1、Java和c#都提供自動裝箱和自動拆箱操作,何為自動裝箱,簡單點說就是將值型別轉換成為引用型別,自動拆箱就是將引用型別轉換成為值型別。並且我們還經常被教導,

CStringwchar和char型別的相互轉換(轉載)

1.標頭檔案中要定義巨集;       #define   UNICODE       #define   _UNICODE    2.char轉換成wchar       const   char   *pFilePathName   =   "c://aa.dll";       int   nLen 

win32中intfloatshortdouble等佔多少個位元組

#include "iostream" #include<stdio.h> #include<stdlib.h> #include<windows.h> using

C語言基礎---intfloatshortdouble等(佔位元組)

#include "iostream" using namespace std; int main() {     cout<<sizeof(char)<<endl;     cout<<sizeof(short)<<endl;

mvc datetime2 資料型別到 datetime 資料型別的轉換產生一個超出範圍

ASP.NET MVC專案中,使用entity framework新增資料遇到“從 datetime2 資料型別到 datetime 資料型別的轉換產生一個超出範圍的值”這個錯誤問題。後經過問題的排查,是由於C#程式碼中實體類所傳入的DateTime型別屬性沒有賦值的原因,其中主要涉及到SQL Se

詳解char型別範圍(-128~127)

類似問題:一個n位有符號整型數值,其範圍為-2^(n-1) ~2^(n-1) -1。 此類問題的根結在於: “人們解決問題時,習慣以人的思維思考問題,但是,計算機本身卻是以機器的思維進行處理的”。 在這裡,就表現為:計算機對資料的處理其實是以“補碼”的形式,而非日常生活中人

從 datetime2 資料型別到 datetime 資料型別的轉換產生一個超出範圍

問題描述:在C#程式中將獲取到的時間,存入到資料庫,於是就遇到了這個問題。 問題分析:datetime和datetime2都是時間格式,只不過在C#的EF框架中,預設的是datetime2型別,它取值範圍是“0001-01-01 到 9999-12-31”,而dateti

從 datetime2 數據類型到 datetime 數據類型的轉換產生一個超出範圍

mvc 異常 highlight ech 解決方案 har sqlserve 要去 轉化 最近在ASP.NET MVC中遇到一個問題,如題,在使用EF數據模型的時候,要去添加一條新的數據到Sqlserver數據庫,在之前項目中並沒有出現該異常,所以去扒了扒demo,發現有幾

Java中兩個byte型別相加結果給byte型別的變數會報編譯錯誤,byte加byte的結果為什麼是int

背景: 之前偶然看到有討論這個問題,在網上搜了半天,結果都不盡如人意,解釋沒有到位, 有的說byte加byte預設就是int,那為什麼這麼做呢? 這不是找麻煩麼?這種奇怪的預設還有哪些?帶來一些列疑問。。。。。。 有的說byte儲存的就是整型資料,這種說法的對錯姑且不論,至少我覺得難免有

Java——finalstaticstatic final修飾的欄位的區別

static修飾的欄位在類載入過程中的準備階段被初始化為0或null等預設值,而後在初始化階段(觸發類構造器<clinit>)才會被賦予程式碼中設定的值,如果沒有設定值,那麼它的值就為預設值。 final修飾的欄位在執行時被初始化(可以直接賦值,也可以在例項構造