__int64 与long long 的区别
?
zz from?http://www.byvoid.com/blog/c-int64/
在C/C++中,64為整型一直是一種沒(méi)有確定規(guī)范的數(shù)據(jù)類型。現(xiàn)今主流的編譯器中,對(duì)64為整型的支持也是標(biāo)準(zhǔn)不一,形態(tài)各異。一般來(lái)說(shuō),64位整型的定義方式有l(wèi)ong long和__int64兩種(VC還支持_int64),而輸出到標(biāo)準(zhǔn)輸出方式有printf(“%lld”,a),printf(“%I64d”,a),和cout << a三種方式。
本文討論的是五種常用的C/C++編譯器對(duì)64位整型的支持,這五種編譯器分別是gcc(mingw32),g++(mingw32),gcc(linux i386),g++(linux i386),Microsoft Visual C++ 6.0。可惜的是,沒(méi)有一種定義和輸出方式組合,同時(shí)兼容這五種編譯器。為徹底弄清不同編譯器對(duì)64位整型,我寫(xiě)了程序?qū)λ鼈冞M(jìn)行了評(píng)測(cè),結(jié)果如下表。
?
| long long | “%lld” | 錯(cuò)誤 | 錯(cuò)誤 | 正確 | 正確 | 無(wú)法編譯 |
| long long | “%I64d” | 正確 | 正確 | 錯(cuò)誤 | 錯(cuò)誤 | 無(wú)法編譯 |
| __int64 | “l(fā)ld” | 錯(cuò)誤 | 錯(cuò)誤 | 無(wú)法編譯 | 無(wú)法編譯 | 錯(cuò)誤 |
| __int64 | “%I64d” | 正確 | 正確 | 無(wú)法編譯 | 無(wú)法編譯 | 正確 |
| long long | cout | 非C++ | 正確 | 非C++ | 正確 | 無(wú)法編譯 |
| __int64 | cout | 非C++ | 正確 | 非C++ | 無(wú)法編譯 | 無(wú)法編譯 |
| long long | printint64() | 正確 | 正確 | 正確 | 正確 | 無(wú)法編譯 |
?
上表中,正確指編譯通過(guò),運(yùn)行完全正確;錯(cuò)誤指編譯雖然通過(guò),但運(yùn)行結(jié)果有誤;無(wú)法編譯指編譯器根本不能編譯完成。觀察上表,我們可以發(fā)現(xiàn)以下幾點(diǎn):
表中最后一行輸出方式中的printint64()是我自己寫(xiě)的一個(gè)函數(shù),可以看出,它的兼容性要好于其他所有的輸出方式,它是一段這樣的代碼:
?
?
這種寫(xiě)法的本質(zhì)是把較大的64位整型拆分為兩個(gè)32位整型,然后依次輸出,低位的部分要補(bǔ)0。看似很笨的寫(xiě)法,效果如何?我把它和cout輸出方式做了比較,因?yàn)樗蚦out都是C++支持跨平臺(tái)的。首先printint64()和cout(不清空緩沖區(qū))的運(yùn)行結(jié)果是完全相同的,不會(huì)出現(xiàn)錯(cuò)誤。我的試驗(yàn)是分別用兩者輸出1000000個(gè)隨機(jī)數(shù),實(shí)際結(jié)果是,printint64()在1.5s內(nèi)跑完了程序,而cout需要2s。cout要稍慢一些,所以在輸出大量數(shù)據(jù)時(shí),要盡量避免使用。
zz from?http://blog.csdn.net/zhlynn/archive/2009/03/28/4032152.aspx
64位整數(shù)全解(增補(bǔ)板)?
??
64位整形引起的混亂主要在兩方面,一是數(shù)據(jù)類型的聲明,二是輸入輸出。
首先是如果我們?cè)谧约簷C(jī)器上寫(xiě)程序的話,情況分類如下:
(1) 在win下的VC6.0里面,聲明數(shù)據(jù)類型的時(shí)候應(yīng)該寫(xiě)作
__int64 a;
輸入輸出的時(shí)候用 %I64d
scanf(”%I64d”,&a);
printf(”%I64d”,a);
(2) 在linux下的gcc/g++里面,數(shù)據(jù)類型聲明寫(xiě)作
long long a;
輸入輸出時(shí)候用 %lld
(3) 在win下的其它IDE里面[包括高版本Visual Studio],數(shù)據(jù)類型聲明用上面兩種均可
輸入輸出用 %I64d
================== 以下可無(wú)視 =========================
以下是對(duì)這種混亂情況的解釋,如無(wú)興趣可以跳過(guò)
首先要說(shuō)的是,和Java等語(yǔ)言不同,C/C++本身并沒(méi)有規(guī)定各數(shù)據(jù)類型的位數(shù),只是限定了一個(gè)大小關(guān)系,也就是規(guī)定從所占的bit數(shù)來(lái)說(shuō),short <= int <= long <= long long。至于具體哪種類型占用多少位,是由你所用的開(kāi)發(fā)平臺(tái)的編譯器決定的。在現(xiàn)在的PC上一個(gè)通常的標(biāo)準(zhǔn)是,int和long同為32位,long long為64位。但是如果換到其它平臺(tái)(如ARM)上,這個(gè)數(shù)字可能會(huì)有不同,類型所占的大小可以用sizeof()運(yùn)算符查看。
long long是C99標(biāo)準(zhǔn)中新引進(jìn)的數(shù)據(jù)類型,在古老的VC6.0中并沒(méi)有這個(gè)類型,所以在VC6.0中用”long long”會(huì)發(fā)生編譯錯(cuò)誤。為了表示64位整數(shù),VC6里采用的是微軟自己搞出來(lái)的一個(gè)數(shù)據(jù)類型,叫做__int64,所以如果你是在VC6.0下編譯的話,應(yīng)該用__int64定義64位整型。新版的Visual Studio已經(jīng)支持long long了。GCC是支持long long的,我們?cè)趙in系統(tǒng)中使用的其它IDE如Dev-Cpp, Code::Blocks等等大多是采用的MinGW編譯環(huán)境,它是與GCC兼容的,所以也支持long long(另外為了與MS兼容,也支持__int64)。如果是在純的linux下,就只能使用long long了。
關(guān)于使用printf的輸入輸出,這里就有一個(gè)更囧的情況。實(shí)際上只要記住,主要的區(qū)分在于操作系統(tǒng):如果在win系統(tǒng)下,那么無(wú)論什么編譯器,一律用%I64d;如果在linux系統(tǒng),一律用%lld。這是因?yàn)镸S提供的msvcrt.dll庫(kù)里使用的就是%I64d的方式,盡管Dev-Cpp等在語(yǔ)法上支持標(biāo)準(zhǔn),但也不得不使用MS提供的dll庫(kù)來(lái)完成IO,所以就造成了這種情況。
==================== 無(wú)視至此 ===========================
那么對(duì)ACMer來(lái)說(shuō),最為關(guān)心的就是在各個(gè)OJ上交題應(yīng)分別使用哪種方式了。其實(shí)方式只有有限的幾種:
如果服務(wù)器是linux系統(tǒng),那么定義用long long,IO用%lld
如果服務(wù)器是win系統(tǒng),那么聲明要針對(duì)編譯器而定:
+ 如果用MS系列編譯器,聲明用__int64 [現(xiàn)在新版的Visual Studio也支持long long了]
+ 如果用MinGW環(huán)境,聲明用long long
+ 無(wú)論什么編譯器,IO一律%I64d
下面把各大OJ情況列表如下:
1. TOJ : Linux系統(tǒng)
2. ZOJ : Linux系統(tǒng)
3. POJ : Win系統(tǒng),語(yǔ)言如選擇C/C++,則用MS編譯器[支持兩種聲明],如選擇GCC/G++,則為MinGW
4. UVa : Linux系統(tǒng)
5. Ural: Win系統(tǒng),MS編譯器[支持兩種聲明]
6. SPOJ: Linux系統(tǒng)
7. SGU : Win系統(tǒng),MS編譯器[支持兩種聲明]
如果有不太清楚的情況可以先看看各OJ上的FAQ,通常會(huì)有說(shuō)明。
另外,為了避免混亂,當(dāng)數(shù)據(jù)量不大時(shí),用cin, cout進(jìn)行輸入輸出也是一種選擇
總結(jié)
以上是生活随笔為你收集整理的__int64 与long long 的区别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 多线程编程基础知识
- 下一篇: Markdown基本语法总结