Блог пользователя Quercitron

Автор Quercitron, 12 лет назад, По-русски

Долго пытался найти, почему мое решение получает Runtime Error. Было установлено, что программа падает во время подсчета "векторного произведения" по трем точкам, текст ошибки:
"Project E.exe raised exception class EIntOverflow with message 'Integer overflow'."
Координаты точек не превосходили по модулю 10^9, значит координаты векторов не больше 2*10^9, и получаемый результат больше 8*10^18 никак не мог быть. А int64 это примерно до 9*10^18, и вроде все должно замечательно работать.
Тогда я поймал значения, на которых программа падала в этом месте. И получилась весьма странная вещь, суть которой сводится к следующему: если запустить такую программу:
{"dollar"Q+}
uses SysUtils;
var
  a, b, c: int64;
procedure bug;
begin
    a := -1834569418;
    b := -330651027;
    c := a * b;
end;
Begin
  bug;
End.
("dollar" -- это знак доллара, но я так и не понял, можно ли его вставить в текст здесь)
то при умножении a на b случается описанная выше ошибка.
Но если выключить директиву проверки на переполнение целочисленных операций Q: {Q-} то все будет выполняться без ошибок. Так же было установлено, что даже с включенной Q+, если производить умножение в основном теле программы (т.е. между Begin и End.), то все будет нормально все будет нормально, пока включен оптимизатор (O+), а если его выключить, то и там падает... При этом числа не обязательно только такие, их можно менять в довольно большом диапазоне (+/- 5-10 %).
Короче, полная хрень какая-то.
Я хочу узнать, может кто-нибудь сталкивался с похожими вещами или просто может объяснить, почему такое происходит и как с этим бороться.
Заранее спасибо.

  • Проголосовать: нравится
  • +24
  • Проголосовать: не нравится

»
12 лет назад, # |
  Проголосовать: нравится +2 Проголосовать: не нравится
ИМХО, int64 в Delphi - зло, страшнее ядерной войны.
Работает долго, иногда вот с такими ошибками...
»
12 лет назад, # |
  Проголосовать: нравится +11 Проголосовать: не нравится
Я тоже сталкивался с этим в какой-то геометрии. Это вроде-бы из-за того, что delphi (не обязательно 7) неправильно проверяет на owerflow у int64. После этого окончательно перешел на fpc. В нем подобных багов я не замечал.