Перейти к содержимому

Integer overflow ошибка как исправить

  • автор:

Переполнение (ошибка 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 

То всё работает верно, результаты совпадают. Что же не так?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *