Ошибка в эмуляторе

41 views
Skip to first unread message

Leo B.

unread,
Jul 13, 2022, 2:55:16 AM7/13/22
to БЭСМ-6
В эмуляторе нашлась ошибка, которой уже лет 25, и ни один тест её ни разу не находил, и ни одна программа на эту ошибку не налетала.

Суть в следующем: команды СЛ, ВЧ, ВЧОБ, ВЧАБ (A+X, A-X, X-A, AMX) выполняются как сложение с тем или иным сочетанием изменения знаков операндов.
Как нетрудно видеть, если нужно изменить знак операнда, мантисса которого равна -1 (например, нормализованное число -1 выглядит как 4020 0000 0000 0000), с полем порядка 64 и мантиссой -1), то у результата будет мантисса 0.5, а порядок на единицу больше. 

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

Ошибка возникает, в режиме блокировки нормализации, когда операнд, которому нужно изменить знак, равен -2^40 (6420 0000 0000 0000). В результате получается  6450 0000 0000 0000, что не является числом с порядком целого.

Вот эта программа

                PROGRAM MAIN
                I = 6420000000000000B   { -2^40 }
       2        J = 6420000000000001B   { -2^40 + 1 }

       3        I  = J - I              { должно получиться 1 }
       4        PRINT 1, I, I
            1   FORMAT(1XI16, 1XO16)
                END
печатает
                0 6440000000000000

Что неверно и арифметически, и тем, что у "нуля" неправильный порядок.

Исправлять это будет довольно муторно.

Leo

Michael Yaroslavtsev

unread,
Jul 13, 2022, 3:20:09 AM7/13/22
to be...@googlegroups.com
А это в обоих эмуляторах проявляется?

--
Данное сообщение отправлено Вам, как участнику группы "БЭСМ-6":
http://groups.google.com/group/besm6/topics
---
Вы получили это сообщение, поскольку подписаны на группу "БЭСМ-6".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес besm6+un...@googlegroups.com.
Чтобы посмотреть обсуждение на веб-странице, перейдите по ссылке https://groups.google.com/d/msgid/besm6/d814f2c6-27fe-41ab-899f-e0d1910b90a0n%40googlegroups.com.


--
Thanks,
-- Michael

Leo B.

unread,
Jul 13, 2022, 3:34:42 AM7/13/22
to БЭСМ-6
On Wednesday, July 13, 2022 at 12:20:09 AM UTC-7 BOPOHOK wrote:
А это в обоих эмуляторах проявляется?

Да, потому что в обоих эмуляторах NEGATE может изменить экспоненту.

Евгений Халуев

unread,
Jul 13, 2022, 7:40:26 AM7/13/22
to БЭСМ-6
Лишен ли наш аппаратный MESM6 данного недостатка?
Как себя должен будет повести реальный процессор в указанной ситуации? 

среда, 13 июля 2022 г. в 14:34:42 UTC+7, Leo B.:

Leo B.

unread,
Jul 13, 2022, 5:35:48 PM7/13/22
to БЭСМ-6
В MESM6 всё в порядке; так и выяснили, что это ошибка именно в эмуляторе. 
Должна получиться целая единица, 6400 0000 0000 0001.

Leo

Serge Vakulenko

unread,
Jul 13, 2022, 6:03:36 PM7/13/22
to БЭСМ-6
Я добавил этот случай в тесты для мэсм6. В нашей хардверной реализации всё работает корректно.


--Сергей

Serge Vakulenko

unread,
Jul 14, 2022, 2:29:10 AM7/14/22
to БЭСМ-6
Да, реализация сложения-вычитания посредством процедуры negate() не годится. Надо менять.

Я воспроизвёл эту багу на тестах процессора СВС. Можно починить сначала здесь, так проще. А потом уже перенести в SIMH и dispak.

$ cd svs-cpu
$ make
$ make test
...
[ ✗ ] - 'aax_asx_xsa' failure
unit_tests.c L.1354 : (ElSvsGetPC(cpu)) is not equal to (056u): expected (47), actual (46)

--Сергей

Leo B.

unread,
Jul 14, 2022, 4:43:11 AM7/14/22
to БЭСМ-6
Я почитал в ТО, как в АУ делались разнообразные вычитания - это довольно-таки безумие. 

Боюсь, и с делением могут быть проблемы.  Попробуй поделить на МЭСМ-6, с блокировкой нормализации
1.0/1.0, -1.0/1.0, 1.0/-1.0, -1.0/-1.0
(1.0 = 4050 0000 0000 0000, -1.0 = 4020 0000 0000 0000)
В эмуляторе диспака получается

  4050000000000000 4070000000000000 4070000000000000 4050000000000000

хотя вместо выделенного по идее как минимум в одном из двух случаев должно оставаться 4020 0000 0000 0000.

Leo

Василий Долматов

unread,
Jul 14, 2022, 6:28:29 AM7/14/22
to 'Кирилл Кобелев' via БЭСМ-6


14 июля 2022 г., в 11:43, Leo B. <leo...@gmail.com> написал(а):

Я почитал в ТО, как в АУ делались разнообразные вычитания - это довольно-таки безумие. 

Боюсь, и с делением могут быть проблемы.  Попробуй поделить на МЭСМ-6, с блокировкой нормализации

а как Фортраны это делают? 
просто РЖА 3 = ДЕЛ ?
или как-то иначе… 
вдруг «они что-то знали»? :)

-- 
Данное сообщение отправлено Вам, как участнику группы "БЭСМ-6":
http://groups.google.com/group/besm6/topics
--- 
Вы получили это сообщение, поскольку подписаны на группу "БЭСМ-6".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес besm6+un...@googlegroups.com.
Чтобы посмотреть обсуждение на веб-странице, перейдите по ссылке https://groups.google.com/d/msgid/besm6/ead473f7-9af6-4e50-a162-9852715a3b0an%40googlegroups.com.

Leo B.

unread,
Jul 14, 2022, 11:07:50 AM7/14/22
to БЭСМ-6
Целое деление в фортранах компилируется в деление с нормализацией и последующее преобразование в целое.
А библиотека форматного вывода использует деление (на 10) с выключенной нормализацией, и Форекс тоже (на 3, 6 и 12).
Как это делает библиотека, ни на что не влияет, потому что она тут же берёт abs от числа, и при попытке напечатать 7760 0000 0000 0000 
просто падает с переполнением АУ.

Leo

Leo B.

unread,
Jul 17, 2022, 1:33:37 AM7/17/22
to БЭСМ-6
По ходу правок софтверных эмуляторов нашлись другие ошибки,  связанные с умножением и делением плюс/минус единицы на плюс-минус единицу: и в этих эмуляторах (практически поправлено), и в реализации МЭСМ-6 (надо будет править), и в 4-й части ТО БЭСМ-6, про АУ. 
В ТО читаем, на странице 45 PDF-файла: 

В качестве делителя может использоваться только нормализованное число, т.е. для мантиссы делителя должно выполняться условие:

 1/2 <= d < 1 при d > 0
-1 <= d < -1/2 при d < 0

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

К сожалению, это лажа, поскольку при делении -1 (абсолютное значение мантиссы = 1) на 1 (абсолютное значение мантиссы = 1/2), и образующиеся согласно алгоритму остатки будут постоянно получаться равными 1/2, то есть равными делителю по абсолютной величине (эта возможность, вопреки цитате, также упомянута при делении нацело на стр 49). В БЭСМ-6, возможно, дело спасала схема специального округления, описанная на стр. 49-53.

А на данный момент в МЭСМ-6 деление  минус единицы (4020 0000 0000 0000) на единицу (4050 0000 0000 0000) даёт чуть больше, чем -1, а именно 4020 0000 0000 0001, хотя все стандартные тесты АУ проходят.

Такие дела. 

Leo


Serge Vakulenko

unread,
Jul 17, 2022, 2:16:15 AM7/17/22
to БЭСМ-6
Могла ли на БЭСМ-6 присутствовать схема, обнаруживавшая деление на степень двойки? Это легко сделать, ведь делитель всегда нормализованный, то есть мантисса начинается с единицы, а дальше все нули. Тогда операция сводится просто к коррекции порядка. Наверное мы можем в МЭСМ-6 такое добавить.

--Сергей

Leo B.

unread,
Jul 17, 2022, 2:36:15 AM7/17/22
to БЭСМ-6
On Saturday, July 16, 2022 at 11:16:15 PM UTC-7 Serge Vakulenko wrote:
Могла ли на БЭСМ-6 присутствовать схема, обнаруживавшая деление на степень двойки? Это легко сделать, ведь делитель всегда нормализованный, то есть мантисса начинается с единицы, а дальше все нули. Тогда операция сводится просто к коррекции порядка. Наверное мы можем в МЭСМ-6 такое добавить.

Не было такого, да и смысла в этом не было: для сравнения 39 разрядов мантиссы с нулём была бы нужна "массовая цепь", которая требует более чем одного такта. За это время собственно деление уже уйдёт вперёд и испортит делимое, так что даже по приходу сигнала, что делитель равен степени двойки, будет поздно. 

Деление -1 на 1 нацело, судя по ТО, по-видимому, действительно, требовало дополнительного разряда для отработки "округления", что добавляло 40 тактов на приведение переноса.из этого дополнительного бита :(

Leo

Michael Yaroslavtsev

unread,
Jul 17, 2022, 5:36:37 AM7/17/22
to be...@googlegroups.com
On Sat, Jul 16, 2022 at 11:16 PM Serge Vakulenko <serge.v...@gmail.com> wrote:
Могла ли на БЭСМ-6 присутствовать схема, обнаруживавшая деление на степень двойки? Это легко сделать, ведь делитель всегда нормализованный, то есть мантисса начинается с единицы, а дальше все нули. Тогда операция сводится просто к коррекции порядка. Наверное мы можем в МЭСМ-6 такое добавить.
И тут возникает философский вопрос: мы хотим в точности воспроизводить БЭСМ-6 и её арифметику (warts and all), или "ещё немножко шить"? 

--Сергей

On Saturday, July 16, 2022 at 10:33:37 PM UTC-7 Leo B. wrote:
По ходу правок софтверных эмуляторов нашлись другие ошибки,  связанные с умножением и делением плюс/минус единицы на плюс-минус единицу: и в этих эмуляторах (практически поправлено), и в реализации МЭСМ-6 (надо будет править), и в 4-й части ТО БЭСМ-6, про АУ. 
В ТО читаем, на странице 45 PDF-файла: 

В качестве делителя может использоваться только нормализованное число, т.е. для мантиссы делителя должно выполняться условие:

 1/2 <= d < 1 при d > 0
-1 <= d < -1/2 при d < 0

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

К сожалению, это лажа, поскольку при делении -1 (абсолютное значение мантиссы = 1) на 1 (абсолютное значение мантиссы = 1/2), и образующиеся согласно алгоритму остатки будут постоянно получаться равными 1/2, то есть равными делителю по абсолютной величине (эта возможность, вопреки цитате, также упомянута при делении нацело на стр 49). В БЭСМ-6, возможно, дело спасала схема специального округления, описанная на стр. 49-53.

А на данный момент в МЭСМ-6 деление  минус единицы (4020 0000 0000 0000) на единицу (4050 0000 0000 0000) даёт чуть больше, чем -1, а именно 4020 0000 0000 0001, хотя все стандартные тесты АУ проходят.

Такие дела. 

Leo

--
Данное сообщение отправлено Вам, как участнику группы "БЭСМ-6":
http://groups.google.com/group/besm6/topics
---
Вы получили это сообщение, поскольку подписаны на группу "БЭСМ-6".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес besm6+un...@googlegroups.com.
Чтобы посмотреть обсуждение на веб-странице, перейдите по ссылке https://groups.google.com/d/msgid/besm6/a579a93c-a39e-44c7-9b26-8be172892a3fn%40googlegroups.com.


--
Thanks,
-- Michael

Leo B.

unread,
Jul 17, 2022, 11:39:38 AM7/17/22
to БЭСМ-6
On Sunday, July 17, 2022 at 2:36:37 AM UTC-7 BOPOHOK wrote:
On Sat, Jul 16, 2022 at 11:16 PM Serge Vakulenko <serge.v...@gmail.com> wrote:
Могла ли на БЭСМ-6 присутствовать схема, обнаруживавшая деление на степень двойки? Это легко сделать, ведь делитель всегда нормализованный, то есть мантисса начинается с единицы, а дальше все нули. Тогда операция сводится просто к коррекции порядка. Наверное мы можем в МЭСМ-6 такое добавить.
И тут возникает философский вопрос: мы хотим в точности воспроизводить БЭСМ-6 и её арифметику (warts and all), или "ещё немножко шить"? 

Я всё же надеюсь, что в настоящей БЭСМ-6 всё работало правильно, поэтому в эмуляторах поправить надо.

Хотя, ради прикола, упомяну, что в 36-битном мейнфрейме PDP-10, в котором плавающие числа тоже представлялись в дополнительном коде, мантисса 100000...000 не допускалась, а для минус единицы было сделано исключение: мантисса 11000000..000. считалась нормализованной.  Кстати говоря, в древнем эмуляторе Диспака у меня на сайте,

  001                PROGRAM MAIN
  002                X = 12345.0
  003                Y = 4070000000000000B  { -0.5 * 2^1 - ненормализованная  минус единица }
  004                X = X/Y
  005                PRINT 1,X
  006            1   FORMAT(F10)
  007                END

выполняется и печатает -12345, потому что деление работает с абсолютными величинами, а абсолютная величина 4070000... получается нормализованная.

Leo

Serge Vakulenko

unread,
Jul 17, 2022, 1:52:29 PM7/17/22
to БЭСМ-6
On Sunday, July 17, 2022 at 2:36:37 AM UTC-7 BOPOHOK wrote:
И тут возникает философский вопрос: мы хотим в точности воспроизводить БЭСМ-6 и её арифметику (warts and all), или "ещё немножко шить"? 

Чем лучше я узнаю арифметику БЭСМ-6, тем больше понимаю математиков типа Шуры-Буры и Келдыша, с готовностью проголосовавших за переход на ЕС ЭВМ. :)

К сожалению, на реальной БЭСМ-6 арифметику уже не проверишь. Лучшее приближение, что мы имеем - микро-БЭСМ. Я проверил на ней деление и умножение без нормализации (и без округления).

-1.0 / -1.0 даёт ровно 1.0, то есть 4050 0000 0000 0000, без лишних младших битов. 

-1.0 / 1.0 даёт -1.0, то есть 4020 0000 0000 0000, без лишних младших битов. 

-1.0 * -1.0 даёт -1.0 вместо ожидаемой +1.0. Скорее всего и на родной БЭСМ-6 тоже. То есть целочисленное умножение было бесполезным, так как в случае INT_MIN получалась фигня.

А деление на мэсм6 и симуляторах надо чинить. Умножение работает правильно.

--Сергей 
 

Leo B.

unread,
Jul 18, 2022, 12:49:42 PM7/18/22
to БЭСМ-6
Если умножение -1.0 на -1.0 с нормализацией работает правильно, то в микрокоде микро-БЭСМ просто ошибка (описка?). Нормализация вправо должна выполняться безусловно. 

Leo

Serge Vakulenko

unread,
Jul 18, 2022, 5:19:07 PM7/18/22
to БЭСМ-6
И в микрокоде микро-БЭСМ, и в нашем RTL коде мэсм6 одинаковая описка?
Они ведут себя одинаково. С нормализацией работает правильно (результат +1.0), а без нормализации выдаёт минус единицу. 

Можешь глянуть RTL мэсм6? Я не вижу, как нормализация вправо там должна помочь.

--Сергей

Leo B.

unread,
Jul 18, 2022, 9:45:19 PM7/18/22
to БЭСМ-6
Всё ясно.  Умножение кончается на

                   if (do_norm)
                        state <= STATE_NORM_AFTER;
                    else if (do_round)
                        state <= STATE_ROUND;
                    else

А надо бы просто безусловно на STATE_NORM_AFTER, где нормализация вправо делается безусловно, и только нормализация влево - в зависимости от do_norm.

Возможно, в микро-БЭСМ так же попытались "сэкономить". В БЭСМ-6 вариантов нет - там нормализация общая для всей арифметики, там всё будет правильно.

Другое дело, что умножать нормализованные числа (в частности, отрицательные) с блокировкой нормализации если для чего и полезно, то только для какой-нибудь
альтернативной реализации двойной точности (хотя надо проверить, не использует ли этот трюк имеющаяся фортрановская), 
а ненормализованные отрицательные числа умножать вообще смысла не имеет - результат оказывается в РМР, а он всегда положителен. 

Над делением пока думаю.

Leo

Serge Vakulenko

unread,
Jul 18, 2022, 10:24:03 PM7/18/22
to БЭСМ-6
Отлично! 
Я исправил умножение в мэсм-6: https://github.com/besm6/mesm6/commit/3178e841f2787856615133a5456c0e15c400e610

--Сергей

Reply all
Reply to author
Forward
0 new messages