Zorko писал(а):
Я полагаю, что актуальность данного вопроса в контексте 32-битных платформ незначительна, и вот аргументация. Если в качестве счётчика цикла использовать 32-битные и больше целые, то вероятность достижения TO MAX(INTEGER), а уж тем более TO MAX(LONGINT) невероятно мала, стоит очень напрячь мозг, чтобы получить задачу, где такое значение действительно потребуется.
Не забывайте, что проблема имеет место, когда B=MAX(LONGINT) или MAX(INTEGER), граница
А в этом случае может быть любой (потому что всегда А<=B=MAX(LONGINT) ), т.е. сама подобласть может состоять всего из нескольких чисел (например MAX(INTEGER)-10 TO MAX(INTEGER)), но сами числа очень большие - максимальные. Конечно, это вряд ли индексы массива. Но почему не параметры в каком-то целочисленном вычислении: датчик СЧ, криптография, поиск целых с заданными свойствами... Например, 2^32-1 - это двоичный
репьюнит,он особыми свойствами обладает, может быть потребуется сделать какие-то вычисления вблизи этого числа?
Вот получила ракета закодированную команду, взяла очередной случайный ключ (а он как назло сегодня MAX(LONGINT)!), выполнила в алгоритме расшифровки FOR вблизи этого числа и ... Жалко, миллиарды долларов стоила. Ну не протестировали, потому что по матпостановке ключ К в алгоритме для любого числа LONGINT справедлив. Поэтому особо не проверяли, понадеялись что достаточно VAR K:LONGINT;
Цитата:
Однако ситуация крайне меняется если нужно программировать 8- и 16-битные процессоры. Здесь уже без маленьких типов данных обойтись не получится (из соображений эффективности), и соответственно нужно с ними как-то работать.
Да, для Z80 и прочих "малышей" это особенно актуально. Хотя, повторю, свалится в эту "каверну" на любой системе можно.
Цитата:
Так что, как видим, проблемы нет.
Да есть проблема-то, и как я понял,
агромадная! Она даже фундаментальней чем цикл FOR, это проблема методическая.
Цитата:
Достаточно просто знать, что цикл FOR реализован без учёта конечного значения переменной, и использовать это.
А многие обероновцы знают? А многие из мэтров (хотя бы с oberoncore) осознают такие особенности своих программ, принципиально не употребляя FOR, но воспроизводя через WHILE эквивалентную "стандартную" конструкцию (и,конечно, с таким же дефектом)? И многие пишут в документации к модулям кроме VAR N:INTEGER еще и N<MAX(INTEGER) или ставят это условие в ASSERT? Это и есть методическая проблема.
Цитата:
Вернее, редко с этим сталкиваться, и если очень уж повезёт.
Читайте выше про ракету, ей сегодня "повезло". А могло бы "повезти" через год. Это хорошо, когда такая бомба замедленного действия есть? Ведь Оберон позиционируется как очень надежный язык, с доказательствами правильности, с выводом свойств, с пред- и постусловиями. А когда легче все это выводить: когда утверждения справедливы для всего множества значений или когда в области значений есть "лакуна", где особые (и "некрасивые") свойства? Если в программе написано VAR N:INTEGER;, то уж вряд ли в N будет что-то другое, за этим компилятор внимательно следит. И если какое-то свойство справедливо для всех INTEGER, то и проверять ничего особо не нужно, всё будет само собой. А вот если дополнительно нужно N<MAX(INTEGER), то нужны спецповерки, ASSERT или еще что-то. А если таких параметров несколько, как проявится их сочетание? Пред\пост-условия превращаются в многоэтажную конструкцию из дизъюнктов и конъюнктов, из которой ничего полезного уже не вывести. Ну не работает интуиция на таких запутанных вещах, ей что-то "красивое", регулярное, "разумное" нужно!
Да и с какой стати мы должны отбрасывать значение MAX? Ну ради чего? Ради старой ошибки стандарта? Давайте лучше ошибку отбросим!
Цитата:
Подсчитанный нами десятитысячелетний срок означает, что за время своего существования умножитель должен будет выполнить только ничтожную часть огромного числа всех возможных перемножений, на которые он способен: практически ничего он сделать не успеет. Как ни странно, мы все же требуем, чтобы он был способен правильно выполнить любое перемножение, если поступит соответствующий приказ. Это фантастическое качество требуется потому, что мы не знаем заранее, какие именно ничтожно малые по своему количеству умножения потребуется выполнить.(Э.Дейкстра.Структурное программирование)
А вот еще вспомнилась
Ошибка Pentium FDIV. Intel тоже пыталась за фичу выдать, "потому что чисел много и вероятность получит ошибку крайне мала, менее вероятности быть убитым метеоритом (хотя если вы знаете куда упадет метеорит, вы можете встать на это место)"(точную цитату не помню и сразу в Инете не нашел, но смысл такой). И что? Скандал поднялся и "фичу" исправили, потому что это явный баг. Процессор должен без ошибок любые числа делить, а FOR в любых границах итерации выполнять!
Цитата:
Ну и что я должен был ответить? Отказаться реализовывать?
Гм, так там ещё покумекать надо. ...
И, кстати, не могу не пойти навстречу юзеру ZXDev, ибо нас так мало.
Должен был согласиться.
И я рад, что согласился.
Про "жаль..." - это шутка была.
Хотя...действительно хотелось вызвать на дискуссию. Ну как-то неинтересно всё монологи разводить, какой-то обратной связи хочется.
Цитата:
Вот мне не нравится заём и переполнение счётчика цикла. В ассемблере и Си ещё куда ни шло, но Оберону приличествует обрабатывать такие ситуации (хотя бы в отладочном режиме, если не всё время).
Переполнение в цикле происходит от неверной организации цикла - после обработки последнего элемента не нужно брать следующий (выполнять инкремент). А само переполнение...Мы работаем на 8-разрядном процессоре, переполнения не избежать. Управлять...ну вроде в самом Обероне управления нету, выходит за рамки языка. Разве что спецSYSTEMпроцедуры написать, чтоб ассемлерные макросы вставлять.
Погоди-ка, что ты сказал?! "Си"?! Ну конечно же, СИ! Вот откуда всё это тянется-то...
Ведь стандартный обероновский FOR это эквивалент сишного for(x=A;x<=B;x++); Перешли на структурный ЯП, и дефектный шаблон из Си протащили.
Так-так, говорил же, методическая проблема, в головах, в мышлении, в инерции - вот где главное зло.
Цитата:
Но поправочка. "Хотите вкусного FOR'а — юзайте волшебную опцию и наслаждайтесь. Но если хотите, чтобы это ещё и не зависало на других Оберонах — тогда уж помилуйте. И не говорите, что мы вас не предупреждали."
Поправочка к поправочке "...Но если хотите, чтобы это ещё и
зависало на других Оберонах" Ведь стандарт-это зависание в некоторых случаях, волшебная опция зависание убирает. А где не зависало, там без разницы - полностью так же работает.
Цитата:
Увы, со стандартами приходится считаться, хотя они и не всегда хороши.
Ну зачем считаться с плохими стандартами, чтоб всем стандартно плохо было?
Цитата:
Тут, опять же, FOR — просто массу проблем порождает. Например, можешь сходу ответить: FOR i := 1 TO Fn() DO — выполнит Fn() один раз? Или столько, сколько раз исполнится цикл? Хорошо, что мы это знаем, но если не знать семантики языка, то из самой записи это не следует.
Если не знать семантики, то из
любой записи ничего не следует, потому что семантика - это и есть смысл. Я не против задания семантики фрагментом кода на Оберон. Я говорю, что в этом фрагменте для FOR ошибка, он должен быть другой, правильный. Чтобы все значения границ обрабатывал и не зацикливался. А какой именно, надеюсь скоро написать.