Цикл 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, он также будет работать нормально.