Цикл For с десятичным приращением!=.5 дает странные результаты

Оригинальная идея

Я только что нашел свой старый компьютер Commodore 64, подключил его и решил попробовать изучать Basic снова. Я только что закончил главу 3, в которой демонстрируется простой цикл FOR:

10 FOR NB = 1 TO 10 STEP 1
20 PRINT NB,
30 NEXT NB

Это дает, как и ожидалось, следующее:

1       2       3       4
5       6       7       8
9       10

Введение чисел с плавающей точкой

Вышеуказанный результат тот же, если для шага установлено значение 1,0. Другие числа, кроме 0.5, однако вызывают проблемы:

Если я изменяю шаг шага на что-то кроме.5 (или 1), я получаю странные числа с плавающей запятой, которые появляются раньше, чем меньше задано число с плавающей запятой. Для первого теста я изменил NB на 1 TO 40,

Результаты теста

  • FOR NB = 1 TO 40 STEP .6: Нормальные результаты для 1–31, затем 31.6000001. Чтобы увидеть, получу ли я странные результаты дальше, я увеличил NB до 100 и снова увидел странные числа, начинающиеся с 42: 41,2, 41,8, 42,4, 42,999999, 43,5999999 и т. Д.
  • FOR NB = 1 TO 40 STEP .4: Нормальные результаты для 1–7,4, затем 7,8000001, затем нормальные результаты 8,2–22,6, затем 22,9999999, 23,3999999 и т. Д.
  • FOR NB = 1 TO 40 STEP .2: Нормальные результаты для 1–6.2, затем с шагом 6,3999999 дюйма до 8,5999999, затем измененные с 8,7999998 до 9,9999998, затем нормальные результаты с 10,2.
  • FOR NB = 1 TO 40 STEP .1: Нормальные результаты для 1–3,6, затем 3,6999999 и т. Д.
  • FOR NB = 1 TO 40 STEP .05: Нормальные результаты для 1–2,3, затем 2,34999999 (обратите внимание на дополнительную цифру) до 2,59999999, затем 2,65–2,7, затем 2,74999999 и т. Д.

Номер итерации отказа

Шаги не выполняются на следующих итерациях:

  • 0,6 приращение не удается на итерации
    • 52 (31.6000001),
    • 51–70 хорошо,
    • затем 71–87 - это 0,0000001 к малому (например, 42,999999),
    • затем 88–103 еще на один меньше (например, 53.1999998),
    • затем 104 и далее уменьшается (например, 62.7999997).
  • 0,4 приращения терпит неудачу при итерации
    • 18,
    • 19–55 в порядке,
    • 56–64 в -9999999,
    • 65 в порядке,
    • 66–84 - в -9999999,
    • 85–100 в порядке,
    • 101–116 - это +,0000001,
    • 117 продолжается на 0,000002 и так далее.
  • 0,2 приращения терпит неудачу при итерации
    • 28 в -9999999,
    • 47–107 в порядке,
    • 108–140 терпит неудачу при +0,0000001,
    • 141 и далее терпит неудачу в +0.0000002, и так далее
    • 0,1 приращения терпит неудачу на итерации
    • 28 в -9999999,
    • 79–88 в порядке,
    • 89–90 терпит неудачу в +0.00000001 (sic),
    • 91–116 в порядке,
    • 117–187 терпит неудачу при +0,0000001,
    • 188 и далее терпит неудачу в +0.0000002, и так далее.
  • 0,05 приращение не удается на итерации
    • 28–33 при –00000001,
    • 34–35 в порядке,
    • 36–68 терпит неудачу в -0,00000001,
    • 69–78 в порядке,
    • 79–92 терпит неудачу в +0,00000001,
    • 93–106 терпит неудачу в +0,00000002,
    • 107 и далее терпит неудачу в +0.00000003 и так далее.

Примечания к вышесказанному

Для записи я добавил счетчик для облегчения отчетности; поэтому программа выглядит так:

05 NC = 1
10 FOR NB = 1 TO 100 STEP 0.05: REM 0.6, 0.4, 0.2, 0.1, 0.05
20 PRINT NC;":";NB,
25 NC = NC + 1
30 NEXT NB

Главный вопрос

Я подозреваю, что проблема заключается в том, как десятичная дробь переводится в двоичную, но я нахожу странным, что она отлично работает с.5 шагами. Что является причиной этой ошибки, и как ее можно исправить, или как ее следует учитывать? Мой коммодор работает с Basic v2.

1 ответ

Решение

Я предполагаю, что, так как кратные числа.5 могут быть легко переведены в базу 2, поэтому это не создает никаких проблем. Могу поспорить, что если вы попытаетесь с шагом 0,25, он также будет работать нормально.

Другие вопросы по тегам