有符號無符號數據類型溢出測試記錄
今天遇到一個比較基礎問題:若有符號位的數據類型溢出會發生什麼後果?
以前記得微機原理上說數據有原碼、反碼、補碼3種表示形式,計算機通常的處理都是按照補碼數據進行的,那麼在一個數據類型的最大值溢出後會發生什麼情況呢。
環境:Qt5.7
#include <QCoreApplication>
#include <limits>
#include <iostream>
#include <QString>
#include <QDebug>
#include <sys/types.h>
#define TYPE_signed int
#define TYPE_NAME_signed "int"
#define TYPE_unsigned unsigned int
#define TYPE_NAME_unsigned "unsigned int"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
const int base = 10;
QString baseStr = base == 10 ? "" : "0x";
qDebug()<<QString(TYPE_NAME_signed" max:%1%2")
.arg(baseStr)
.arg(std::numeric_limits<TYPE_signed>::max(),0,base);
qDebug()<<QString(TYPE_NAME_signed" min:%1%2")
.arg(baseStr)
.arg(std::numeric_limits<TYPE_signed>::min(),0,base);
TYPE_signed symbTest;
symbTest = std::numeric_limits<TYPE_signed>::max();
symbTest += 1;
qDebug()<<QString(TYPE_NAME_signed" Overflow result:%1%2+1=%1%3")
.arg(baseStr)
.arg(std::numeric_limits<TYPE_signed>::max(),0,base)
.arg(symbTest,0,base);
TYPE_signed tmp = symbTest + 1;
qDebug()<<QString(TYPE_NAME_signed" Overflow result:%1%2+1=%1%3")
.arg(baseStr)
.arg(symbTest,0,base)
.arg(tmp,0,base);
qDebug()<<QString(TYPE_NAME_unsigned" max:%1%2")
.arg(baseStr)
.arg(std::numeric_limits<TYPE_unsigned>::max(),0,base);
qDebug()<<QString(TYPE_NAME_unsigned" min:%1%2")
.arg(baseStr)
.arg(std::numeric_limits<TYPE_unsigned>::min(),0,base);
TYPE_unsigned usymbText;
usymbText = std::numeric_limits<TYPE_unsigned>::max();
usymbText += 1;
qDebug()<<QString(TYPE_NAME_unsigned" Overflow result:%1%2+1=%1%3")
.arg(baseStr)
.arg(std::numeric_limits<TYPE_unsigned>::max(),0,base)
.arg(usymbText,0,base);
return a.exec();
}
分別作了幾種數據類型的測試:
int16_t和u_int16_t輸出結果:
“int16_t max:32767”
“int16_t min:-32768”
“int16_t Overflow result:32767+1=-32768”
“int16_t Overflow result:-32768+1=-32767”
“u_int16_t max:65535”
“u_int16_t min:0”
“int16_t Overflow result:65535+1=0”
int和unsigned int輸出結果:
“int max:2147483647”
“int min:-2147483648”
“int Overflow result:2147483647+1=-2147483648”
“int Overflow result:-2147483648+1=-2147483647”
“unsigned int max:4294967295”
“unsigned int min:0”
“unsigned int Overflow result:4294967295+1=0”
結論
- 無符號位最大值加1後會變爲0,重新重0開始加
- 有符號位最大值加1後會變爲有符號位的最小值,繼續在此基礎上遞增
tips
把一個二進制數右移N位,規則爲:
- 如果數字是一個無符號數值,則用0填補最左邊的N位;
- 如果數字是一個有符號數值,則用1填補最左邊的N位。