C语言怎么计算数据类型范围?
之前在網上看到的一個討論,是誰決定了數據類型的范圍?
比如說,怎么確定 char 就是 ?-128~127 ,而不是 -127~128 呢?
說下規定
signed 的取值范圍是 -(2N-1) to 2N-1 - 1
unsigned 的取值范圍是 0 to (2N-1) + (2N-1 - 1)
只要記住一點就好了,就是最小值,有符號的最小值是 -128 開始,因為0占用了一個位置,所以最大值就只能是127。
無符號的最小值是 0 ,那最大值就是255了。
#怎么計算呢?
如果我們知道 #include<limits.h> 這個頭文件后,可能就很容易了,因為最大值最小值都在這里面有宏定義。
#看一個老外的代碼
#include?<stdio.h> #include?<limits.h> #include?<float.h>int?main() {printf("Range?of?signed?char?%d?to?%d\n",?SCHAR_MIN,?SCHAR_MAX);printf("Range?of?unsigned?char?0?to?%d\n\n",?UCHAR_MAX);printf("Range?of?signed?short?int?%d?to?%d\n",?SHRT_MIN,?SHRT_MAX);printf("Range?of?unsigned?short?int?0?to?%d\n\n",?USHRT_MAX);printf("Range?of?signed?int?%d?to?%d\n",?INT_MIN,?INT_MAX);printf("Range?of?unsigned?int?0?to?%lu\n\n",?UINT_MAX);printf("Range?of?signed?long?int?%ld?to?%ld\n",?LONG_MIN,?LONG_MAX);printf("Range?of?unsigned?long?int?0?to?%lu\n\n",?ULONG_MAX);//?In?some?compilers?LLONG_MIN,?LLONG_MAXprintf("Range?of?signed?long?long?int?%lld?to?%lld\n",?LONG_LONG_MIN,?LONG_LONG_MAX);?//?In?some?compilers?ULLONG_MAXprintf("Range?of?unsigned?long?long?int?0?to?%llu\n\n",?ULONG_LONG_MAX);?printf("Range?of?float?%e?to?%e\n",?FLT_MIN,?FLT_MAX);printf("Range?of?double?%e?to?%e\n",?DBL_MIN,?DBL_MAX);printf("Range?of?long?double?%e?to?%e\n",?LDBL_MIN,?LDBL_MAX);return?0; }#輸出
Range?of?signed?char?-128?to?127 Range?of?unsigned?char?0?to?255Range?of?signed?short?int?-32768?to?32767 Range?of?unsigned?short?int?0?to?65535Range?of?signed?int?-2147483648?to?2147483647 Range?of?unsigned?int?0?to?4294967295Range?of?signed?long?int?-2147483648?to?2147483647 Range?of?unsigned?long?int?0?to?4294967295Range?of?signed?long?long?int?-9223372036854775808?to?9223372036854775807 Range?of?unsigned?long?long?int?0?to?18446744073709551615Range?of?float?1.175494e-038?to?3.402823e+038 Range?of?double?2.225074e-308?to?1.797693e+308 Range?of?long?double?-0.000000e+000?to?-1.#QNAN0e+000--------------------------------#尷尬了
要是我記不住那個頭文件,或者是我記不住那些宏,那要怎么搞呢?所以就有了下面的代碼
#include?"string.h" #include?"stdio.h"int?main() {printf("Range?signed?char?%lld?to?%lld\n",-(1LL?<<?(8*sizeof(char)?-1)),(1LL?<<?(8*sizeof(char)?-1))?-?1);printf("Range?unsigned?char?0?to?%lld\n",(1LL?<<?(8*sizeof(char)?-1))?+?(1LL?<<?(8*sizeof(char)?-1))?-?1);printf("Range?signed?int?%lld?to?%lld\n",-(1LL?<<?(8*sizeof(int)?-1)),(1LL?<<?(8*sizeof(int)?-1))?-?1);printf("Range?unsigned?int?0?to?%lld\n",(1LL?<<?(8*sizeof(int)?-1))?+?(1LL?<<?(8*sizeof(int)?-1))?-?1);printf("Range?signed?long?%lld?to?%lld\n",-(1LL?<<?(8*sizeof(long)?-1)),(1LL?<<?(8*sizeof(long)?-1))?-?1);printf("Range?unsigned?long?0?to?%lld\n",(1LL?<<?(8*sizeof(long)?-1))?+?(1LL?<<?(8*sizeof(long)?-1))?-?1);printf("Range?signed?long?long?%lld?to?%lld\n",-(1LL?<<?(8*sizeof(long?long)?-1)),(1LL?<<?(8*sizeof(long?long)?-1))?-?1);printf("Range?unsigned?long?long?0?to?%llu\n",(1LL?<<?(8*sizeof(long?long)?-1))?+?(1LL?<<?(8*sizeof(long?long)?-1))?-?1);}#輸出
Range?signed?char?-128?to?127 Range?unsigned?char?0?to?255 Range?signed?int?-2147483648?to?2147483647 Range?unsigned?int?0?to?4294967295 Range?signed?long?-2147483648?to?2147483647 Range?unsigned?long?0?to?4294967295 Range?signed?long?long?-9223372036854775808?to?9223372036854775807 Range?unsigned?long?long?0?to?18446744073709551615-------------------------------- Process?exited?after?0.03036?seconds?with?return?value?51如果對上面的不是很理解的話,可以看看我這個圖片
方便理解的圖片#還有一種寫法
這里使用了庫函數pow,但是這個函數返回值是double,這里需要特別注意一下。
#include?"stdio.h" #include?"math.h"int?main() {printf("signed?char?%ld?to?%ld\n",(int)-pow(2,sizeof(char)*8-1),(int)pow(2,sizeof(char)*8-1)?-1);printf("unsigned?char?0?to?%ld\n",(int)pow(2,sizeof(char)*8)?-1);printf("signed?int?%lld?to?%lld\n",(long?long)-pow(2,sizeof(int)*8-1),(long?long)pow(2,sizeof(int)*8-1)?-1);printf("unsigned?int?0?to?%lld\n",(long?long)pow(2,sizeof(int)*8)?-?1);return?0; }#輸出
signed?char?-128?to?127 unsigned?char?0?to?255 signed?int?-2147483648?to?2147483647 unsigned?int?0?to?4294967295--------------------------------因為pow的返回值是 double 使用的時候需要特別注意
# 說一下
數值在計算機里面都是用補碼的形式存儲的,補碼和原碼是不一樣的,特別是負數。
正數的原碼、反碼、補碼都相同。
原碼: 最高位是符號位,其余為是數值位「8421定律」,最高位是0表示正數,1表示負數。
負數的反碼: 在原碼的基礎上,符號位不變,數值位取反。
負數的補碼: 在反碼的基礎上加 1 。
? 推薦閱讀:
? ??專輯|Linux文章匯總
? ??專輯|程序人生
? ??專輯|C語言
嵌入式Linux
微信掃描二維碼,關注我的公眾號?
總結
以上是生活随笔為你收集整理的C语言怎么计算数据类型范围?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 别人不让你发传单怎么办?
- 下一篇: 共享单车项目计划书_共享单车众筹项目商业