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

使用uint64_t实现point_add函数时输出异常的修复求助

椭圆曲线点加法函数异常修复

问题背景

需要实现point_add()函数完成不同点的加法操作,但原代码运行仅第三个测试用例正确,前两个出现异常,修改后问题仍未解决。

原代码

#include <stdio.h>
#include <stdint.h>


typedef struct {
    uint64_t x;
    uint64_t y;
} point;


point point_add(point P, point Q){
    point R;
    R.x = 0;
    R.y = 0;

    if(P.x == Q.x && P.y == Q.y) return R;
    
    double s = ((double)(P.y - Q.y))/((double)(P.x-Q.x));
    R.x=s*s-P.x-Q.x;
    R.y=s*(P.x-Q.x)-P.y;

return R;
}

int main(){ 
  point A = {1, 2};
  point B = {3, 4};
  point C = {5, 6};
  point D;

  // Test case 1: A + B
  D = point_add(A, B);
  printf("(%lu, %lu) + (%lu, %lu) = (%lu, %lu)\n", A.x, A.y, B.x, B.y, D.x, D.y);
  // Expected output: (1, 2) + (3, 4) = (2, 3)

  // Test case 2: B + C
  D = point_add(B, C);
  printf("(%lu, %lu) + (%lu, %lu) = (%lu, %lu)\n", B.x, B.y, C.x, C.y, D.x, D.y);
  // Expected output: (3, 4) + (5, 6) = (-11, -30)

  // Test case 3: A + A
  D = point_add(A, A);
  printf("(%lu, %lu) + (%lu, %lu) = (%lu, %lu)\n", A.x, A.y, A.x, A.y, D.x, D.y);
  // Expected output: (1, 2) + (1, 2) = (0, 0)

    return 0;
}

原代码运行输出

(1, 2) + (3, 4) = (18446744073709551613, 9223372036854775808)
(3, 4) + (5, 6) = (18446744073709551609, 9223372036854775808)
(1, 2) + (1, 2) = (0, 0)

修改后的代码(仍存在问题)

point point_add(point P, point Q){
    point R;

    uint16_t s;
    s = (P.y - Q.y) / (P.x - Q.x);

    if((P.x == Q.x && P.y == Q.y)|| (P.x == Q.x && P.x != Q.x)|| s<0){ R.x = 0; R.y = 0;}
    
    R.x=s*s-P.x-Q.x;
    R.y=s*(P.x-Q.x)-P.y;

return R;
}

int main(){ 
  point A = {1, 2};
  point B = {3, 4};
  point C = {5, 6};
  point D;

  D = point_add(A, B);
  printf("%" PRIu64 ",%" PRIu64"\n", D.x, D.y);
  // Expected output: (1, 2) + (3, 4) = (2, 3)

  // Test case 3: A + A
  D = point_add(A, A);
  printf("%" PRIu64 ",%" PRIu64"\n", D.x, D.y);
  // Expected output: (1, 2) + (1, 2) = (0, 0) 

    return 0;
} 

修改后代码运行输出

18446744073709551613,18446744073709551612
Floating point exception

问题分析与修复方案

核心问题

  1. 无符号整数溢出:使用uint64_t存储坐标,计算负数时会触发无符号溢出,导致输出异常大的数值(例如-1会被转换为18446744073709551615)。
  2. 浮点精度丢失:原代码用double计算斜率s,当数值较大时会丢失精度,导致结果偏差。
  3. 逻辑错误:修改后的代码中(P.x == Q.x && P.x != Q.x)是矛盾条件,且用uint16_t存储s会截断数值,还可能因除数为0触发浮点异常。

正确修复代码

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

typedef struct {
    int64_t x;  // 改用有符号整数存储坐标,支持负数结果
    int64_t y;
} point;

point point_add(point P, point Q) {
    point R;

    // 处理同点情况(题目要求输入不同点,保留原逻辑返回(0,0))
    if (P.x == Q.x && P.y == Q.y) {
        R.x = 0;
        R.y = 0;
        return R;
    }

    // 处理垂直线情况(P.x == Q.y但y不同,对应无穷远点,返回(0,0)表示)
    if (P.x == Q.x) {
        R.x = 0;
        R.y = 0;
        return R;
    }

    // 用整数计算斜率,避免浮点精度丢失
    int64_t dy = P.y - Q.y;
    int64_t dx = P.x - Q.x;

    // 题目示例中斜率均为整数,这里先判断是否为整数斜率
    if (dy % dx != 0) {
        // 非整数斜率情况可根据需求自定义处理,此处返回(0,0)
        R.x = 0;
        R.y = 0;
        return R;
    }

    int64_t s = dy / dx;

    // 代入椭圆曲线点加法公式计算
    R.x = s * s - P.x - Q.x;
    R.y = s * (P.x - R.x) - P.y;

    return R;
}

int main() {
    point A = {1, 2};
    point B = {3, 4};
    point C = {5, 6};
    point D;

    // Test case 1: A + B
    D = point_add(A, B);
    printf("(%" PRId64 ", %" PRId64 ") + (%" PRId64 ", %" PRId64 ") = (%" PRId64 ", %" PRId64 ")\n",
           A.x, A.y, B.x, B.y, D.x, D.y);

    // Test case 2: B + C
    D = point_add(B, C);
    printf("(%" PRId64 ", %" PRId64 ") + (%" PRId64 ", %" PRId64 ") = (%" PRId64 ", %" PRId64 ")\n",
           B.x, B.y, C.x, C.y, D.x, D.y);

    // Test case 3: A + A
    D = point_add(A, A);
    printf("(%" PRId64 ", %" PRId64 ") + (%" PRId64 ", %" PRId64 ") = (%" PRId64 ", %" PRId64 ")\n",
           A.x, A.y, A.x, A.y, D.x, D.y);

    return 0;
}

修复说明

  1. 改用有符号整数:将uint64_t替换为int64_t,支持负数坐标输出,避免无符号溢出问题。
  2. 整数运算替代浮点:用整数计算斜率s,完全避免浮点精度丢失的问题,同时处理了斜率非整数的边界情况。
  3. 修正逻辑错误:移除矛盾条件,增加垂直线情况的处理逻辑,确保代码严谨性。
  4. 规范输出格式:使用PRId64宏输出int64_t类型,避免格式不匹配导致的输出异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 10:37:24