Home > front end >  Incorrect result when using %d placeholder in a pow() function in C
Incorrect result when using %d placeholder in a pow() function in C

Time:10-05

I'm trying to finish some basic coding exercise and I have already figured out how to fix it but I would just really like to understand what's going on.

#include <stdio.h>
#include <math.h>
int main(void) {
    int first, second, third, fourth, fifth, sumOne, sumTwo, product;

    printf("Enter integer 1: ");
    scanf("%d", &first);
    printf("Enter integer 2: ");
    scanf("%d", &second);
    printf("Enter integer 3: ");
    scanf("%d", &third);
    printf("Enter integer 4: ");
    scanf("%d", &fourth);
    printf("Enter integer 5: ");
    scanf("%d", &fifth);

    sumOne = first   second;
    sumTwo = third   fourth;

    printf("Result = %d", pow ((sumOne * sumTwo), fifth));

    return 0;

    
}

I have been reading and I found out that pow provides a double result. I found that by changing the placeholder on the last printf() statement to %.0f, I get the desired result. Reason why I used %d is because I didn't want to get decimals in the output. I could also modify the data type and to double instead of int and just limit the decimals again on the final result.

I think my question is why have I been getting incorrect result with the use of %d as placeholder? Thank you.

CodePudding user response:

The function pow is declared like

double pow(double x, double y);

That is its return type is double. So you need to write using the conversion specifier f instead of d

printf("Result = %f", pow ((sumOne * sumTwo), fifth));

I think my question is why have I been getting incorrect result with the use of %d as placeholder?

double numbers usually occupy 8 bytes (objects of the type int usually occupy 4 bytes) and have internal representation that differ from the internal representation of integers.

You could cast the result of the call of pow to the type int and in this case use the conversion specifier d.

printf("Result = %d", ( int )pow ((sumOne * sumTwo), fifth));

Or you could round the result of the call of pow before outputting it as an integer.

CodePudding user response:

A printf conversion specification generally tells printf two things: what type of argument to expect and what to do with it.

For example:

  • %d says expect an int argument and print it as a decimal numeral.
  • %c says expect an int argument, convert it to an unsigned char, and print the character with that code.
  • %f says expect a double argument and print it in decimal notation with six digits after the decimal point.
  • %e says expect a double argument and print it in scientific notation.

The conversion specification needs to tell printf the type of the argument because nothing in the regular C function-call mechanism tells the called function what the argument types are. A function has to be either defined with certain types or it has to be told what the types are through some other mechanism. For printf, that mechanism is the format string.

When you pass the result of pow, you pass a double argument, but %d tells printf to expect an int argument. Since these are different types, represented with different encoding methods, and may be passed in different places in the processor or memory, printf is unable to find and decode the argument you passed. The C standard does not define the behavior when you pass an argument of the wrong type for a printf conversion specification.

CodePudding user response:

I think my question is why have I been getting incorrect result with the use of %d as placeholder? Thank you.

%d expects its corresponding argument to have type int; pow returns a double. These types have different sizes and different representations - the binary representation of 123.0 (double) is completely different from the binary representation of 123 (int):

123   = 00 00 00 7b 
123.0 = 40 5e c0 00 00 00 00 00 

Because of how printf is defined, it doesn't know the actual types of its arguments - it doesn't know that the argument corresponding to the result of pow is a double instead of an int. Instead, it expects the first argument to be an int because you used %d, so it's not interpreting that value correctly.

Crank up your warnings on your compiler.

  • Related