Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.06.20;
Скачать: CL | DM;

Вниз

ошибка Integer overflow   Найти похожие ветки 

 
ancara   (2004-06-08 10:13) [0]

Добрый день, уважемые мастера! У меня глупый вопрос, но тем не менее я не знаю на него ответа:
есть такие переменные:

 X: DWORD;
A,B: DWORD;

и такой код:

X:= Abs(A-B)*2;

включил Overflow checking - начал показывать ошибку, причем в том случае, если B>A, т.е. в скобках отрицательное число. X делать integer"ом нежелательно, там потом кусок на асме, он там используется как целое положительное. В чем причина, я специально ABS поставил и не помогает. Да, еще я попробовал вместо переменных написать значения, типа:

X:=(5-10)*2;

и все нормально! Почему так?


 
Digitman ©   (2004-06-08 10:35) [1]

при включенной опции проверки переполнения :

1. в случае

X:= Abs(A-B)*2;

компилятор считает, что при A,B:DWORD вычисленное значение A-B так же должно иметь явный тип DWORD, в диапазон представления значений которого отиц.значения не входят, о чем в ран-тайм и сообщается исключением по integer overflow

2. в случае

X:= Abs(5-10)*2;

компилятор вообще генерирует код вызова ф-ции Abs() и операции ц/ч умножения, потому что все выражение можно вычислить на этапе компиляции, получить заведомо однозначный результат = 10 и присвоить его переменной X, что не возбудит никаких исключений, благо результ.число 10 заведомо входит в диапазон представления типа DWORD, поэтому код проверки на переполнение компилятор даже не генерирует


 
Digitman ©   (2004-06-08 10:37) [2]


> вообще генерирует


читать как "вообще НЕ генерирует"


 
Digitman ©   (2004-06-08 10:42) [3]


> X делать integer"ом нежелательно, там потом кусок на асме,
> он там используется как целое положительное


никаких ограничений нет : используй в асм-блоке переменную Х как хочешь - хоть как знаковое хоть как беззнаковое ...

в дан.случае абсолютно индифферентно, какой тип - integer или dword - имеет переменная Х, используемая в asm-блоке, важно что размер переменной в памяти и в том и в другом случае будет одинаков


 
ancara   (2004-06-08 10:46) [4]

Хм... Сделал все таки ради эксперимента

X: integer

история та же, а вот после такого изменения:


 A: WORD;
 B: DWORD;


ошибка исчезла... Вообщем проблема решена, но как - я не понял...


 
Anatoly Podgoretsky ©   (2004-06-08 10:47) [5]

Abs бессмысленен для dword


 
pasha_golub ©   (2004-06-08 10:48) [6]

ancara   (08.06.04 10:46) [4]
Проблема не решена, ИМХО, а завуалирована. Перечитайте посты Digitman © очень внимательно, иначе рискуете отгребсти по самые мама не горюй.

С уважением.


 
Digitman ©   (2004-06-08 10:52) [7]


> ошибка исчезла


и это тоже объяснимо


> Вообщем проблема решена, но как - я не понял


странно ты подходишь к решению проблемы - методом "научного тыка" ..

работаешь явно выражениями, принимающими в ран-тайм в т.ч. и отриц.значения (а иначе на кой шут тогда Abs, спрашивается ?), а переменные объявляешь как беззнаковые целые ..

да и с опцией overflow checking - тоже ситуация сомнительная, ибо в асм-блоке, где ты волен творить с любой переменной любого типа все что угодно, компилятор бессилен отслеживать твои логические ошибки


 
ancara   (2004-06-08 10:57) [8]

Еще ситуация:

 X: byte;
 A: WORD;
 B: DWORD;

X:=Abs(A-B)*2;

ошибок нет! а если без Abs() то Range check error.
 (в момент отладки A=7; B=8;)


 
ancara   (2004-06-08 10:58) [9]

Еще ситуация:

 X: byte;
 A: WORD;
 B: DWORD;

X:=Abs(A-B)*2;

ошибок нет! а если без Abs() то Range check error.
 (в момент отладки A=7; B=8;)
Дело в разрядности переменных чтоли? (16 bit, 32 bit)?


 
ancara   (2004-06-08 11:09) [10]


> Digitman ©   (08.06.04 10:52) [7]

 Я поясню: overflow checking я включаю время от времени (иногда всегда включен) чтобы компилятор указал на разные "слабые места", привычка у меня такая, я не только для асма ее включил.
 А насчет беззнаковых - прога ориентирована на графику,
  A - это ширина картинки в байтах расчетная(кол-во точек умножить на кол-во бай на точку),
  B - это ширина в байтах истинная, с выравниванием (bmp-файлы  должны же быть "word aligned");
  X - это величина "добавки", т.е. сколько байт нужно добавить в конец каждой строки, чтобы выравнять по словам, она не может быть меньше нуля теоретически,( но в проге почему-то может и я буду это устранять...)
 именно поэтому я выбрал изначально DWORD.


 
Digitman ©   (2004-06-08 11:15) [11]


> ancara



> Дело в разрядности переменных чтоли? (16 bit, 32 bit)?


ну разумеется !

в случае A-B компилятор считает результирующим типом значения выражения тип dword, иначе - integer

ты вроде бы с асм-ом знаком, коль блоки на нем используешь ...
не так уж и трудно посмотреть в режиме отладки, какой маш.код компилятор генерирует в том или ином случае ..


 
ancara   (2004-06-08 11:43) [12]


> не так уж и трудно посмотреть в режиме отладки, какой маш.код
> компилятор генерирует

 Вы совершенно правы :), в регистре EAX вместо 00000001 получается FFFFFFFE, а потом это рассмартивается как BYTE - маразм!
 Спасибо за ценные советы.


 
Digitman ©   (2004-06-08 11:53) [13]


> ancara   (08.06.04 11:09) [10]


X := (Max(A,B) - Min(A,B)) * 2

и всех делов) .. и никаких переполнений) ..
разница между макс. и мин. значениями всегда будет >= 0


 
evvcom ©   (2004-06-08 14:42) [14]


>   A - это ширина картинки в байтах расчетная(кол-во точек
> умножить на кол-во бай на точку),
>   B - это ширина в байтах истинная, с выравниванием (bmp-файлы
>  должны же быть "word aligned");
>   X - это величина "добавки", т.е. сколько байт нужно добавить
> в конец каждой строки, чтобы выравнять по словам, она не
> может быть меньше нуля теоретически

Из этого следует, что A, B и X можно описать как Integer и использовать X:= Abs(A-B)*2; как в вопросе. Ну а если принципиально они должны быть DWORD, то можно использовать явное приведение типов X:= Abs(Integer(A)-B)*2;
Посмотрев на код, сгенерированный компилятором, будет видно, что, возможно, потребуется еще где-нибудь применить явное приведение типов.



Страницы: 1 вся ветка

Текущий архив: 2004.06.20;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.035 c
3-1085416122
pok
2004-05-24 20:28
2004.06.20
Как узнать имя поля...


14-1086328393
Iraizor
2004-06-04 09:53
2004.06.20
Что за компонент ?


3-1085502140
Kein
2004-05-25 20:22
2004.06.20
переход с IBX на FIBPlus


3-1085631099
Litr
2004-05-27 08:11
2004.06.20
Поиск


14-1086215474
Jprs154
2004-06-03 02:31
2004.06.20
жаргон школьников