简体   繁体   中英

Why do I get two different results? (issue with booleans)

I am a Python developer for the most part, but recently I have needed to solve a few problems using C and, honestly, it makes me suffer.

func.c

#define _CRT_SECURE_NO_WARNINGS

#define M_PI 3.1415926535897932384626433832795028841971693993751058209

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <math.h>
#include "Point.h"

bool point_on_line(struct Point p1, struct Point p2, struct Point point) {

    double min_x = min(p1.x, p2.x);
    double max_x = max(p1.x, p2.x);
    double min_y = min(p1.y, p2.y);
    double max_y = max(p1.y, p2.y);

    if (p2.y - p1.y == 0) {
        return point.y == p2.y && point.x >= min_x && point.x <= max_x && point.y >= min_y && point.y <= max_y;
    }

    if (p2.x - p1.x == 0) {
        return point.x == p2.x && point.x <= max_x && point.x >= min_x && point.y >= min_y && point.y <= max_y;
    }

    double k = (p2.y - p1.y) / (p2.x - p1.x);
    double b = (p2.x * p1.y - p1.x * p2.y) / (p2.x - p1.x);

    return point.y == (k * point.x + b) && point.x >= min_x && point.x <= max_x && point.y >= min_y && point.y <= max_y;
}

double calculate_angle(struct Point p1, struct Point p2) {

    double dot_product = p1.x * p2.x + p1.y * p2.y;

    double lenp1 = sqrt(p1.x * p1.x + p1.y * p1.y);

    double lenp2 = sqrt(p2.x * p2.x + p2.y * p2.y);

    double orientation = p1.x * p2.y - p1.y * p2.x;

    int sign;

    if (orientation > 0) {
        sign = 1;
    }
    else {
        sign = -1;
    }

    return sign * acos(dot_product / (lenp1 * lenp2));
}

bool check_border(struct Point p, struct Point points[], int size) {

    for (int i = 0; i < size - 1; i++) {

        if (point_on_line(points[i], points[i + 1], p)) {

            return true;
        }
    }

    return false;
}

bool calc_angle_sum(struct Point p1, struct Point points[], int size) {

    struct Point* vectors = malloc(size * sizeof(struct Point));

    for (int i = 0; i < size; i++) {

        struct Point temp = { points[i].x - p1.x,points[i].y - p1.y };
        vectors[i] = temp;
    }

    double total_sum = 0;

    for (int i = 0; i < size - 1; i++) {
        total_sum += calculate_angle(vectors[i], vectors[i + 1]);
    }

    bool res = (fabs(total_sum - 2 * M_PI)) < 0.00005;

    printf("TOTAL SUM %.100f\n", total_sum);

    printf("DIFFERENCE SMALL %d\n", fabs(total_sum - 2 * M_PI) < 0.00005);

    return fabs(total_sum - 2 * M_PI) < 0.00005;

    //return res;
}

Source.c

#define _CRT_SECURE_NO_WARNINGS
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "Point.h"

int main() {

    int length = 5;

    struct Point p1 = { 1,2 };
    struct Point p2 = { 5,0 };
    struct Point p3 = { 7,4 };
    struct Point p4 = { 5,6 };
    struct Point p5 = { 2,5 };
    struct Point p6 = { 1,2 };

    struct Point points_test[6] = {p1,p2,p3,p4,p5,p6};

    struct Point point_test = {7,3};

    //bool result = calc_angle_sum(point, points, length + 1);

    //printf("%s", result ? "true\n" : "false\n");

    if (check_border(point_test, points_test, length + 1)) {

        printf("BORDER");
        return 0;
    }

    else if (calc_angle_sum(point_test, points_test, length + 1)) {

        printf("INSIDE");
        return 0;
    }

    else {
        printf("OUTSIDE");
        return 0;
    }

}

Point.h


#pragma once

struct Point {
    double x, y;
};

coordinates.txt

1 2 5 0 7 4 5 6 2 5

lap.txt (the first number is the number of rectangle vertices, the second and third - the coordinates of the point.

5 7 3

This algorithm determines whether a point is inside/outside/on an edge of a given polygon using the winding number method.

The point (7,3) (the second and third numbers inside lap.txt ) lies outside the polygon so the correct answer is "OUTSIDE/FALSE". Nevertheless, the output differs depending on Debug/Release and the way I return from calc_angle_sum function.

When I return this way:

return fabs(total_sum - 2 * M_PI) < 0.00005;

I get inconsistent results depending on debug/release mode.

The following way, however, seems to work fine:

bool res = (fabs(total_sum - 2 * M_PI)) < 0.00005
return res

Below is the part inside Source.c that calls the method:

else if (calc_angle_sum(point, points, length + 1)) {

        printf("INSIDE");
        return 0;
    }

There is something I cannot understand about how expressions are evaluated in C.

In Python, I am used to returning like return <some_expression> and expect it to get converted to True/False . In C, however, this doesn't seem to be true, or else there is some other error.

One obvious problem is that of implicit function declarations.

Neither

bool calc_angle_sum(struct Point p1, struct Point points[], int size)

and

bool check_border(struct Point p, struct Point points[], int size)

are not declared in the translation unit source.c . Therefore the compiler assumes that the functions are of type

int calc_angle_sum()
int check_border()

Were the return type of the functions int , they could be called compatibly in this manner - with these arguments. But because the actual return type of the functions is bool , the behaviour of the function calls is undefined .

C99 removed implicit function definitions. A compliant C99, C11, C17 compiler must complain about these function calls in your source.c .But the substandard MSVC compiler barely meets the long obsolete C89 specification...

Thus, try declaring

bool calc_angle_sum(struct Point p1, struct Point points[], int size);
bool check_border(struct Point p, struct Point points[], int size);

in Point.h.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM