Переполнение (ошибка 6)
Попытка выполнить назначение, превышающее ограничения цели назначения, приводит к переполнению. Эта ошибка имеет следующие причины и решения:
- Результат назначения, вычисления или преобразования типа данных слишком велик для представления в диапазоне значений, разрешенных для этого типа переменной. Назначьте значение переменной типа, который может содержать больший диапазон значений.
- Назначение свойству превышает максимальное значение, которое может принять свойство. Убедитесь, что выполненное назначение соответствуют диапазону, определенному для соответствующего свойства.
- Предпринята попытка использовать число в вычислении, это число приведено к типу integer, но результат превышает ограничения для типа integer. Например:
Dim x As Long x = 2000 * 365 ' Error: Overflow
Чтобы обойти эту ситуацию, укажите число следующего вида:
Dim x As Long x = CLng(2000) * 365
Для получения дополнительной информации выберите необходимый элемент и нажмите клавишу F1 (для Windows) или HELP (для Macintosh).
Поддержка и обратная связь
Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.
Обратная связь
Были ли сведения на этой странице полезными?
Integer overflow ошибка как исправить
← →
ancara ( 2004-06-08 10:13 ) [0]
Добрый день, уважемые мастера! У меня глупый вопрос, но тем не менее я не знаю на него ответа:
есть такие переменные:
X: DWORD;
A,B: DWORD;
и такой код:
включил Overflow checking — начал показывать ошибку, причем в том случае, если B>A, т.е. в скобках отрицательное число. X делать integer»ом нежелательно, там потом кусок на асме, он там используется как целое положительное. В чем причина, я специально ABS поставил и не помогает. Да, еще я попробовал вместо переменных написать значения, типа:
и все нормально! Почему так?
← →
Digitman © ( 2004-06-08 10:35 ) [1]
при включенной опции проверки переполнения :
компилятор считает, что при A,B:DWORD вычисленное значение A-B так же должно иметь явный тип DWORD, в диапазон представления значений которого отиц.значения не входят, о чем в ран-тайм и сообщается исключением по integer overflow
компилятор вообще генерирует код вызова ф-ции 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]
Хм. Сделал все таки ради эксперимента
история та же, а вот после такого изменения:
ошибка исчезла. Вообщем проблема решена, но как — я не понял.
← →
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 © очень внимательно, иначе рискуете отгребсти по самые мама не горюй.
и это тоже объяснимо
> Вообщем проблема решена, но как — я не понял
странно ты подходишь к решению проблемы — методом «научного тыка» ..
работаешь явно выражениями, принимающими в ран-тайм в т.ч. и отриц.значения (а иначе на кой шут тогда Abs, спрашивается ?), а переменные объявляешь как беззнаковые целые ..
да и с опцией overflow checking — тоже ситуация сомнительная, ибо в асм-блоке, где ты волен творить с любой переменной любого типа все что угодно, компилятор бессилен отслеживать твои логические ошибки
← →
ancara ( 2004-06-08 10:57 ) [8]
Еще ситуация:
X: byte;
A: WORD;
B: DWORD;
ошибок нет! а если без Abs() то Range check error.
(в момент отладки A=7; B=8;)
← →
ancara ( 2004-06-08 10:58 ) [9]
Еще ситуация:
X: byte;
A: WORD;
B: DWORD;
ошибок нет! а если без 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;
Посмотрев на код, сгенерированный компилятором, будет видно, что, возможно, потребуется еще где-нибудь применить явное приведение типов.
Integer overflow ошибка как исправить
Сообщений: 11,442
при подсчете хеш-суммы ошибка Integer Overflow. как обойти?
Привет всем!
Возникла проблема.. при подсчете md5 файла выскакивает ошибка об integer overflow.
Код выполнения вот:
Модуль n формы
begin repeat Application.ProcessMessages; if (SearchRec.Attr and faDirectory) <> faDirectory then begin if StartDir + SearchRec.Name <> StartDir then begin case FilesListGenForm.HashGr.ItemIndex of 0: Buff := StartDir + SearchRec.Name + ':' + UpperCase(MD5Print(MD5File(StartDir + SearchRec.Name))); //считаем MD5 файла 1: Buff := StartDir + SearchRec.Name + ':' + FileCRC(StartDir + SearchRec.Name); end;
Ошибка выскакивает сдесь:
Мродуль MD5:
procedure FF(var a: DWORD; b, c, d, x: DWORD; s: BYTE; ac: DWORD); begin inc(a, F(b, c, d) + x + ac); //ошибка сдесь rot(a, s); inc(a, b); end;
как решить? ранее такого не было. Как отследить откуда ноги растут?
| Человек_Борща |
| Посмотреть профиль |
| Найти ещё сообщения от Человек_Борща |
Ошибка при знаковом делении
Доброго времени суток. У меня есть два файла: first.cpp и second.asm . Проект пишу в эмуляторе 86 серии, но это не столь важно для контекста вопроса. Итак, у меня есть весьма тривиальная на первый взгляд задачка — вычислить выражение (22 / c + 3 * b) / (36 — a * c / 3). В cpp файла происходит ввод переменных и дальнейший экспорт в ассемблеровский. Я смог написать код, который считает это выражение на cpp и на asm. Только проблема в том, что знаменатель у меня при больших числах выражается совсем не так и в сумме я получаю ошибку деления на ноль (это только в asm). а вот second.cpp считает всё без ошибок. Итак, вот код конкретно расчёта знаменателя:
; Объявление переменных, которые экспортируются из cpp файла Extrn num_a:byte, num_b:byte, num_c:byte, numerator:dword, denominator:word, result:word ; Вычисление числителя . ; Вычисление знаменателя mov al, num_a imul num_c mov cl, 3 idiv cl ; Ошибка деления на ноль! cbw mov bx, 36 sub bx, ax mov ax, bx mov denominator, AX ; Получение финального результата mov AX, word ptr numerator mov DX, word ptr numerator+2 idiv denominator mov result, AX
Допустим, когда я ввожу следующее:
a= - 100 b= -100 c= -100
числитель= -300 знаменатель= -3297 cpp - 0 Divide error
Но при этом, когда я ввожу другие значения. Например:
a= -10 b= 7 c= -4
То всё работает верно, результаты совпадают. Что же не так?