Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RusFAQ.ru: Программирование на языке Pascal


Информационный Канал Subscribe.Ru


RusFAQ.ru: Программирование на языке Pascal

Выпуск № 260
от 23.03.2004, 17:00

Администратор:
Имя: Sensey
URL: Информационный ресурс
ICQ: 105679124
Украина, Харьков
О рассылке:
Задано вопросов: 441
Отправлено ответов: 1624
Активность: 368.2 %
[Задать вопрос >>][Регистрация эксперта >>]
[Поиск в базе][Обсудить на форуме]


 Список экспертов, ответы которых опубликованы в данном выпуске

Strory
Статус: Доверительный
Общий рейтинг: 161.66
[Подробней >>]
Vitally
Статус: Доверительный
Общий рейтинг: 141.25
[Подробней >>]
Ayl
Статус: Профессиональный
Общий рейтинг: 116.64
[Подробней >>]
 
sir henry
Статус: Профессиональный
Общий рейтинг: 159.39
[Подробней >>]
Boriss
Статус: Профессиональный
Общий рейтинг: 154.63
URL: Программирование на Паскале
[Подробней >>]
samum2000
Статус: Профессиональный
Общий рейтинг: 132.33
[Подробней >>]


 Краткий перечень вопросов

Вопрос № 437. Я написал процедуру для вывода точки на экран в режиме 640*480*256. procedure VESAPOVPutPix101h(X, Y... (ответов: 6)

Вопросов: 1, ответов: 6


 Вопрос № 437

Я написал процедуру для вывода точки на экран в режиме 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,
Ленёк.



Вопрос отправлен: 20.03.2004, 16:52
Отправитель: Lenyok (lenyok123@yandex.ru)

[Следующий вопрос >>] [Список вопросов]

Отвечает Strory

Добрый день, 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.

(C) 2002-2003 Команда RusFAQ.ru.

 Персональные данные

Ваше имя:

Ваш e-mail:

Опубликовать мой e-mail в рассылке


 Вопрос и дополнение

Ваш вопрос:


Приложение (если необходимо):


Получить ответов:


 Выбор рассылки

Программисту
Assembler (26)
C / C++ (17)
Perl (4)
Builder / Delphi (20)
Pascal (22)
Basic / VBA (8)
Java / JavaScript (7)
PHP (14)
Криптография (7)
WinAPI (15)
Радиоэлектроника (8)
Пользователю
Windows 95/98/Me (43)
Windows NT/2000/XP (56)
"Железо" (33)
Поиск информации (21)
Администратору
Windows NT/2000/XP (27)
Linux / Unix (13)
Юристу
Гражданское право (14)
Семейное право (13)
Трудовое право (13)
КоАП (10)

Отправить вопрос всем экспертам выбранной рассылки.




Задать вопрос | Регистрация эксперта | Поиск в базе | Чат | Форумы | Новости
Проект экспертов RusFAQ.ru | Фотоальбом | Virus.RusFAQ.ru | Администрирование
Профессиональная WEB-Студия B.I.T.


Яндекс цитирования
© 2001-2004 Россия, Москва. Авторское право: Калашников О.А.

http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу


В избранное