Оригинальная идея
Я только что нашел свой старый компьютер 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, вызывают проблемы:
Если я изменяю приращение шага на любое, кроме 0,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,9999999, 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 с шагом 0,2 до 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 increment fails at iteration
- 52 (31.6000001),
- 51-70 нормально,
- тогда 71–87 будет от 0,0000001 до мало (пример: 42,9999999),
- тогда 88–103 еще на единицу меньше (пример: 53.1999998),
- затем число 104 и далее сокращается (например: 62,7999997).
- 0.4 increment fails at iteration
- 18,
- 19–55 нормально,
- 56–64 is at −.9999999,
- 65 нормально,
- 66–84 is at −.9999999,
- 85-100 нормально,
- 101–116 is +.0000001,
- 117 продолжается с 0,000002 и так далее.
- 0.2 increment fails at iteration
- 28 at −.9999999,
- 47–107 нормально,
- 108–140 терпит неудачу при +0,0000001,
- 141 и далее терпит неудачу при +0,0000002 и т. д.
- 0,1 инкремент не работает на итерации
- 28 at −.9999999,
- 79–88 нормально,
- 89–90 терпит неудачу при +0,00000001 (sic),
- 91–116 нормально,
- 117–187 не работает на +0,0000001,
- 188 и выше терпит неудачу при +0,0000002 и так далее.
- 0.05 increment fails at iteration
- 28–33 at −.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
Главный вопрос
Я подозреваю, что проблема в том, как десятичное число преобразуется в двоичное, но мне кажется странным, что он отлично работает с шагом 0,5. Что вызывает эту ошибку, и как ее можно исправить или как ее объяснить? Мой Commodore работает на Basic v2.