Zorko писал(а):
Тогда так: "переполнение FOR" — это когда из-за шага точное достижение значения B невозможно:
Код: "OBERON"
и в какой-то момент n подойдёт к шагу, который приведёт к выходу за пределы конечных значений типа.
Но целью цикла FOR не является точное достижение
В. Цикл должен выполниться для значений
n=А, А+Step,A+2Step,...,A+kStep, которые не превосходят
В. Последнее значение (если оно вообще есть)
Nlast=A+kStep<=В, т.е. может быть равно
В, но может быть меньше его. А вот следующее после последнего
Nlast+Step должно в идеале быть больше
В, по какому признаку его и следует обнаружить и прекратить итерации. Однако, если
Nlast+Step>MAX(T) , то произойдет переполнение, которое испортит значение
n. В результате "наивное" условие продолжения цикла
WHILE n<=B посчитает, что цикл еще не закончен, что приведет к зацикливанию. Чтобы этого избежать нужно либо заранее определить, что следующий шаг превысит
В и этот шаг не делать, либо не полагаться только на значение
n, а замечать каким-то образом переполнение (проверкой флагов процессора или в какой-то булевской переменной при инкременте). Выше были примеры и того и другого подхода.
Или под словами "точное достижение" ты подразумеваешь что-то другое? Ты хотел условие при котором стандартный обероновский FOR сработает без переполнения? Это произойдет, если за
В существует "буферная зона" - место для маневра, позволяющее сделать еще 1 шаг и не свалиться в пропасть переполнения. Своего рода "ничейная земля": если мы туда попали, то это еще ничего страшного - увидим, что мы за граничным столбом (
В) и примем меры, в чужое государство ("переполнение") мы еще не заехали. Поэтому нужное условие
В+Step<=MAX(T), т.е. сделав шаг, мы не вызовем переполнение (в крайнем случае окажемся на самом краю целого типа
n=MAX(T)). Для
Step<0 аналогично:
В+Step>=MIN(T). Если будем писать эти условия в программе, то лучше их выразить в форме:
Цитата:
В<=MAX(T)-Step, Step>0
В>=MIN(T)-Step, Step<0
потому что
В+Step может вызвать переполнение, а
MAX(T)-Step (MIN(T)-Step) нет.
Это
достаточное условие отсутствия зацикливания, но
не необходимое, потому что от
А зависит как далеко мы выскочим за
В на последнем шаге. Если недалеко, то может и простого
B<MAX(T) хватит. При
B=MAX(T) (или
B=MIN(T) для отрицательного шага) зацикливание неминуемо!