In VS Code terminal is giving wrong output of my code [duplicate]

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

typedef struct Node
{
    int coef;
    struct Node *ptr;
} node;

void createLinkList(node **head, int degree){
    node *temp, *last, *tempHead;
    tempHead = (node *)malloc(sizeof(node));
    tempHead->ptr = NULL;
    scanf("%d", &(tempHead->coef));
    last = tempHead;
    for (int i = 1; i < degree + 1; i++){
        temp = (node *)malloc(sizeof(node));
        scanf("%d", &(temp->coef));
        temp->ptr = NULL;
        last->ptr = temp;
        last = temp;}
    *head = tempHead;}

int findVal(node *head, int degree, int x){
    int result = 0;
    while (head != NULL){
        result += (head->coef) * pow(x, degree);
        head = head->ptr;
        degree--;}
    return result;}

int main()
{
    node *head;
    int power;
    int x;
    scanf("%d",&power);
    createLinkList(&head,power);
    scanf("%d",&x);
    int k = findVal(head,power,x);
    printf("k = %d",k);
    // int n = 4*pow(5,2);
    // printf("n = %d",n);
}

So here is a simple C language code. The createLinkList() function is for creating a linked list and findVal() is for evaluating a polynomial.

For other values of x, my code is running fine but, whenever I take x=5, the code gives wrong output.

For example if I take: n = 2, coef = 4, 0, 5 and x = 5 (which is equivalent to giving input in one line as follows: 2 4 0 5 5), then obviously the output (value of k) should be 105 (4*(x^2) + 0*(x^1) + 5).

But in my terminal output is showing 104. You can check this code in your IDE. As much as I know, there is no problem in createLinkList() function.

Could anyone please tell why this is happening?


Solution 1:

You are truncating very slightly off results into much more incorrect results. Use some kind of rounding instead of truncation.


While I can't reproduce the problem, the problem is surely pow not returning the result exactly.

pow(x, y) can't simply use a loop that multiplies x by itself y times, at least not always. There are three reasons for this.

  • y doesn't have to be an integer. Consider the case where y is 2.4. How many times would you loop?

  • It's very common to have a decimal numbers that can't be represented accurately by a floating point number. For example, 1/10, 2/10, 3/10, 4/10, 6/10, 7/10, 8/10 and 9/10 are all periodic numbers in binary (like 1/3 is in decimal), so they can't be represented accurately by a floating point number. Each multiplication in that loop would compound any inaccuracy in the representation of x. If you know anything about compound interest, then you know that compounding can magnify small amounts quite fast.

  • It would be very inefficient for large values of y.

So internally, pow is calculating the result by some other method, and this method doesn't produce exactly the right result. It's probably only off by less than 0.00000000000000001 (for real). The issue is that you truncate this number when you convert it to an int. The 5 that's actually 4.99999999999999999 suddenly becomes 4 (for example), and your final result is off by one.

Instead of truncating, use some kind of rounding.