Issue with while loop executing when it shouldn't (c)





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







3















So as part of a computer science course I've been doing a little bit of C. One of the challenges was to create a program that would tell a hypothetical cashier how many coins they would need in order to give change to a customer. I accomplished this with a set of while loops, the entire program looking like this:



#include <stdio.h>
#include <cs50.h>

int main(void)
{
float f;
int i;
i=0;
do
{
f = get_float("Input Change: n");
}
while(f<0);
// This do-while loop uses a get_float operator to get a postive input from the user.
while(f>=0.25)
{
f=f-0.25;
i=i+1;
}
// Each one of these loops represents using one kind of coin. For this one, every time it runs it adds
// one coin to the final tally and removes 25 cents from the change owed.
while(f>=0.10)
{
f=f-0.10;
i=i+1;
}
// Dime loop, subtracts ten from change owed.
while(f>=0.05)
{
f=f-0.0500000;
i=i+1;
}
// Nickel loop, subtracts five from change owed.
while(f>0)
{
f=f-0.01;
i=i+1;
}
// Penny loop, subtracts one from change owed.
printf("You need %i coins.%fn", i, f);
//This just prints the number of coins needed.
}


The issue is that the last while loop we execute randomly even when there is no reason to do so. For example, $0.42 returns a correct value while $0.15 causes the last while loop to add an extra penny for no reason.



while(f>0)
{
f=f-0.01;
i=i+1;
}


(The problematic while loop in question)



I'm new to programming in general, so this is probably just a problem borne of me doing something stupid, but exactly what I'm doing wrong I do not know. Anyone encountered this before?










share|improve this question




















  • 1





    First, does the same input always produce the same output? Second, try printing the value of f in each iteration, I suspect you have floating point rounding errors. Maybe using integers to represent whole cents would make the math easier.

    – Drew Reese
    Nov 17 '18 at 1:01











  • it is a poor programming practice to use non-standard C header files, that are not portable. If your in a class, then that is acceptable, just remember that the header file: `cs50.h is not portable.

    – user3629249
    Nov 17 '18 at 2:11











  • in general, using float for monetary values is very risky as float does not always result in 100 percent correct values.

    – user3629249
    Nov 17 '18 at 2:15











  • OR: For ease of readability and understanding: 1) Please consistently indent the code. Indent after every opening brace '{'. Unindent before every closing brace '}'. Suggest each indent level be 4 spaces. 2) separate code blocks: for if else while do...while switch case default via a single blank line

    – user3629249
    Nov 17 '18 at 2:19




















3















So as part of a computer science course I've been doing a little bit of C. One of the challenges was to create a program that would tell a hypothetical cashier how many coins they would need in order to give change to a customer. I accomplished this with a set of while loops, the entire program looking like this:



#include <stdio.h>
#include <cs50.h>

int main(void)
{
float f;
int i;
i=0;
do
{
f = get_float("Input Change: n");
}
while(f<0);
// This do-while loop uses a get_float operator to get a postive input from the user.
while(f>=0.25)
{
f=f-0.25;
i=i+1;
}
// Each one of these loops represents using one kind of coin. For this one, every time it runs it adds
// one coin to the final tally and removes 25 cents from the change owed.
while(f>=0.10)
{
f=f-0.10;
i=i+1;
}
// Dime loop, subtracts ten from change owed.
while(f>=0.05)
{
f=f-0.0500000;
i=i+1;
}
// Nickel loop, subtracts five from change owed.
while(f>0)
{
f=f-0.01;
i=i+1;
}
// Penny loop, subtracts one from change owed.
printf("You need %i coins.%fn", i, f);
//This just prints the number of coins needed.
}


The issue is that the last while loop we execute randomly even when there is no reason to do so. For example, $0.42 returns a correct value while $0.15 causes the last while loop to add an extra penny for no reason.



while(f>0)
{
f=f-0.01;
i=i+1;
}


(The problematic while loop in question)



I'm new to programming in general, so this is probably just a problem borne of me doing something stupid, but exactly what I'm doing wrong I do not know. Anyone encountered this before?










share|improve this question




















  • 1





    First, does the same input always produce the same output? Second, try printing the value of f in each iteration, I suspect you have floating point rounding errors. Maybe using integers to represent whole cents would make the math easier.

    – Drew Reese
    Nov 17 '18 at 1:01











  • it is a poor programming practice to use non-standard C header files, that are not portable. If your in a class, then that is acceptable, just remember that the header file: `cs50.h is not portable.

    – user3629249
    Nov 17 '18 at 2:11











  • in general, using float for monetary values is very risky as float does not always result in 100 percent correct values.

    – user3629249
    Nov 17 '18 at 2:15











  • OR: For ease of readability and understanding: 1) Please consistently indent the code. Indent after every opening brace '{'. Unindent before every closing brace '}'. Suggest each indent level be 4 spaces. 2) separate code blocks: for if else while do...while switch case default via a single blank line

    – user3629249
    Nov 17 '18 at 2:19
















3












3








3


1






So as part of a computer science course I've been doing a little bit of C. One of the challenges was to create a program that would tell a hypothetical cashier how many coins they would need in order to give change to a customer. I accomplished this with a set of while loops, the entire program looking like this:



#include <stdio.h>
#include <cs50.h>

int main(void)
{
float f;
int i;
i=0;
do
{
f = get_float("Input Change: n");
}
while(f<0);
// This do-while loop uses a get_float operator to get a postive input from the user.
while(f>=0.25)
{
f=f-0.25;
i=i+1;
}
// Each one of these loops represents using one kind of coin. For this one, every time it runs it adds
// one coin to the final tally and removes 25 cents from the change owed.
while(f>=0.10)
{
f=f-0.10;
i=i+1;
}
// Dime loop, subtracts ten from change owed.
while(f>=0.05)
{
f=f-0.0500000;
i=i+1;
}
// Nickel loop, subtracts five from change owed.
while(f>0)
{
f=f-0.01;
i=i+1;
}
// Penny loop, subtracts one from change owed.
printf("You need %i coins.%fn", i, f);
//This just prints the number of coins needed.
}


The issue is that the last while loop we execute randomly even when there is no reason to do so. For example, $0.42 returns a correct value while $0.15 causes the last while loop to add an extra penny for no reason.



while(f>0)
{
f=f-0.01;
i=i+1;
}


(The problematic while loop in question)



I'm new to programming in general, so this is probably just a problem borne of me doing something stupid, but exactly what I'm doing wrong I do not know. Anyone encountered this before?










share|improve this question
















So as part of a computer science course I've been doing a little bit of C. One of the challenges was to create a program that would tell a hypothetical cashier how many coins they would need in order to give change to a customer. I accomplished this with a set of while loops, the entire program looking like this:



#include <stdio.h>
#include <cs50.h>

int main(void)
{
float f;
int i;
i=0;
do
{
f = get_float("Input Change: n");
}
while(f<0);
// This do-while loop uses a get_float operator to get a postive input from the user.
while(f>=0.25)
{
f=f-0.25;
i=i+1;
}
// Each one of these loops represents using one kind of coin. For this one, every time it runs it adds
// one coin to the final tally and removes 25 cents from the change owed.
while(f>=0.10)
{
f=f-0.10;
i=i+1;
}
// Dime loop, subtracts ten from change owed.
while(f>=0.05)
{
f=f-0.0500000;
i=i+1;
}
// Nickel loop, subtracts five from change owed.
while(f>0)
{
f=f-0.01;
i=i+1;
}
// Penny loop, subtracts one from change owed.
printf("You need %i coins.%fn", i, f);
//This just prints the number of coins needed.
}


The issue is that the last while loop we execute randomly even when there is no reason to do so. For example, $0.42 returns a correct value while $0.15 causes the last while loop to add an extra penny for no reason.



while(f>0)
{
f=f-0.01;
i=i+1;
}


(The problematic while loop in question)



I'm new to programming in general, so this is probably just a problem borne of me doing something stupid, but exactly what I'm doing wrong I do not know. Anyone encountered this before?







c while-loop cs50






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 17 '18 at 1:35









Jonathan Leffler

576k956911043




576k956911043










asked Nov 17 '18 at 0:53









Wesley LanceWesley Lance

295




295








  • 1





    First, does the same input always produce the same output? Second, try printing the value of f in each iteration, I suspect you have floating point rounding errors. Maybe using integers to represent whole cents would make the math easier.

    – Drew Reese
    Nov 17 '18 at 1:01











  • it is a poor programming practice to use non-standard C header files, that are not portable. If your in a class, then that is acceptable, just remember that the header file: `cs50.h is not portable.

    – user3629249
    Nov 17 '18 at 2:11











  • in general, using float for monetary values is very risky as float does not always result in 100 percent correct values.

    – user3629249
    Nov 17 '18 at 2:15











  • OR: For ease of readability and understanding: 1) Please consistently indent the code. Indent after every opening brace '{'. Unindent before every closing brace '}'. Suggest each indent level be 4 spaces. 2) separate code blocks: for if else while do...while switch case default via a single blank line

    – user3629249
    Nov 17 '18 at 2:19
















  • 1





    First, does the same input always produce the same output? Second, try printing the value of f in each iteration, I suspect you have floating point rounding errors. Maybe using integers to represent whole cents would make the math easier.

    – Drew Reese
    Nov 17 '18 at 1:01











  • it is a poor programming practice to use non-standard C header files, that are not portable. If your in a class, then that is acceptable, just remember that the header file: `cs50.h is not portable.

    – user3629249
    Nov 17 '18 at 2:11











  • in general, using float for monetary values is very risky as float does not always result in 100 percent correct values.

    – user3629249
    Nov 17 '18 at 2:15











  • OR: For ease of readability and understanding: 1) Please consistently indent the code. Indent after every opening brace '{'. Unindent before every closing brace '}'. Suggest each indent level be 4 spaces. 2) separate code blocks: for if else while do...while switch case default via a single blank line

    – user3629249
    Nov 17 '18 at 2:19










1




1





First, does the same input always produce the same output? Second, try printing the value of f in each iteration, I suspect you have floating point rounding errors. Maybe using integers to represent whole cents would make the math easier.

– Drew Reese
Nov 17 '18 at 1:01





First, does the same input always produce the same output? Second, try printing the value of f in each iteration, I suspect you have floating point rounding errors. Maybe using integers to represent whole cents would make the math easier.

– Drew Reese
Nov 17 '18 at 1:01













it is a poor programming practice to use non-standard C header files, that are not portable. If your in a class, then that is acceptable, just remember that the header file: `cs50.h is not portable.

– user3629249
Nov 17 '18 at 2:11





it is a poor programming practice to use non-standard C header files, that are not portable. If your in a class, then that is acceptable, just remember that the header file: `cs50.h is not portable.

– user3629249
Nov 17 '18 at 2:11













in general, using float for monetary values is very risky as float does not always result in 100 percent correct values.

– user3629249
Nov 17 '18 at 2:15





in general, using float for monetary values is very risky as float does not always result in 100 percent correct values.

– user3629249
Nov 17 '18 at 2:15













OR: For ease of readability and understanding: 1) Please consistently indent the code. Indent after every opening brace '{'. Unindent before every closing brace '}'. Suggest each indent level be 4 spaces. 2) separate code blocks: for if else while do...while switch case default via a single blank line

– user3629249
Nov 17 '18 at 2:19







OR: For ease of readability and understanding: 1) Please consistently indent the code. Indent after every opening brace '{'. Unindent before every closing brace '}'. Suggest each indent level be 4 spaces. 2) separate code blocks: for if else while do...while switch case default via a single blank line

– user3629249
Nov 17 '18 at 2:19














2 Answers
2






active

oldest

votes


















3














It's a precision problem. Equality with floats can be rather problematic. Even though in theory f=0 when you get to the last loop, this fails, and it enters the loop.



A possible workaround is to change it to some number between 0 and 0.01. E.g.



while(f>0.005)


But a better approach would be to use type int to represent money, each unit corresponding to a cent.






share|improve this answer

































    1














    With floating point values it gets "weird" comparing them to other floats, like 5, 0.63, and 0.0 because your value may actually be 0.4999999999 or 0.000000000001, which is essentially zero, and in your case fails the condition test and thus adds a final penny when the value then truly goes negative. When comparing floats you must account for this by comparing the difference to some small epsilon value.



    float epsilon = 0.0000001;
    if ((f - testVal) < epsilon) {
    ...
    }





    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',
      autoActivateHeartbeat: false,
      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%2f53347203%2fissue-with-while-loop-executing-when-it-shouldnt-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









      3














      It's a precision problem. Equality with floats can be rather problematic. Even though in theory f=0 when you get to the last loop, this fails, and it enters the loop.



      A possible workaround is to change it to some number between 0 and 0.01. E.g.



      while(f>0.005)


      But a better approach would be to use type int to represent money, each unit corresponding to a cent.






      share|improve this answer






























        3














        It's a precision problem. Equality with floats can be rather problematic. Even though in theory f=0 when you get to the last loop, this fails, and it enters the loop.



        A possible workaround is to change it to some number between 0 and 0.01. E.g.



        while(f>0.005)


        But a better approach would be to use type int to represent money, each unit corresponding to a cent.






        share|improve this answer




























          3












          3








          3







          It's a precision problem. Equality with floats can be rather problematic. Even though in theory f=0 when you get to the last loop, this fails, and it enters the loop.



          A possible workaround is to change it to some number between 0 and 0.01. E.g.



          while(f>0.005)


          But a better approach would be to use type int to represent money, each unit corresponding to a cent.






          share|improve this answer















          It's a precision problem. Equality with floats can be rather problematic. Even though in theory f=0 when you get to the last loop, this fails, and it enters the loop.



          A possible workaround is to change it to some number between 0 and 0.01. E.g.



          while(f>0.005)


          But a better approach would be to use type int to represent money, each unit corresponding to a cent.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 17 '18 at 2:29

























          answered Nov 17 '18 at 1:16









          Jorge AdrianoJorge Adriano

          2,219919




          2,219919

























              1














              With floating point values it gets "weird" comparing them to other floats, like 5, 0.63, and 0.0 because your value may actually be 0.4999999999 or 0.000000000001, which is essentially zero, and in your case fails the condition test and thus adds a final penny when the value then truly goes negative. When comparing floats you must account for this by comparing the difference to some small epsilon value.



              float epsilon = 0.0000001;
              if ((f - testVal) < epsilon) {
              ...
              }





              share|improve this answer




























                1














                With floating point values it gets "weird" comparing them to other floats, like 5, 0.63, and 0.0 because your value may actually be 0.4999999999 or 0.000000000001, which is essentially zero, and in your case fails the condition test and thus adds a final penny when the value then truly goes negative. When comparing floats you must account for this by comparing the difference to some small epsilon value.



                float epsilon = 0.0000001;
                if ((f - testVal) < epsilon) {
                ...
                }





                share|improve this answer


























                  1












                  1








                  1







                  With floating point values it gets "weird" comparing them to other floats, like 5, 0.63, and 0.0 because your value may actually be 0.4999999999 or 0.000000000001, which is essentially zero, and in your case fails the condition test and thus adds a final penny when the value then truly goes negative. When comparing floats you must account for this by comparing the difference to some small epsilon value.



                  float epsilon = 0.0000001;
                  if ((f - testVal) < epsilon) {
                  ...
                  }





                  share|improve this answer













                  With floating point values it gets "weird" comparing them to other floats, like 5, 0.63, and 0.0 because your value may actually be 0.4999999999 or 0.000000000001, which is essentially zero, and in your case fails the condition test and thus adds a final penny when the value then truly goes negative. When comparing floats you must account for this by comparing the difference to some small epsilon value.



                  float epsilon = 0.0000001;
                  if ((f - testVal) < epsilon) {
                  ...
                  }






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 17 '18 at 1:32









                  Drew ReeseDrew Reese

                  995211




                  995211






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53347203%2fissue-with-while-loop-executing-when-it-shouldnt-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

                      List item for chat from Array inside array React Native

                      Thiostrepton

                      Caerphilly