使用 uint64_t 时输出不正确

问题描述 投票:0回答:1

Create functionpoint_add()实现加点操作。输入参数是2个不同的点。函数返回新的计算点。

#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
c types output
1个回答
4
投票

uint64_t 是无符号的

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

可能以负数结束,当分配给无符号类型时会给出一些非常大的数字。

您可能需要以某种方式在代码中满足这一点。作为测试,您能否将 uint64_t 更改为 int64_t 并查看您得到的结果。

2023 年 3 月 31 日添加

在你重新处理的问题中你有这个:

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;
}

首先……这条线有时会让你心痛:

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

(***** 见下文)

其次,P和Q中的x和y仍然是unsigned int类型。因此,当 P.x - Q.x 变为负数时,您仍然会得到大量数字……除此之外,让我们看一下代码。

我们有:

s = (P.y - Q.y) / (P.x - Q.x) = (2 - 4) / (1 - 3) = -2/-2

但不会是-2/-2,而是18446744073709551614 / 18446744073709551614 = 1

所以,s = 1.

继续前进,

R.x=s*s-P.x-Q.x;
R.y=s*(P.x-Q.x)-P.y;

我们有:

R.x=s*s-P.x-Q.x = 1*1-1-3 = 1-1-3 = -3
R.y=s*(P.x-Q.x)-P.y = 1*(1-3)-2 = 1*-2-2 = -4

但不会是-3和-4,而是18446744073709551613和18446744073709551612,这就是你得到的答案。

***** 对于浮点异常,请参见上文。

© www.soinside.com 2019 - 2024. All rights reserved.