Quercitron's blog

By Quercitron, 13 years ago, In Russian

Долго пытался найти, почему мое решение получает 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 %).
Короче, полная хрень какая-то.
Я хочу узнать, может кто-нибудь сталкивался с похожими вещами или просто может объяснить, почему такое происходит и как с этим бороться.
Заранее спасибо.

  • Vote: I like it
  • +24
  • Vote: I do not like it