Форум: "Основная";
Текущий архив: 2004.06.20;
Скачать: [xml.tar.bz2];
Внизошибка 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;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.035 c