回到「13. 額外語法 (Extra syntax)」
上一頁
請注意,這裡只介紹小莫用過的型別,但應該已經非常非常夠用了!
為了方便介紹,小莫將其分為兩大類:「浮點數」和「整數」(註13)
- 浮點數
- 特色:支援小數、有微小誤差、數字範圍大
- 溢位會怎樣:超過最大值會變成inf,超過最小值會變成-inf
- 除以0會怎樣:正數除以0會變成inf、負數除以0會變成-inf,0除以0會變成nan (「not a number」的縮寫)
-
型別有哪些:
名稱 float double long double __float128 占用記憶體 32位元 64位元 96位元 128位元 誤差和數字範圍 占用記憶體越大,誤差越小、數字範圍越大 輸入(scanf) %f %lf 不支援 不支援 輸出(printf) %f %f 不支援 不支援 - 整數
- 特色:不支援小數、沒有誤差、數字範圍小
- 溢位會怎樣:超過最大值會變成最小值,超過最小值會變成最大值
- 除以0會怎樣:會造成不可預知的錯誤,通常是程式出錯並停止運作
-
型別有哪些:
名稱 bool char short int long long __int128 占用記憶體 8位元 8位元 16位元 32位元 64位元 128位元 數字範圍 $0\sim 1$ $(-2^{占用記憶體-1})\sim (2^{占用記憶體-1}-1)$ 輸入(scanf) 不支援 %c 不支援 %d %lld 不支援 輸入(scanf) 不支援 %c 不支援 %d %lld 不支援
斜體標示 (針對__int128):如果要使用此型別,請先參考前一頁並設定好編譯參數,以使用C++11的功能 - 另外,整數還可以用「unsigned」修飾而有更多玩法!意者請Google搜尋「C++ unsigned 用法」
#include<cstdio> int main() { double a,b; long double c,d,e; scanf("%lf%lf",&a,&b); c=a; d=b; e=c+d; double f=(double)e;//請注意,「f」的誤差是「double」等級 (而不是「long double」等級) printf("%f\n",f); return 0; }
這種方式並不是最好的 (支援「long double」等級的加法運算,但不支援「long double」等級的輸入輸出)
如果要讓程式支援「long double」等級的輸入輸出,請自行處理每個位數的輸入輸出,但這會複雜許多 (真的複雜許多,別怪我沒警告你),方法如下 (不想看的話可以直接跳過):
#include<cstdio> bool IsDigit(char c) { return '0'<=c&&c<='9'; } int main() { long double a=0; { char c; while(1) { scanf("%c",&c); if(!IsDigit(c))break; a=a*10+(c-'0'); } if(c=='.')//如果有小數點 { long double digit=0.1; while(c) { scanf("%c",&c); if(!IsDigit(c))break; a=a+digit*(c-'0'); digit=digit/10; } } } { int count=0; while(a/10>=1) { a=a/10; count=count+1; } while(count>=-50)//假設要輸出小數點以下50位數 { if(0<=a&&a<1)printf("0"); else if(1<=a&&a<2) { printf("1"); a=a-1; } else if(2<=a&&a<3) { printf("2"); a=a-2; } else if(3<=a&&a<4) { printf("3"); a=a-3; } else if(4<=a&&a<5) { printf("4"); a=a-4; } else if(5<=a&&a<6) { printf("5"); a=a-5; } else if(6<=a&&a<7) { printf("6"); a=a-6; } else if(7<=a&&a<8) { printf("7"); a=a-7; } else if(8<=a&&a<9) { printf("8"); a=a-8; } else if(9<=a&&a<10) { printf("9"); a=a-9; } else { printf("錯誤!!!不該發生這種情況的!!!\n"); return 0; } if(count==0)printf(".");//剛剛輸出的是個位數字,是時候接小數點了 count=count-1; a=a*10; } printf("\n"); } return 0; }
這樣真的可以支援輸入輸出「long double」等級的位數嗎?
把程式碼中兩個「long double」都改成「double」,輸入「123456789.0123456789」看看
你會發現「double」和「long double」之間的差異
「double」版本 |
「long double」版本 |
如果需要儲存更多位數怎麼辦?
抱歉,目前的方法只有自行模擬直式運算 (其中一種方法是用很大的陣列儲存一個一個的位數,這種方式比上面那個恐怖的東西複雜10倍以上)
或者,請祈禱更新版的C++ (C++17快出來了) 會提供大數型別
下一頁
感謝:
(版權所有 All copyright reserved)
沒有留言:
張貼留言
歡迎留言或問問題~
若您的留言中包含程式碼,請參考這篇
如果留言不見了請別慌,那是因為被google誤判成垃圾留言,小莫會盡快將其手動還原
注意:只有此網誌的成員可以留言。