Почему мой последний раздел не выполняется? - PullRequest
1 голос
/ 16 апреля 2020

Это код для задачи 1, около sh, из CS50:

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

  int main(void) {
      double d;
      int coins = 0;

      do {
          d = get_float("Change owed: ");
      } while(d < 0);

      for (int i = 0; i <= 5; i++) {
          if (d == 0) break;
          if (d >= 0.25) {
              coins += d / 0.25;
              d = fmod(d, 0.25);
              printf("\nd0: %f\n", d);
              printf("coins0: %d\n\n", coins);
          }
          else if (d >= 0.10) {
              coins += d / 0.1;
              d = fmod(d, 0.1);
              printf("\nd1: %f\n", d);
              printf("coins1: %d\n\n", coins);
          }
          else if (d >= 0.05) {
              coins += d / 0.05;
              d = fmod(d, 0.05);
              printf("\nd2: %f\n", d);
              printf("coins2: %d\n\n", coins);
          }
          else if (d >= 0.01) {
              coins += d / 0.01;
              d = fmod(d, 0.01);
              printf("\nd3: %f\n", d);
              printf("coins3: %d\n\n", coins);
          }
      }

      printf("coins: %d\\n\n", coins);
  }

Когда я пытаюсь получить общее количество монет, которое требует хотя бы копейки, деление не происходят, чтобы числа монет не увеличивались. Итак, почему?

Ответы [ 2 ]

1 голос
/ 16 апреля 2020

Почему мое последнее деление не выполняется?

Когда OP обнаружил , d было меньше 0,01, поэтому d >= 0.01 неверно.

Это связано с тем, что значения с плавающей запятой, такие как 0,05, являются дьяди c рациональными , не кратными степеням 10 и не точно 0,05.


Вместо этого избегайте накопленных ошибок округления с деньгами. Попробуйте использовать целое число наименьших денежных единиц, например 0,01, типа long или long long.

. Считать значение с плавающей запятой, масштабировать до центов и округлить.

  // double d;
  long d_cents;
  ...
  do {
      //d = get_float("Change owed: ");
      d_cents= lround(100.0 * get_float("Change owed: "));
  } while(d_cents < 0);

Масштаб по математике соответственно.

      //else if (d >= 0.05) {
      //    coins += d / 0.05;
      //    d = fmod(d, 0.05);
      //    printf("\nd2: %f\n", d);
      //    printf("coins2: %d\n\n", coins);
      //}
      else if (d_cents >= 5) {
          coins += d_cents / 5;
          d_cents %= 5;
          printf("\nd2: %0.2f\n", d_cents/100.0);
          printf("coins2: %d\n\n", coins);
      }
1 голос
/ 16 апреля 2020

Плавающие точки всегда могут вызвать проблемы такого рода, решение здесь состоит в том, чтобы дать вашим плавающим числам диапазон. Например, не ищите, если x> 0,01, а ищите x> (0,01-0,000001)

Хотя при использовании чисел с плавающей запятой всегда используйте диапазоны, никогда не ищите конкретное c число.

...