1. 程式人生 > >關於操作有符號數的溢位問題

關於操作有符號數的溢位問題

在計算機中,數值的二進位制表示方法主要有:原碼、反碼和補碼。通常取最高位為符號位,0表示正數,1表示負數。正數的原碼、反碼、補碼一樣。而負數的原碼最高位取1,數值位取負數絕對值的二進位制值;反碼的符號位為1,其餘位取反;補碼的符號位為1,其餘位取反加1。

在32位計算機中,有符號字元型變數的取值範圍是-27 ~ 27-1,有符號整型變數的取值範圍是-215~ 215-1,如果將有符號整型變數賦給有符號字元型變數,則高位被截斷,保留低八位。

看一個例子:

#include<stdio.h>
#include<string.h>

int main()
{
	char a[1000];
	int i;
	for(i = 0; i < 1000; i++)
	{
		a[i] = -1 - i;
	}
	printf("%d\n", strlen(a));
	return 0;	
}

語句a[i] = -1 – i ;將有符號整型變數賦給有符號字元型變數,當0 <= i <=127時,不會溢位,a[i]從-1變到-128,當i = 128時,- 1 - i = -129。-129的原碼形式是:

1000 0000 0000 0000 0000 00001000 0001;補碼形式是

1111 1111 1111 1111 1111 11110111 1111;此時將其賦給signed char型別的a[128]時,發生溢位,只保留低八位0111 1111,即127。之後隨著i的增加,a[i]從127逐漸向0靠近,當I = 254時,-1 – I =-255,補碼錶示是:1111 1111 1111 1111 1111 1111 0000 0001,此時a[254] = 1。當i = 255時,a[255] = 0,即將ASCII碼為0的值賦給字元型陣列元素a[255]。隨後a[i]又是從-1 ~ -128,再從127 ~ 0之間反覆變化。

而strlen函式是求取字串的實際長度,當遇到第一個空字元’\0’時,返回,所以strlen(a) = 255。

PS:空字元’\0’(ASCII碼值為0)、零字元’0’(ASCII碼值為48)。

2014年8月10日星期日