You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CUDA中((x+y)²/xy)公式计算结果错误,寻求排查方案

CUDA公式计算错误排查:((x+y)²/xy)结果异常问题

错误原因分析

1. pow()函数的浮点精度误差

你代码里用pow(x+y, 2)计算平方,这是浮点运算。对于整数的平方,比如x=55,y=55时,x+y=110,理论上110²=12100,但pow返回的浮点值可能因为精度问题略小于12100(比如12099.999999999998)。这个值除以55*55=3025得到约3.999999999999999,强制转换为long类型时会直接截断小数部分,最终得到3,而非预期的4。

2. 整数除法的截断特性

就算不用pow,直接用整数运算((x+y)*(x+y))/(x*y),当分子无法被分母整除时,整数除法会直接丢弃小数部分。不过在你的场景中,数学上((x+y)²)/(xy) = x/y + y/x + 2,对于正整数x、y来说,这个值必然≥4(当x=y时等于4,否则大于4),但浮点精度误差会让本应等于4的结果变成略小于4,触发错误判断。

修复方案

方案1:替换浮点运算为整数运算

用整数乘法替代pow计算平方,同时注意类型溢出问题(x+y的平方可能超过int范围,需要转成long):

__global__ void proof() {
    int x = 1;
    int y = 1;
    int multi_number = 1000;

    while (true) {
        // 用long类型避免整数溢出
        long numerator = (long)(x + y) * (x + y);
        long denominator = (long)x * y;
        // 使用浮点除法保留小数,加误差容限处理精度问题
        double eq = (double)numerator / denominator;

        printf("\nEquation being used: (%d+%d)^2 / (%d*%d) >= 4", x, y, x, y);
        printf("\nCalculated result: %.2f", eq);

        if (eq < 4 - 1e-9) { // 极小容限避免浮点精度误判
            printf("\nProof Failed: %d, %d", x, y);
            break;
        }

        x++;
        if (x >= multi_number) {
            x = 1;
            y++;
            if (y >= multi_number) {
                printf("\nProof is true for all cases.");
                break;
            }
        }
    }
}

方案2:数学变形彻底避免除法和浮点运算

原公式((x+y)²)/(xy) ≥4可以通过代数变形简化:

展开左边:(x²+2xy+y²)/xy ≥4
两边乘xy(x,y为正整数,xy>0,不等号方向不变):x²+2xy+y² ≥4xy
整理得:x²-2xy+y² ≥0 → (x-y)² ≥0

这个式子对于所有整数x、y都恒成立,因此完全不需要计算除法,直接验证(x-y)² ≥0即可,彻底规避精度问题:

__global__ void proof() {
    int x = 1;
    int y = 1;
    int multi_number = 1000;

    while (true) {
        long diff_sq = (long)(x - y) * (x - y);
        bool satisfies = diff_sq >= 0; // 恒成立,仅作演示

        printf("\nEquation being used: (%d+%d)^2 / (%d*%d) >= 4", x, y, x, y);
        printf("\nVerification via (x-y)² = %ld ≥ 0: %s", diff_sq, satisfies ? "满足条件" : "不满足");

        if (!satisfies) {
            printf("\nProof Failed: %d, %d", x, y);
            break;
        }

        x++;
        if (x >= multi_number) {
            x = 1;
            y++;
            if (y >= multi_number) {
                printf("\nProof is true for all cases.");
                break;
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者Box

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 10:35:23