我有以下问题。执行此代码时,变量lonpk的值超出了long int值的限制,程序打印的值不正确。问题在于计算加起来为100的数字立方
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <conio.h>
void main(void){
for (long i = -2000; i <= 2000; i++) {
long pi = i * i * i;
if ((i > 0) && (pi > 100)) {
break;
}
for (long j = i; j <= 2000; j++) {
long pj = (pi + (j * j * j));
if ((j > 0) && (pj > 100)) {
break;
}
for (long k = j; k <= 2000; k++) {
long pk = pj + (k * k * k);
if ((k > 0) && (pk > 100)) {
break;
}
if (pk == 100.0) {
printf("%ld",pk);
printf("primer numero=%ld segundo numero=%ld tercer numero=%ld\n",i,j,k);
}
}
}
}
getch();
}
错误的结果
primer numero=-1971 segundo numero=-986 tercer numero=295
correct result
primer numero=-1797 segundo numero=1870 tercer numero=-903
答案 0 :(得分:1)
使用long long
进行数学运算,因为它具有pow(2000,3)
所需的范围。
请注意下面的代码行。第一个可以溢出,假设ULNG_MAX == 2**32 - 1
,而第二个,通过乘以1LL
强制long long
数学来使用 - = - 至少是64位。
long i;
i * i * i
1LL * i * i * i
代码:
for (long i = -2000; i <= 2000; i++) {
long long pi = 1LL * i * (i * i);
if ((i > 0) && (pi > 100)) {
break;
}
for (long j = i; j <= 2000; j++) {
long long pj = (pi + (1LL*j * (j * j)));
if ((j > 0) && (pj > 100)) {
break;
}
for (long k = j; k <= 2000; k++) {
long long pk = pj + (1LL * k * (k * k));
if ((k > 0) && (pk > 100)) {
break;
}
if (pk == 100) {
printf("%lld",pk);
printf("primer numero=%ld segundo numero=%ld tercer numero=%ld\n"
,i,j,k);
}
}
}
}
getch();
}
OP无法访问long long
,然后使用{em>可能具有足够范围/精度的double
来执行此任务。
int main(void) {
for (long i = -2000; i <= 2000; i++) {
double pi = 1.0 * i * (i * i);
if ((i > 0) && (pi > 100)) {
break;
}
for (long j = i; j <= 2000; j++) {
double pj = (pi + (1.0 * j * (j * j)));
if ((j > 0) && (pj > 100)) {
break;
}
for (long k = j; k <= 2000; k++) {
double pk = pj + (1.0 * k * (k * k));
if ((k > 0) && (pk > 100)) {
break;
}
if (pk == 100) {
printf("%.0f", pk);
printf("primer numero=%ld segundo numero=%ld tercer numero=%ld\n", i, j, k);
fflush(stdout);
}
}
}
}
getch();
return 0;
}
100primer numero=-1797 segundo numero=-903 tercer numero=1870
100primer numero=-161 segundo numero=-139 tercer numero=190
100primer numero=-6 segundo numero=-3 tercer numero=7
[编辑]主要加速 - 减少for(k)
,可能快50倍
// k*k*k + pj = 100;
// k = pow(100 - pj, 1.0/3)
long kmin = (long) pow(100 - pj, 1.0/3) - 1;
if (kmin < j) kmin = j;
for (long k = kmin; k <= 2000; k++) {
double pk = pj + (1.0 * k * k * k);
if ((k > 0) && (pk > 100)) {
break;
}