C 中的 long long 乘法给出错误的结果
long long multiplication in C gives wrong result
我的 C 代码似乎出现了故障,无法将很长的数字相乘并输出结果,而且我无法弄清楚为什么。
这是罪魁祸首代码:
#include "stdio.h"
int main()
{
unsigned long long primes[] = {199453LL, 200723LL, 203317LL, 205103LL, 206603LL, 208057LL, 210323LL, 210961LL, 212827LL, 214237LL, 215693LL, 216319LL};
unsigned long long numbers[6];
int i;
printf("Calculating the numbers to factor!\n");
printf("Size of long: %i\n", sizeof(long));
printf("Size of long long: %i\n", sizeof(long long));
for (i = 0; i < 6; i++)
{
numbers[i] = primes[i]*primes[11-i];
printf("%ld*%ld = %ld\n", primes[i], primes[11-i], numbers[i]);
printf("Result is %ld\n",numbers[i]);
}
return 0;
}
这是我编译它和 运行 时的输出(我在 Linux 上使用 gcc 4.8.2 版)
Calculating the numbers to factor!
Size of long: 4
Size of long long: 8
199453*0 = 216319
Result is 195800547
200723*0 = 215693
Result is 344873079
203317*0 = 214237
Result is 608351169
205103*0 = 212827
Result is 701783221
206603*0 = 210961
Result is 635502523
208057*0 = 210323
Result is 809499451
您的 printf
格式字符串有误。 %ld
需要一个long int
,%lld
是一个long long int
,既然你用的是unsigned long long
,你应该用%llu
,否则大正值将显示为负数。
而且,正如 所注意到的,size_t
(sizeof
) 需要 %zu
。
来自 printf(3):
l
(ell) A following integer conversion corresponds to a long int
or unsigned long int
argument, or a following n conversion
corresponds to a pointer to a long int
argument, or a following c
conversion corresponds to a wint_t
argument, or a following s
conversion corresponds to a pointer to wchar_t
argument.
ll
(ell-ell). A following integer conversion corresponds to a long long int
or unsigned long long int
argument, or a following
n
conversion corresponds to a pointer to a
long long int
argument.
...
z
A following integer conversion corresponds to a size_t
or ssize_t
argument. (Linux libc5 has Z with this meaning. Don't use it.)
现在,例如这个输出
199453*0 = 216319
发生是因为小端64位数字199453、216319和43145473507被正确压入堆栈;但是 printf
期望在堆栈上只找到 32 位数字,因此它打印 199453、0(这是 64 位数字 199453 的前 4 个字节)和 216319。
我的 C 代码似乎出现了故障,无法将很长的数字相乘并输出结果,而且我无法弄清楚为什么。
这是罪魁祸首代码:
#include "stdio.h"
int main()
{
unsigned long long primes[] = {199453LL, 200723LL, 203317LL, 205103LL, 206603LL, 208057LL, 210323LL, 210961LL, 212827LL, 214237LL, 215693LL, 216319LL};
unsigned long long numbers[6];
int i;
printf("Calculating the numbers to factor!\n");
printf("Size of long: %i\n", sizeof(long));
printf("Size of long long: %i\n", sizeof(long long));
for (i = 0; i < 6; i++)
{
numbers[i] = primes[i]*primes[11-i];
printf("%ld*%ld = %ld\n", primes[i], primes[11-i], numbers[i]);
printf("Result is %ld\n",numbers[i]);
}
return 0;
}
这是我编译它和 运行 时的输出(我在 Linux 上使用 gcc 4.8.2 版)
Calculating the numbers to factor!
Size of long: 4
Size of long long: 8
199453*0 = 216319
Result is 195800547
200723*0 = 215693
Result is 344873079
203317*0 = 214237
Result is 608351169
205103*0 = 212827
Result is 701783221
206603*0 = 210961
Result is 635502523
208057*0 = 210323
Result is 809499451
您的 printf
格式字符串有误。 %ld
需要一个long int
,%lld
是一个long long int
,既然你用的是unsigned long long
,你应该用%llu
,否则大正值将显示为负数。
而且,正如 size_t
(sizeof
) 需要 %zu
。
来自 printf(3):
l
(ell) A following integer conversion corresponds to along int
orunsigned long int
argument, or a following n conversion corresponds to a pointer to along int
argument, or a followingc
conversion corresponds to awint_t
argument, or a followings
conversion corresponds to a pointer towchar_t
argument.
ll
(ell-ell). A following integer conversion corresponds to along long int
orunsigned long long int
argument, or a followingn
conversion corresponds to a pointer to along long int
argument....
z
A following integer conversion corresponds to asize_t
orssize_t
argument. (Linux libc5 has Z with this meaning. Don't use it.)
现在,例如这个输出
199453*0 = 216319
发生是因为小端64位数字199453、216319和43145473507被正确压入堆栈;但是 printf
期望在堆栈上只找到 32 位数字,因此它打印 199453、0(这是 64 位数字 199453 的前 4 个字节)和 216319。