Opeartion on a variable and constant giving different result in c











up vote
0
down vote

favorite












A simple calculation: 3^20%15.

The answer, according to a calculator, is 6.



The following code generates answer 7.



#include <stdio.h>
#include <math.h>
int main() {
int i = 20;
printf("%dn", ((int)pow(3,20)%15));
return 0;
}


If I replace 20 in the printf statement with the variable i, it gives -8 as output.



Assuming that the calculator is corrent (or not?), what is the problem in the program?



Thank you.










share|improve this question
























  • Please shown an Minimal, Complete, and Verifiable example of the failing program. And please read about how to ask good questions, as well as this question checklist.
    – Some programmer dude
    Nov 19 at 15:15






  • 1




    The numerical limits of integers are usually addressed in the first chapters of any C programming book.
    – Lundin
    Nov 19 at 15:31















up vote
0
down vote

favorite












A simple calculation: 3^20%15.

The answer, according to a calculator, is 6.



The following code generates answer 7.



#include <stdio.h>
#include <math.h>
int main() {
int i = 20;
printf("%dn", ((int)pow(3,20)%15));
return 0;
}


If I replace 20 in the printf statement with the variable i, it gives -8 as output.



Assuming that the calculator is corrent (or not?), what is the problem in the program?



Thank you.










share|improve this question
























  • Please shown an Minimal, Complete, and Verifiable example of the failing program. And please read about how to ask good questions, as well as this question checklist.
    – Some programmer dude
    Nov 19 at 15:15






  • 1




    The numerical limits of integers are usually addressed in the first chapters of any C programming book.
    – Lundin
    Nov 19 at 15:31













up vote
0
down vote

favorite









up vote
0
down vote

favorite











A simple calculation: 3^20%15.

The answer, according to a calculator, is 6.



The following code generates answer 7.



#include <stdio.h>
#include <math.h>
int main() {
int i = 20;
printf("%dn", ((int)pow(3,20)%15));
return 0;
}


If I replace 20 in the printf statement with the variable i, it gives -8 as output.



Assuming that the calculator is corrent (or not?), what is the problem in the program?



Thank you.










share|improve this question















A simple calculation: 3^20%15.

The answer, according to a calculator, is 6.



The following code generates answer 7.



#include <stdio.h>
#include <math.h>
int main() {
int i = 20;
printf("%dn", ((int)pow(3,20)%15));
return 0;
}


If I replace 20 in the printf statement with the variable i, it gives -8 as output.



Assuming that the calculator is corrent (or not?), what is the problem in the program?



Thank you.







c output runtime-error pow mod






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 19 at 15:31









DeiDei

6,08053253




6,08053253










asked Nov 19 at 15:10









nachiketa

32




32












  • Please shown an Minimal, Complete, and Verifiable example of the failing program. And please read about how to ask good questions, as well as this question checklist.
    – Some programmer dude
    Nov 19 at 15:15






  • 1




    The numerical limits of integers are usually addressed in the first chapters of any C programming book.
    – Lundin
    Nov 19 at 15:31


















  • Please shown an Minimal, Complete, and Verifiable example of the failing program. And please read about how to ask good questions, as well as this question checklist.
    – Some programmer dude
    Nov 19 at 15:15






  • 1




    The numerical limits of integers are usually addressed in the first chapters of any C programming book.
    – Lundin
    Nov 19 at 15:31
















Please shown an Minimal, Complete, and Verifiable example of the failing program. And please read about how to ask good questions, as well as this question checklist.
– Some programmer dude
Nov 19 at 15:15




Please shown an Minimal, Complete, and Verifiable example of the failing program. And please read about how to ask good questions, as well as this question checklist.
– Some programmer dude
Nov 19 at 15:15




1




1




The numerical limits of integers are usually addressed in the first chapters of any C programming book.
– Lundin
Nov 19 at 15:31




The numerical limits of integers are usually addressed in the first chapters of any C programming book.
– Lundin
Nov 19 at 15:31












2 Answers
2






active

oldest

votes

















up vote
4
down vote



accepted










The result of pow(3,20) can't fit in an int on your platform (or mine for that matter). Because of that, you're experiencing unexpected results.



Changing to a larger integer type such as long long will do the job.



Moreover, pow works with floating-point numbers which aren't represented exactly in memory (look that up). During conversion to an integer, that can cause certain errors. For example, for printf("%fln", (pow(3,20))); I get 3486784401.000000l which is not a precise integer value.






share|improve this answer



















  • 1




    Additionally, note that poor implementations of pow may return inaccurate results for pow(3, 20). They may return 3486784400.999999523162841796875 instead of 3486784401, which would cause the conversion to int to produce 3486784400 (before final conversion to 32-bit).
    – Eric Postpischil
    Nov 19 at 15:17








  • 1




    Answers to this question should also address why there is a difference between pow(3, 20) and pow(3, i), as the question asked.
    – Eric Postpischil
    Nov 19 at 15:19










  • Unfortunately, the new statements in this answer about floating-point are not correct. Each floating-point object that is not a NaN represents one number exactly. The rounding errors in floating-point operations occur during operations, not in numbers. And the error I cautioned about occurs in poor implementations of pow, not in conversion to an integer.
    – Eric Postpischil
    Nov 19 at 15:22










  • @EricPostpischil I don't think there is a difference between pow(3, 20) and pow(3, i). The problem the OP is seeing comes from the fact that int can't hold such a large value. That's about that. Please post an answer that is more technically correct, this is as far as I can go.
    – DeiDei
    Nov 19 at 15:23












  • Likely the compiler evaluated pow(3, 20) at compile time and pow(3, i) at run time. Sometimes the arithmetic used by a compiler at compile time differs from the arithmetic used at run time.
    – Eric Postpischil
    Nov 19 at 15:59


















up vote
1
down vote













What likely happened here is:




  • In your C implementation, int is 32 bits, with a minimum of −2,147,483,648 and a maximum of 2,147,483,647.

  • The result of pow(3, 20) is 3486784401. (See note 1 below.)

  • 3486784401 is too large for an int, so there is an overflow. In case of integer overflow, the C standard permits an implementation to do anything.

  • In (int) pow(3, 20), the conversion to int may have been computed at a compile time by producing the maximum, 2,147,483,647. Then the remainder of that divided by 15 is 7.

  • In (int) pow(3, i), the conversion to int may have been computed at run time by producing the minimum, −2,147,483,648. (Some processors produce such a result for integer overflows.) Then the remainder of that divided by 15 is −8.


In summary:




  • Your code overflows, so the C standard does not define the behavior.

  • The compiler likely behaves differently for pow(3, 20) and pow(3, i) because it evaluates the former at compile time and the latter at execution time.


Note




  1. Good implementations of pow return exactly 3486784401 for pow(3, 20). Unfortunately, poor implementations may return inaccurate values such as 3486784401.000000476837158203125 or 3486784400.999999523162841796875.






share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53377522%2fopeartion-on-a-variable-and-constant-giving-different-result-in-c%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    4
    down vote



    accepted










    The result of pow(3,20) can't fit in an int on your platform (or mine for that matter). Because of that, you're experiencing unexpected results.



    Changing to a larger integer type such as long long will do the job.



    Moreover, pow works with floating-point numbers which aren't represented exactly in memory (look that up). During conversion to an integer, that can cause certain errors. For example, for printf("%fln", (pow(3,20))); I get 3486784401.000000l which is not a precise integer value.






    share|improve this answer



















    • 1




      Additionally, note that poor implementations of pow may return inaccurate results for pow(3, 20). They may return 3486784400.999999523162841796875 instead of 3486784401, which would cause the conversion to int to produce 3486784400 (before final conversion to 32-bit).
      – Eric Postpischil
      Nov 19 at 15:17








    • 1




      Answers to this question should also address why there is a difference between pow(3, 20) and pow(3, i), as the question asked.
      – Eric Postpischil
      Nov 19 at 15:19










    • Unfortunately, the new statements in this answer about floating-point are not correct. Each floating-point object that is not a NaN represents one number exactly. The rounding errors in floating-point operations occur during operations, not in numbers. And the error I cautioned about occurs in poor implementations of pow, not in conversion to an integer.
      – Eric Postpischil
      Nov 19 at 15:22










    • @EricPostpischil I don't think there is a difference between pow(3, 20) and pow(3, i). The problem the OP is seeing comes from the fact that int can't hold such a large value. That's about that. Please post an answer that is more technically correct, this is as far as I can go.
      – DeiDei
      Nov 19 at 15:23












    • Likely the compiler evaluated pow(3, 20) at compile time and pow(3, i) at run time. Sometimes the arithmetic used by a compiler at compile time differs from the arithmetic used at run time.
      – Eric Postpischil
      Nov 19 at 15:59















    up vote
    4
    down vote



    accepted










    The result of pow(3,20) can't fit in an int on your platform (or mine for that matter). Because of that, you're experiencing unexpected results.



    Changing to a larger integer type such as long long will do the job.



    Moreover, pow works with floating-point numbers which aren't represented exactly in memory (look that up). During conversion to an integer, that can cause certain errors. For example, for printf("%fln", (pow(3,20))); I get 3486784401.000000l which is not a precise integer value.






    share|improve this answer



















    • 1




      Additionally, note that poor implementations of pow may return inaccurate results for pow(3, 20). They may return 3486784400.999999523162841796875 instead of 3486784401, which would cause the conversion to int to produce 3486784400 (before final conversion to 32-bit).
      – Eric Postpischil
      Nov 19 at 15:17








    • 1




      Answers to this question should also address why there is a difference between pow(3, 20) and pow(3, i), as the question asked.
      – Eric Postpischil
      Nov 19 at 15:19










    • Unfortunately, the new statements in this answer about floating-point are not correct. Each floating-point object that is not a NaN represents one number exactly. The rounding errors in floating-point operations occur during operations, not in numbers. And the error I cautioned about occurs in poor implementations of pow, not in conversion to an integer.
      – Eric Postpischil
      Nov 19 at 15:22










    • @EricPostpischil I don't think there is a difference between pow(3, 20) and pow(3, i). The problem the OP is seeing comes from the fact that int can't hold such a large value. That's about that. Please post an answer that is more technically correct, this is as far as I can go.
      – DeiDei
      Nov 19 at 15:23












    • Likely the compiler evaluated pow(3, 20) at compile time and pow(3, i) at run time. Sometimes the arithmetic used by a compiler at compile time differs from the arithmetic used at run time.
      – Eric Postpischil
      Nov 19 at 15:59













    up vote
    4
    down vote



    accepted







    up vote
    4
    down vote



    accepted






    The result of pow(3,20) can't fit in an int on your platform (or mine for that matter). Because of that, you're experiencing unexpected results.



    Changing to a larger integer type such as long long will do the job.



    Moreover, pow works with floating-point numbers which aren't represented exactly in memory (look that up). During conversion to an integer, that can cause certain errors. For example, for printf("%fln", (pow(3,20))); I get 3486784401.000000l which is not a precise integer value.






    share|improve this answer














    The result of pow(3,20) can't fit in an int on your platform (or mine for that matter). Because of that, you're experiencing unexpected results.



    Changing to a larger integer type such as long long will do the job.



    Moreover, pow works with floating-point numbers which aren't represented exactly in memory (look that up). During conversion to an integer, that can cause certain errors. For example, for printf("%fln", (pow(3,20))); I get 3486784401.000000l which is not a precise integer value.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 19 at 15:20

























    answered Nov 19 at 15:15









    DeiDei

    6,08053253




    6,08053253








    • 1




      Additionally, note that poor implementations of pow may return inaccurate results for pow(3, 20). They may return 3486784400.999999523162841796875 instead of 3486784401, which would cause the conversion to int to produce 3486784400 (before final conversion to 32-bit).
      – Eric Postpischil
      Nov 19 at 15:17








    • 1




      Answers to this question should also address why there is a difference between pow(3, 20) and pow(3, i), as the question asked.
      – Eric Postpischil
      Nov 19 at 15:19










    • Unfortunately, the new statements in this answer about floating-point are not correct. Each floating-point object that is not a NaN represents one number exactly. The rounding errors in floating-point operations occur during operations, not in numbers. And the error I cautioned about occurs in poor implementations of pow, not in conversion to an integer.
      – Eric Postpischil
      Nov 19 at 15:22










    • @EricPostpischil I don't think there is a difference between pow(3, 20) and pow(3, i). The problem the OP is seeing comes from the fact that int can't hold such a large value. That's about that. Please post an answer that is more technically correct, this is as far as I can go.
      – DeiDei
      Nov 19 at 15:23












    • Likely the compiler evaluated pow(3, 20) at compile time and pow(3, i) at run time. Sometimes the arithmetic used by a compiler at compile time differs from the arithmetic used at run time.
      – Eric Postpischil
      Nov 19 at 15:59














    • 1




      Additionally, note that poor implementations of pow may return inaccurate results for pow(3, 20). They may return 3486784400.999999523162841796875 instead of 3486784401, which would cause the conversion to int to produce 3486784400 (before final conversion to 32-bit).
      – Eric Postpischil
      Nov 19 at 15:17








    • 1




      Answers to this question should also address why there is a difference between pow(3, 20) and pow(3, i), as the question asked.
      – Eric Postpischil
      Nov 19 at 15:19










    • Unfortunately, the new statements in this answer about floating-point are not correct. Each floating-point object that is not a NaN represents one number exactly. The rounding errors in floating-point operations occur during operations, not in numbers. And the error I cautioned about occurs in poor implementations of pow, not in conversion to an integer.
      – Eric Postpischil
      Nov 19 at 15:22










    • @EricPostpischil I don't think there is a difference between pow(3, 20) and pow(3, i). The problem the OP is seeing comes from the fact that int can't hold such a large value. That's about that. Please post an answer that is more technically correct, this is as far as I can go.
      – DeiDei
      Nov 19 at 15:23












    • Likely the compiler evaluated pow(3, 20) at compile time and pow(3, i) at run time. Sometimes the arithmetic used by a compiler at compile time differs from the arithmetic used at run time.
      – Eric Postpischil
      Nov 19 at 15:59








    1




    1




    Additionally, note that poor implementations of pow may return inaccurate results for pow(3, 20). They may return 3486784400.999999523162841796875 instead of 3486784401, which would cause the conversion to int to produce 3486784400 (before final conversion to 32-bit).
    – Eric Postpischil
    Nov 19 at 15:17






    Additionally, note that poor implementations of pow may return inaccurate results for pow(3, 20). They may return 3486784400.999999523162841796875 instead of 3486784401, which would cause the conversion to int to produce 3486784400 (before final conversion to 32-bit).
    – Eric Postpischil
    Nov 19 at 15:17






    1




    1




    Answers to this question should also address why there is a difference between pow(3, 20) and pow(3, i), as the question asked.
    – Eric Postpischil
    Nov 19 at 15:19




    Answers to this question should also address why there is a difference between pow(3, 20) and pow(3, i), as the question asked.
    – Eric Postpischil
    Nov 19 at 15:19












    Unfortunately, the new statements in this answer about floating-point are not correct. Each floating-point object that is not a NaN represents one number exactly. The rounding errors in floating-point operations occur during operations, not in numbers. And the error I cautioned about occurs in poor implementations of pow, not in conversion to an integer.
    – Eric Postpischil
    Nov 19 at 15:22




    Unfortunately, the new statements in this answer about floating-point are not correct. Each floating-point object that is not a NaN represents one number exactly. The rounding errors in floating-point operations occur during operations, not in numbers. And the error I cautioned about occurs in poor implementations of pow, not in conversion to an integer.
    – Eric Postpischil
    Nov 19 at 15:22












    @EricPostpischil I don't think there is a difference between pow(3, 20) and pow(3, i). The problem the OP is seeing comes from the fact that int can't hold such a large value. That's about that. Please post an answer that is more technically correct, this is as far as I can go.
    – DeiDei
    Nov 19 at 15:23






    @EricPostpischil I don't think there is a difference between pow(3, 20) and pow(3, i). The problem the OP is seeing comes from the fact that int can't hold such a large value. That's about that. Please post an answer that is more technically correct, this is as far as I can go.
    – DeiDei
    Nov 19 at 15:23














    Likely the compiler evaluated pow(3, 20) at compile time and pow(3, i) at run time. Sometimes the arithmetic used by a compiler at compile time differs from the arithmetic used at run time.
    – Eric Postpischil
    Nov 19 at 15:59




    Likely the compiler evaluated pow(3, 20) at compile time and pow(3, i) at run time. Sometimes the arithmetic used by a compiler at compile time differs from the arithmetic used at run time.
    – Eric Postpischil
    Nov 19 at 15:59












    up vote
    1
    down vote













    What likely happened here is:




    • In your C implementation, int is 32 bits, with a minimum of −2,147,483,648 and a maximum of 2,147,483,647.

    • The result of pow(3, 20) is 3486784401. (See note 1 below.)

    • 3486784401 is too large for an int, so there is an overflow. In case of integer overflow, the C standard permits an implementation to do anything.

    • In (int) pow(3, 20), the conversion to int may have been computed at a compile time by producing the maximum, 2,147,483,647. Then the remainder of that divided by 15 is 7.

    • In (int) pow(3, i), the conversion to int may have been computed at run time by producing the minimum, −2,147,483,648. (Some processors produce such a result for integer overflows.) Then the remainder of that divided by 15 is −8.


    In summary:




    • Your code overflows, so the C standard does not define the behavior.

    • The compiler likely behaves differently for pow(3, 20) and pow(3, i) because it evaluates the former at compile time and the latter at execution time.


    Note




    1. Good implementations of pow return exactly 3486784401 for pow(3, 20). Unfortunately, poor implementations may return inaccurate values such as 3486784401.000000476837158203125 or 3486784400.999999523162841796875.






    share|improve this answer

























      up vote
      1
      down vote













      What likely happened here is:




      • In your C implementation, int is 32 bits, with a minimum of −2,147,483,648 and a maximum of 2,147,483,647.

      • The result of pow(3, 20) is 3486784401. (See note 1 below.)

      • 3486784401 is too large for an int, so there is an overflow. In case of integer overflow, the C standard permits an implementation to do anything.

      • In (int) pow(3, 20), the conversion to int may have been computed at a compile time by producing the maximum, 2,147,483,647. Then the remainder of that divided by 15 is 7.

      • In (int) pow(3, i), the conversion to int may have been computed at run time by producing the minimum, −2,147,483,648. (Some processors produce such a result for integer overflows.) Then the remainder of that divided by 15 is −8.


      In summary:




      • Your code overflows, so the C standard does not define the behavior.

      • The compiler likely behaves differently for pow(3, 20) and pow(3, i) because it evaluates the former at compile time and the latter at execution time.


      Note




      1. Good implementations of pow return exactly 3486784401 for pow(3, 20). Unfortunately, poor implementations may return inaccurate values such as 3486784401.000000476837158203125 or 3486784400.999999523162841796875.






      share|improve this answer























        up vote
        1
        down vote










        up vote
        1
        down vote









        What likely happened here is:




        • In your C implementation, int is 32 bits, with a minimum of −2,147,483,648 and a maximum of 2,147,483,647.

        • The result of pow(3, 20) is 3486784401. (See note 1 below.)

        • 3486784401 is too large for an int, so there is an overflow. In case of integer overflow, the C standard permits an implementation to do anything.

        • In (int) pow(3, 20), the conversion to int may have been computed at a compile time by producing the maximum, 2,147,483,647. Then the remainder of that divided by 15 is 7.

        • In (int) pow(3, i), the conversion to int may have been computed at run time by producing the minimum, −2,147,483,648. (Some processors produce such a result for integer overflows.) Then the remainder of that divided by 15 is −8.


        In summary:




        • Your code overflows, so the C standard does not define the behavior.

        • The compiler likely behaves differently for pow(3, 20) and pow(3, i) because it evaluates the former at compile time and the latter at execution time.


        Note




        1. Good implementations of pow return exactly 3486784401 for pow(3, 20). Unfortunately, poor implementations may return inaccurate values such as 3486784401.000000476837158203125 or 3486784400.999999523162841796875.






        share|improve this answer












        What likely happened here is:




        • In your C implementation, int is 32 bits, with a minimum of −2,147,483,648 and a maximum of 2,147,483,647.

        • The result of pow(3, 20) is 3486784401. (See note 1 below.)

        • 3486784401 is too large for an int, so there is an overflow. In case of integer overflow, the C standard permits an implementation to do anything.

        • In (int) pow(3, 20), the conversion to int may have been computed at a compile time by producing the maximum, 2,147,483,647. Then the remainder of that divided by 15 is 7.

        • In (int) pow(3, i), the conversion to int may have been computed at run time by producing the minimum, −2,147,483,648. (Some processors produce such a result for integer overflows.) Then the remainder of that divided by 15 is −8.


        In summary:




        • Your code overflows, so the C standard does not define the behavior.

        • The compiler likely behaves differently for pow(3, 20) and pow(3, i) because it evaluates the former at compile time and the latter at execution time.


        Note




        1. Good implementations of pow return exactly 3486784401 for pow(3, 20). Unfortunately, poor implementations may return inaccurate values such as 3486784401.000000476837158203125 or 3486784400.999999523162841796875.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 19 at 15:58









        Eric Postpischil

        69.3k873150




        69.3k873150






























             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53377522%2fopeartion-on-a-variable-and-constant-giving-different-result-in-c%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Wiesbaden

            Marschland

            Dieringhausen