2009/11/02

Unsigned vs. Signed in C

在定義整數變數的型態的時候可以加上 unsigned 或是 signed, 例如
unsigned char
unsigned short (int)
unsigned long (int)
unsigned int
----------
signed char
signed short (int)
signed long (int)
signed int
--------------
上面 signed 有加和沒有加是一樣的意義


加上 unsigned 以後,

1. 所需要的資料儲存空間和沒有加 unsigned 時是一樣的

2. 在使用 printf() 列印時基本上你必須分清楚
   unsigned 有影響到的是參數的傳遞, 使用 %d 或是
   %u 基本上是看程式設計者自己的選擇

   int i=-1;
   printf("%d %u\n", i, i);

   會印出
   -1 4294967295

   unsigned int i=-1;
   printf("%d %u\n", i, i);

   也會印出
   -1 4294967295

   char i=-1;
   printf("%d %u\n", i, i);

   還是會印出
   -1 4294967295

   但是
   unsigned char i=-1;
   printf("%d %u\n", i, i);
   則會印出
   255 255
   這不是 %d 和 %u 的問題, 而是
   參數傳遞時資料轉換的問題 (見下面第 3 項)


不一樣的地方有下面幾個

1. 資料的範圍基本上加上 unsigned 以後會變成 2 倍

2. 程式裡比較大小的時候

   int i=1;
   int j=-1;
   if (i>j) printf("i>j\n");
   else printf("i<=j\n");
   你會發現結果是 i>j

   unsigned int i=1;
   int j=-1;
   if (i>j) printf("i>j\n");
   else printf("i<=j\n");
   你會發現結果是 i<=j

   也就是說 signed 和 unsigned 在比較的時候 compiler
   會把 signed int 自動當成 unsigned int 來比較

2. 資料轉換的時候 (或是函式呼叫的時候)
   char i = -128;
   int j = i;
   變數 i 裡面的資料只有 1 個位元組, 要放進
   變數 j 裡面的時候需要做 sign extension
   也就是多出來的 3 個位元組 (24 個 bit) 都要
   填入原來 i 的 sign bit (第 8 個 bit)
   以上例來說 (用二進位表示)
   i: 10000000
   j: 11111111 11111111 11111111 10000000

   unsigned char i = -128;
   int j = i;
   由 unsigned 轉為 signed 時前面一率補 0
   用二進位表示
   i: 10000000
   j: 00000000 00000000 00000000 10000000

   char i = -128;
   unsigned int j = i;
   還是做 sign extension
   用二進位表示
   i: 10000000
   j: 11111111 11111111 11111111 10000000

   函式呼叫的時候會做型態的轉變, 例如
   void fun(int x)
   {
     ...
   }

   呼叫時如果用
   unsigned char i=-1;
   fun(i);
   就會自動做轉換

   呼叫 printf 時會做 default promotion
   因為 printf 函式的定義如下
   int printf(const char *format, ...)

   其中的 ... 代表可以接受任意型態和個數
   的參數, 所有小於四個位元組的整數資料一律
   轉換為四個位元組, 浮點數一律轉為八個位元組

   所以在轉換時也會根據傳入參數是否有 unsigned
   來做 sign extension

source: http://squall.cs.ntou.edu.tw/cprog/Materials/Unsigned.html

製作日期: 04/29/2003 by 丁培毅 (Pei-yih Ting)
E-mail: pyting@cs.ntou.edu.tw TEL: 02 24622192x6615
海洋大學 理工學院 資訊科學系 Lagoon

沒有留言:

2024年React state management趨勢

輕量化 在過去Redux 是 React 狀態管理的首選函式庫。 Redux 提供了強大的功能和靈活性,但也帶來了一定的學習成本和複雜度。 隨著 React 生態的不斷發展,越來越多的開發者開始追求輕量化的狀態管理函式庫。 Zustand 和 Recoil 等庫以其簡單易用、性...