Я написал процедуру для вывода точки на экран в режиме 640*480*256. procedure VESAPOVPutPix101h(X, Y : Word; Color : Byte); var GrWin : Word; Offset : Word; begin GrWin := (Y*640+X) div $FFFF; - Окно видеопамяти VESAMoveOknoVP(GrWin); - Перемещение окна видеопамяти Offset := (Y*640+X) mod $FFFF; Mem[$A000:Offset] := Color; end; Если координаты небольшие , то рисует точку без проблем, а если координаты например 630 на 470 , то паскаль пишет: 'Error 215:Runtime error'-переполнение при арифметической операции. Попробовал заменить Y и X на числа: Offset := (470*640+630) mod $FFFF; и GrWin := (470*640+630) div $FFFF; Всё работает. Не понимаю почему не работает, когда используешь переменные, ведь переменные равны этим числам. Потом сделал X и Y типа LongInt, вместо Word. - Процедура стала работать нормально. Уважаемые
эксперты! Объясните, пожалуйста, почему так происходит. Have a nice day (or night)! Bye, Ленёк.
Добрый день, Lenyok! Всё абсолютно правильно. Ведь диапозон типа Word 0..65535, а результаты у Вас получаются больше этого диапозона, поэтому и выдаётся ошибка. Просчитывайте на калькуляторе максимальные данные и используйте подходящий тип - ошибок не будет. Ответ отправлен: 21.03.2004, 05:10 Отправитель: Strory Отвечает Vitally
Здравствуйте, Lenyok! У меня однажды была такая же фигня. Никто мне не помог. Пришлось разбираться самому. 100% уверенности нет, но выглядит это примерно так: когда ты перемножаешь числа, BP должен где-то хранить промежуточный резултат. Видимо он не сразу кладет его в конечную переменную. А сохраняя его где-то, ориентируется не на тип конечной переменной, а на тип переменных участвующих в операции умножения. Избежать этого можно отключив опцию проверки переполнения. {$R-} Ответ отправлен: 21.03.2004, 14:45 Отправитель: Vitally Отвечает Ayl
Приветствую Вас, Lenyok! А если попробовать посчитать и сравнить диапазоны значений? Допустим, у тебя X = 630, Y - 470 Считаем (по шагам, как комп): GrWin := (Y * 640 + X) div $FFFF 1. Y * 640 = 470 * 640 = 300800
Диапазон значений переменной типа Word - 0..65535, 300800 > 65535 - вот в этом и проблема.
Просто Паскаль при вычисления в качестве размера промежуточного результата берет наибольший из размеров операндов. Например, вот так должно отработать: GrWin := (LongInt (Y) * 640 + X) div $FFFF;
Ответ отправлен: 21.03.2004, 13:51 Отправитель: Ayl Отвечает sir henry
Приветствую Вас, Lenyok! А Вы попробуйте типы GrWin и Offset поменять на LONGINT или, если Вы программируете в 32-разрядной системе, на DWORD. Ответ отправлен: 22.03.2004, 08:01 Отправитель: sir henry Отвечает Boriss
Здравствуйте, Lenyok! Дело в следующем: когда происходит деление на СЛОВО (WORD), то делимое - это двойное слово (смотрите в описание команды ассемблера DIV). Когда Вы используете константы, то это старшее слово заполняется нулями и деление происходит правильно. Когда это переменные типа WORD, то и результат будет приведен к типу WORD, а старшая часть числа окажется незаполненной - вот и источник ошибок, которой нет, если переменные типа Longint Ответ отправлен: 22.03.2004, 12:41 Отправитель: Boriss Отвечает samum2000
Приветствую вас,Lenyok! Я не уверен, но кажется происходит следующее. Программа вычисляет значение Y*640, и, раз уж Y типа Word, то и результат этого действия она пытается затолкнуть в 2 байта. А результат-то большой, туда не помещается, в итоге ошибка. Когда ты Y делаешь типа LongInt переполнения не происходит. -------------------------- -=Experts helper: testmode=- Ответ отправлен: 23.03.2004, 10:11 Отправитель: samum2000
Форма отправки вопроса
Внимание!
Мы рекомендуем открывать рассылку в программе Internet Explorer 5.0+
или отправлять вопросы с сайта по адресу:
http://rusfaq.ru/cgi-bin/Message.cgi.