1. 程式人生 > >負數賦值給無符號數的陷阱[轉]

負數賦值給無符號數的陷阱[轉]

原文:http://blog.csdn.net/Songbai_Pu/article/details/9172689

有沒有人嘗試過將負數賦給一個無符號整型變數?知不知道這樣做會發生什麼?還沒有嘗試的就讓我們來探索下無符號整型隱藏的祕密。

先來看看下面程式碼:

int main()
{
      unsigned int val = -1;
      cout<<val<<endl;

      return 0;
}

執行的結果:

4294967295
請按任意鍵繼續. . .

----------------------------------------

你可能禁不住驚歎:這麼大!沒想到吧,把一個負數賦值給無符號整型變數,會產生這麼大的數!為啥呢?好,我們一步步分析:

首先,仔細觀察輸出的結果4294967295,發現4294967295=2^32-1,哦!好像有點規律!但是,又為啥會是這樣?讓我們先來討論下int和unsigned int的表現形式,其中他倆都是4個位元組,32位的二進位制表示,但int有一位是符號位,unsigned則沒有。那-1的int型別表示為1000 0000 0000 0000 0000 0000 0000 0001,那麼將其強制轉換成unsigned int 應該是1000 0000 0000 0000 0000 0000 0000 0001(紅色為符號位),用指數表示是2^31+1,而不是2^32-1!這是怎麼回事呢?(*^__^*) 嘻嘻……,這裡還隱藏著一個小祕密!那就是int在真正儲存在記憶體中的二進位制數不是值的原碼,而是其補碼(為了便於運算,可以參考《數字邏輯》)!那麼在強制型別轉換之前,int變數-1記憶體中儲存的是1

111 1111 1111 1111 1111 1111 1111 1111,等於2^32-1。soso在強轉為unsigned int時,就是讀取該塊記憶體的值賦給變數!這樣val就變成了4294967295,超級大的數!所以各位同仁在處理unsigned int 賦值時一定要謹慎!如果出錯將影響甚大,因為unsigned int一般都會作為for或while迴圈體的標識型別,如果將負值賦給它,將導致嚴重的假死迴圈!痛哉!痛哉!


相關推薦

負數符號陷阱[]

原文:http://blog.csdn.net/Songbai_Pu/article/details/9172689 有沒有人嘗試過將負數賦給一個無符號整型變數?知不知道這樣做會發生什麼?還沒有嘗試的就讓我們來探索下無符號整型隱藏的祕密。 先來看看下面程式碼: i

符號負數(有符號)的理解(unsigned\signedf)

無符號數賦負數(有符號數)就類似於給字元型變數賦數值(char word=0x56),對相同的值不同的型別解析 //s16:signed short; u16:unsigned short s16 temp1=0; //十進位制:0;十六進位制0x0000

從Vuex中取出新的組,新組push時報錯的解決方法

syn 調度系統 scrip vip tor ood 教育 java初學者 str 如下所示: ? 1 Uncaught Error: [vuex] Do not mutate vuex store state outside mutation hand

python_cookbook之路:據結構-解壓可叠代對象多個變量以及擴展的叠代解壓語法(*)

rec 3.4 open pan spl python res cor coo 1.一一對應: >>> data = [ ‘ACME‘, 50, 91.1, (2012, 12, 21) ] >>> name, shares, pri

符號陷阱

示例程式碼: #include <iostream> using namespace std; int main(){ int array[]={

將char* std::string的一些陷阱

這段時間,總是要使用char或者char* 賦值給std::string,踩了不少坑。於是寫了個測試程式碼,如果你不想看我的程式碼,可以跳到下面直接看總結: #include <string> #include <iostream> using

雜湊變形—點陣圖(給定40億個不重複的符號整數,沒排過序,一個符號整數,如何快速判斷一個數是否在這40億個數中)

#include<stdio.h> #include<stdlib.h> #include<assert.h> #include<string.h> typedef struct BitMap { size_t* _bits

printf 注意 以及符號轉化有符號陷阱

%d 是列印有符號數,如果引數是無符號數,要轉化成有符號數 %u 才是列印無符號數,如果引數是有符號數,轉化為無符號數 下面轉自:    無符號數與有符號數之間存在著很多細節問題,稍有不慎就可能導致程式出現不可預料的錯誤。如果說是在長度相同的數值型別之間相互轉

系統ifconfig,一條命令獲取本機ip並將其指定變數來使用

在Linux系統中,準確地獲取本機IP資訊是非常有用的。在寫bash shell指令碼事經常會用到IP,這時就需要我們使用一些辦法獲取本機IP並賦值給變數來使用。最近剛剛完成grep及sed的摸索、研究,本著學以致用的原則,用一條命令獲取本機IP並將其賦值給某個

據庫中查詢出據,結構體。

method sel lec not 取出 eth where turn class 1: method GET_CUSTOMER. DATA: zlt TYPE table OF ZGT_CUSTOMER, "定義內表 z

如何將字符串分割多個shell變量

lock ext shell變量 宋體 for prev spa str -a 如何將字符串分割賦值給多個shell變量shellTarget Target 比如字符串"111|222|333"分割分別賦值給三個shell變量 $ a=‘111|222|333

C# Hashtable另一個Hashtable時

元素 全部 nbsp htable table賦值 tab tor 操作 enume c#中想將一個hashtable的元素全部給另一個hashbale時, 使用叠代一個一個元素賦值 如: ammus.Clear(); IDictionaryEnume

Python學習-解壓可叠代對象多個變量

col 如果 可變 home nbsp one nobody lis 輸出 解壓序列賦值給多個對象 任何的序列(或者是可叠代對象)可以通過一個簡單的賦值語句解壓並賦值給多個變量。唯一的前提就是變量的數量必須跟序列元素的數量是一樣的。 >>> data =

C# 大數組小數組,小數組大數組

賦值 ray min 數組 c# class clas arr [] string[] arraymax = new string[5]; string[] arraymin = new string[3]; string[

KendoUI關於Grid頁面刷新(不修改據庫)

fresh 修改 png row -1 event var 技術 remove 1.Grid頁面某個字段修改賦值(不用刷新) var row = GG.data("kendoGrid").select(); var data = GG.data("kend

js生成隨機編碼並input文本框

查看 技術 根據 1-1 javascrip clas times product pro    效果圖如下:                          頁面代碼:     <div class="form-item form-width-in fr">

saddle中每一個屬性到WebPlate中的同名屬性

一個 this getprop jstring 賦值 () sad ring property //將saddle中每一個屬性賦值給到WebPlate中的同名屬性 foreach (PropertyInfo info in saddle.GetType().Get

符號符號在一起如何處理的

有符號數 無符號數 “當表達式中存在有符號類型和無符號類型時,默認情況下計算的結果將轉化為無符號類型”而對於計算機過程而言,變量本身轉化為有符號還是無符號數,都不會改變在計算機中存儲的位狀態。也就是說有符號和無符號數在計算機中都是以補碼形式存在。舉例:#include <stdio.h>

C語言中 有符號符號、整數溢出 (

alt 原因 () tar sig 重新 detail copyto 想象 [cpp] view plain copy print? #include<stdio.h> void main() { int l=-1; unsigned

Mysql查詢結果只有一條的情況下把變量

lec div class date() where sql logs pan rdate 1 set @n=(SELECT count(day) from log where day=CURDATE()); 2 SELECT @n 把結果中count(day)的值賦值