C 非斜边数

C 非斜边数,c,function,C,Function,A是一个自然数,其平方不能写成两个非零平方的和 给定两个整数a和b,任务是找到[L,R]范围内所有奇数长度非斜边数的总和,其中代码中这一行存在一些数值问题 temp = sqrt((double)(x*x-i*i)); // where 'temp', 'x' and 'i' are int x*x和i*i都可能溢出。结果是否被转换为双倍并不重要,因为它发生在产品执行之后。您应该使用更大的类型,如long-long,并在乘法之前强制转换值。在这种情况下,转换为double甚至可能会引入一些舍

A是一个自然数,其平方不能写成两个非零平方的和


给定两个整数a和b,任务是找到[L,R]范围内所有奇数长度非斜边数的总和,其中代码中这一行存在一些数值问题

temp = sqrt((double)(x*x-i*i));  // where 'temp', 'x' and 'i' are int
x*x和i*i都可能溢出。结果是否被转换为双倍并不重要,因为它发生在产品执行之后。您应该使用更大的类型,如long-long,并在乘法之前强制转换值。在这种情况下,转换为double甚至可能会引入一些舍入错误

将sqrt的结果指定给int也可能会引入一些不必要的舍入错误。你可以用圆形来防止这些

在这种特殊情况下,您可以使用不同的算法避免sqrt并保存一些迭代:

#include <stdbool.h>

static inline long long sq(int x)
{
    return (long long)x * x;
}

bool is_nonhypotenuse(int x)
{
    long long square_x = sq(x);

    // Meet in the middle, instead of going up to x
    for (int i = 1, j = x - 1; i <= j; i++)
    {
        long long square_j, target = square_x - sq(i);

        // Iterates, instead of calculating the square root
        while ( (square_j = sq(j)) > target )
            --j;
        if ( square_j == target )
            return false;
    }
    return true;
}
或者,假设基数为2,只需使用位移位

int R = b * b - (1 << a);

通过这些修改,您的程序应该输出所需的值。请参见例如…

了解更高的数字,您的意思是什么?尽量缩小范围。您正在使用int,您可能需要考虑使用未签名的long long int。您的区域也会对结果产生问题。您正在将从sqrt直接返回的double转换为int值。假设匹配,则会将结果截断为和int值,丢弃任何小数部分。即使你把温度转换成双倍,==比较的精确性质可能会失败,因为浮点数学并不总是精确的。@Andrewenle他的算法似乎依赖于truncation@AndrewHenle:该==不受浮点舍入的影响,因为它正在比较使用整数算术计算的两个整数。可能重复此整数!我尝试了你的代码,但它给出了相同的错误输出,请参见我编辑的问题。
long long int_pow(int base, int exp)
{
    long long result = 1;
    while ( exp )
    {
        if (exp & 1)
            result *= base;
        exp /= 2;
        base *= base;
    }
    return result;
}
int R = b * b - (1 << a);