c - 奇怪的问题 : Getting different calculation results of the area and perimeter of a polyngn (on different machines and on different times)

标签 c

我有一个程序可以计算多边形的面积和周长。程序还会确认面积和周长的计算结果是否与预期结果相同。

我不明白发生了什么,但确认面积和周长是否与预期相同的验证部分无法正常工作。

例如,我现在测试并在所有情况下都得到“数组相同”,这是正确的,因为我在 txt 文件中给出了正确的坐标以匹配每个预期结果。但是我稍后或在不同的机器上进行了测试,我也在 Linux 中进行了测试,在某些情况下会出现“Arrays are diferent”。在不更改坐标文件或代码的情况下发生这种情况真的很奇怪。

你明白为什么会出现这个奇怪的问题吗?

这是文本文件,带有正确的坐标以达到预期的结果:

 1.0 2.5 5.1 5.8 5.9 0.7 
 1.2 4.1 5.1 5.8 6.8 1.9 2.9 0.2
 1.7 4.9 5.1 5.8 7.0 2.8 4.8 0.1 1.5 1.4
 2.1 5.3 5.1 5.8 7.0 3.5 5.9 0.7 2.9 0.2 1.0 2.5
 2.5 5.6 5.1 5.8 6.9 3.9 6.5 1.3 4.2 0.0 1.8 1.0 1.0 3.4
 2.8 5.7 5.1 5.8 6.7 4.2 6.8 1.9 5.2 0.3 2.9 0.2 1.3 1.8 1.2 4.1

程序:

    #include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

enum {x, y};
typedef struct triangle {
    double v1[2];
    double v2[2];
    double v3[2];
} triangle;
double area(triangle a);
double perimeter(double *vertices, int size);
double side(double *p1, double *p2);


char result[256];
char expected[] = "11.7715.65";     //triangle regular
char expected1[] = "18.1017.02";    //quadrilateral regular
char expected2[] = "21.3317.60";    //pentagon regular
char expected3[] = "23.5518.07";    //hexagon regular
char expected4[] = "24.8018.29";    //heptagon regular
char expected5[] = "25.1418.26";     //octagon regular


int main()
{
    int idx;
    int triangles;
    int index;
    int xycount;
    double xy;
    double triangle_area;
    double polygon_area;
    double perim;
    double polygon_vertices[50] = {0.0};
    triangle a;

    FILE* data;
    char line[256];
    char* token;
    if ((data = fopen("test.txt", "r")) == NULL) {
        fprintf(stderr, "can't open data file\n");
        exit (EXIT_FAILURE);
    }
    while (fgets(line, sizeof (line), data)){
        xycount = 0;
        polygon_area = 0;

        line[strlen(line) - 1] = 0;
        token = strtok(line, " ");
        while (token != NULL){
            xy = atof(token);
            token = strtok(NULL, " ");
            polygon_vertices[xycount++] = xy;
        }
        idx = 0;
        triangles = (xycount / 2) - 2;
        for (index = 2, idx = 0;idx < triangles;index += 2, ++idx){
            a.v1[x] = polygon_vertices[0];
            a.v1[y] = polygon_vertices[1];
            a.v2[x] = polygon_vertices[index + 0];
            a.v2[y] = polygon_vertices[index + 1];
            a.v3[x] = polygon_vertices[index + 2];
            a.v3[y] = polygon_vertices[index + 3];

            triangle_area = area(a);
            polygon_area += triangle_area;

        }

        printf("area=%.2f\t", polygon_area);
        perim = perimeter(polygon_vertices, xycount);
        printf("perimeter=%.2f\n", perim);

        sprintf(result, "%.2f%.2f", polygon_area, perim);

        if(strcmp(result,expected) == 0) {
            printf("Arrays are the same\n");
        }
        else if(strcmp(result,expected1) == 0){
            printf("Arrays are the same");        
        }
        else if(strcmp(result,expected2) == 0){
            printf("Arrays are the same");        
        }
        else if(strcmp(result,expected3) == 0){
            printf("Arrays are the same");        
        }

        else if(strcmp(result,expected4) == 0){
            printf("Arrays are the same");        
        }
        else if(strcmp(result,expected5) == 0){
            printf("Arrays are the same");        
        }
        else {
            printf("Arrays are the different");        
        }

    }
    fclose(data);
    return 0;
}

/* calculate triangle area with Heron's formula */
double area(triangle a)
{
    double s1, s2, s3, S, area;

    s1 = side(a.v1, a.v2);
    s2 = side(a.v2, a.v3);
    s3 = side(a.v3, a.v1);
    S = (s1 + s2 + s3) / 2;
    area = sqrt(S*(S - s1)*(S - s2)*(S - s3));

    return area;
}

/* calculate polygon perimeter */
double perimeter(double *vertices, int size)
{
    int idx, jdx;
    double p1[2], p2[2], pfirst[2], plast[2];
    double perimeter;

    perimeter = 0.0;
    /* 1st vertex of the polygon */
    pfirst[x] = vertices[0];
    pfirst[y] = vertices[1];
    /* last vertex of polygon */
    plast[x] = vertices[size-2];
    plast[y] = vertices[size-1];
    /* calculate perimeter minus last side */
    for(idx = 0; idx <= size-3; idx += 2)
    {
        for(jdx = 0; jdx < 4; ++jdx)
        {
            p1[x] = vertices[idx];
            p1[y] = vertices[idx+1];
            p2[x] = vertices[idx+2];
            p2[y] = vertices[idx+3];
        }
        perimeter += side(p1, p2);
    }
    /* add last side */
    perimeter += side(plast, pfirst);

    return perimeter;
}

/* calculate length of side */
double side(double *p1, double *p2)
{
    double s1, s2, s3;

    s1 = (p1[x] - p2[x]);
    s2 = (p1[y] - p2[y]);
    s3 = (s1 * s1) + (s2 * s2);

    return sqrt(s3);
}

最佳答案

on a diferente machine, I tested in Linux also, and in some cases it appears "Arrays are diferent".

例如考虑第一个 triangle .它的面积是 11.775,在 expected 中你有 11.77 可以比较。现在,在不同的实现中,舍入误差可能导致结果略低于或高于 11.775,而 sprintf(result, "%.2f ... 可以产生 11.7711.78,因此 strcmp 在一种情况下导致“相同”,在另一种情况下导致“不同”。

关于c - 奇怪的问题 : Getting different calculation results of the area and perimeter of a polyngn (on different machines and on different times),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41154443/

相关文章:

C 字节 - 无法输出 char(仅 8 位)

c - 对 *.h 文件中声明的函数的 undefined reference

c++ - 修改 char *const 字符串

c - 将指针存储在指针数组中时遇到问题

c - 如何从Linux中的C获取当前时间(以毫秒为单位)?

c - 如何从 AVX 内在函数中获得用于计算基本统计数据的性能提升?

C++ 和 SDL2 - "Auto-Generate"使用了 DLL?

c - 使用 realloc 动态扩展数组

c - fflush 在命名管道中不起作用

c - 为什么我的结构中的 fread() 不起作用?