題目描述
輸入正整數(shù)n,統(tǒng)計(jì)它的正因子個(gè)數(shù),n<= 10^(12),例如n=30時(shí),輸出應(yīng)該為8。
源碼
#include <stdio.h>
#include <math.h>
int main () {
int64_t a;
int count = 0;
printf("請(qǐng)輸入一個(gè)正整數(shù):");
scanf("%lld", &a);
if (a <= 0 || a > pow(10, 12)) {
printf("請(qǐng)輸入一個(gè)正整數(shù),小于10^(12)");
} else {
for (int i = 1; i <= sqrt(a); i++) {
if ((a % i) == 0) {
count += 2;
}
}
printf("%d\n", count);
}
return 0;
}
剖析
這個(gè)題邏輯并不復(fù)雜,核心在于分析整型字節(jié)數(shù)。
1.整型長度
咱們先復(fù)習(xí)幾個(gè)概念知識(shí)。
- 機(jī)器字長
機(jī)器字長指的是CPU一次性能處理的二進(jìn)制位(Bit),如x86-32位、x86-64位架構(gòu)。機(jī)器字長代表了硬件處理速度,CPU處理字長越大,則效率越高,對(duì)寄存器、總線寬度要求也就越高。同時(shí),機(jī)器字長也是寄存器長度,所以指針字節(jié)數(shù)跟硬件配置相關(guān)。因?yàn)橹羔槾鎯?chǔ)的就是地址。64位CPU,指針大小為8字節(jié)。CPU對(duì)應(yīng)的指令字長不一定與機(jī)器字長相同,比如為了兼容,64位機(jī)器字長也可以支持32位指令字長。
- 32位、64位操作系統(tǒng)
操作系統(tǒng)是運(yùn)行在硬件上層的第一層軟件,而操作系統(tǒng)字長則等于指令字長, 小于等于 機(jī)器字長。比如你買了64位架構(gòu)的電腦,裝了個(gè)32位的操作系統(tǒng)。
所以究竟是機(jī)器字長決定整型數(shù)字長還是操作系統(tǒng)字長?都不是。
- 編譯器決定數(shù)據(jù)字長
我使用的gcc編譯器。整型數(shù)據(jù)長度實(shí)際是由編譯器根據(jù)自身硬件長度決定的。
Each compiler is free to choose appropriate sizes for its own hardware, subject only to the restriction that shorts and ints are at least 16bits, longs are at least 32bits, and short is no longer than int, which is no longer than long.
以GCC為例,在32位、64位操作系統(tǒng)中,short 是 2個(gè)字節(jié),int 是4個(gè)字節(jié),32位系統(tǒng)中l(wèi)ong 4個(gè)字節(jié)、long long 8個(gè)字節(jié),64位系統(tǒng)中l(wèi)ong 與 long long 都是 8個(gè)字節(jié)。
題目中輸入數(shù)小于等于1012,大約是214,已經(jīng)超過了int表示的范圍,略寬于-2 * 109 ~ 2 * 109 -1.所以采用了64位整型數(shù)據(jù)類型,等同于使用 long long,范圍大約略寬于 -8 * 1018 ~ 8 * 1018 -1。
2.循環(huán)次數(shù)
如果i是n的因子,那么n/i也是n的因子,所以只需要遍歷到n的算術(shù)平方根即可。
3.輸入校驗(yàn)
題目對(duì)輸入數(shù)據(jù)有大小顯示,所以做下必要的校驗(yàn)。
參考
int類型究竟占幾個(gè)字節(jié)
CPU位數(shù)、操作系統(tǒng)位數(shù)、計(jì)算機(jī)字長、C/C++基本數(shù)據(jù)類型長度