麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > C > 正文

深入理解大數與高精度數的處理問題

2020-01-26 16:08:40
字體:
來源:轉載
供稿:網友
float和double型數據分別是單精度和雙精度型數,他們的取值分別是3.4E+10的負38次方到3.4E+10的38次方,和1.7E+10的負308次方到1.7E+10的308次方。

那么對于float而言,只有6-7位的有效數字,怎么能裝下可達3.4*10^(-38)這么大的數呢?同理,15-16位的double型,也無法裝下1.7*10^(-308)這么大的數啊?

回答: float 6-7位指的是有效數字的位數(精度),而不是數值大小。例如,3.14159267有9位有效數字,數值卻在3~4之間,而350有3位數字,數值卻在300~400之間。所以說float數能達到3.4E+10,但是它的有效數字位數只能達到6-7位,如果3.14159267賦值給一個float變量,那么精度將會丟失。例如
復制代碼 代碼如下:

float a=3234567.1;
float b=3234567;
if( a==b )
    printf("YES");
else
    printf("NO");

將輸出YES,因為a末尾的11超出了float 只能達到6-7位的精度。(如果a=1234567.1;b=3234567)輸入結果將是NO,為什么呢?這就要我們分析:超出精度的部分怎么處理?不是四舍五入,而是二進制位的丟失。所以說有時候能達到6位的精度,有時候能達到7位的精度,取決于該數的二進制表示。

那么我們就想怎么表示超長位數,超大精度的數字呢?
比如123456789123456789123456789(超長30位的大整數);
比如3.14159012345678901234567890123(超高精度30位的小數),這么長的數字,long float都存不下來,這就要借助于“字符串”或者“字符數組”了。

unsigned __int64 n;
無符號__int64類型的變量n,最大值超過了1234567892345678912(20位),可達到約1.8E+19,平常來說應該夠用了。

但是__int64類型的數據不能用C++里面的cout來輸出,應該是cout沒有重載這個類型,如果用printf來輸出,顯然%d, %f, %l都無法滿足20位的精度,網上查到VC6下可以用printf("%I64d/n", n);但是支持的位數不超過20,經我測試,大概超過9.23E+18 輸出的結果就會出錯了。那么最好的辦法是將“長位數”轉換成字符串,如下:
復制代碼 代碼如下:

char buffer[65];
printf("%s", _ui64toa(n, buffer,10) );

函數_ui64toa就是負責將n轉換成字符串的,存入字符數組buffer[65]中,10代表轉換成10進制。

數字轉換為字符串,參考程序如下:
復制代碼 代碼如下:

#include <stdlib.h>
#include <stdio.h>
int main( void )
{
   char buffer[65];
   int r;
   for( r=10; r>=2; --r )
   {
     _itoa( -1, buffer, r );
     printf( "base %d: %s (%d chars)/n", r, buffer, strlen(buffer) );
   }
   printf( "/n" );
   for( r=10; r>=2; --r )
   {
     _i64toa( -1L, buffer, r );
     printf( "base %d: %s (%d chars)/n", r, buffer, strlen(buffer) );
   }
   printf( "/n" );
   for( r=10; r>=2; --r )
   {
     _ui64toa( 0xffffffffffffffffL, buffer, r );
     printf( "base %d: %s (%d chars)/n", r, buffer, strlen(buffer) );
   }
}


復制代碼 代碼如下:

Output
base 10: -1 (2 chars)
base 9: 12068657453 (11 chars)
base 8: 37777777777 (11 chars)
base 7: 211301422353 (12 chars)
base 6: 1550104015503 (13 chars)
base 5: 32244002423140 (14 chars)
base 4: 3333333333333333 (16 chars)
base 3: 102002022201221111210 (21 chars)
base 2: 11111111111111111111111111111111 (32 chars)

base 10: -1 (2 chars)
base 9: 145808576354216723756 (21 chars)
base 8: 1777777777777777777777 (22 chars)
base 7: 45012021522523134134601 (23 chars)
base 6: 3520522010102100444244423 (25 chars)
base 5: 2214220303114400424121122430 (28 chars)
base 4: 33333333333333333333333333333333 (32 chars)
base 3: 11112220022122120101211020120210210211220 (41 chars)
base 2: 1111111111111111111111111111111111111111111111111111111111111111 (64 chars)

base 10: 18446744073709551615 (20 chars)
base 9: 145808576354216723756 (21 chars)
base 8: 1777777777777777777777 (22 chars)
base 7: 45012021522523134134601 (23 chars)
base 6: 3520522010102100444244423 (25 chars)
base 5: 2214220303114400424121122430 (28 chars)
base 4: 33333333333333333333333333333333 (32 chars)
base 3: 11112220022122120101211020120210210211220 (41 chars)
base 2: 1111111111111111111111111111111111111111111111111111111111111111 (64 chars)

PS:可以用這個函數來將10進制整數轉換成二進制字符串;
復制代碼 代碼如下:

int main( void )
{
   char buffer[65];
   _itoa( 12, buffer, 2 );
   printf( "base %d: %s (%d chars)/n", r, buffer, strlen(buffer) );
}

還有一種方法是自己定義字符數組存放超長位數的數,小數點也是可以解決的,然后自己定義這些字符串形式的超長數之間的運算法則并重載運算符,據說這樣做運算效率還是蠻高的。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 欧美日韩在线播放 | 日韩精品a在线观看 | 免费观看黄视频 | 国产1区在线观看 | 亚洲视频在线网 | 特黄一级小说 | 爱操影视 | 夜夜夜影院 | 视频一区二区三区在线观看 | 久久网站免费 | 国产成年人网站 | 91精品国产九九九久久久亚洲 | 在线小视频国产 | 黄色aaa视频 | 国产在线精品一区二区三区不卡 | 欧美精品激情视频 | 国产 视频 一区二区 | 成人在线视频精品 | 国产精品久久久乱弄 | 啪啪毛片 | 国产毛片视频 | 老司机一级毛片 | 男女隐私免费视频 | 精品在线观看一区二区 | 一级做a爰片性色毛片2021 | 免费黄色在线电影 | 爱射av| 国产精品久久久久久久四虎电影 | av免费在线观看国产 | 欧美性受xxxx白人性爽 | 欧美1 | 日韩视频一二区 | 日本不卡二区 | 欧美另类在线视频 | 国产一国产精品一级毛片 | 国产一国产一级毛片视频 | 国产成人高清在线观看 | 最新在线黄色网址 | av电影在线网 | 在线91观看 | 天天夜夜操操 |