External sigfpe lazarus что за ошибка
Перейти к содержимому

External sigfpe lazarus что за ошибка

  • автор:

Ошибка External: SIGFPE

Нужно было сделать программу, которая бы решала многочлен методом barstow (деление на многочлен), но при вычислении dr (39 строка) программа выдает ошибку External: SIGFPE.
Как я узнала, это означает, что в числе слишком много знаков, но как это исправить?

Вот сам код программы:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
procedure TForm1.Button1Click(Sender: TObject); var n,i:integer; Es,r,s,D,k:real; dr,ds:extended; a:array[0..10] of real; b:array[0..10] of real; c:array[0..10] of real; begin n:=strtoint(edit1.text); for i:=0 to n do a[i]:=strtofloat(stringgrid1.cells[1,i+1]); Es:=strtofloat(edit2.text); r:=strtofloat(edit3.text); s:=strtofloat(edit4.text); repeat for i:=0 to n do begin b[7]:=a[7]; b[6]:=a[6]+r*a[6]; b[5]:=a[5]+r*b[6]+s*a[7]; b[4]:=a[4]+r*b[5]+s*b[6]; b[3]:=a[3]+r*b[4]+s*b[5]; b[2]:=a[2]+r*b[3]+s*b[4]; b[1]:=a[1]+r*b[2]+s*b[3]; b[0]:=a[0]+s*b[2]; c[7]:=b[7]; c[6]:=b[6]+r*b[6]; c[5]:=b[5]+r*b[6]+s*b[7]; c[4]:=b[4]+r*b[5]+s*b[6]; c[3]:=b[3]+r*c[4]+s*b[5]; c[2]:=b[2]+r*c[3]+s*c[4]; c[1]:=b[1]+r*c[2]+s*c[3]; c[0]:=b[0]+s*c[2]; end; k:=c[2]*c[2]-c[1]*c[3]; if k<>0 then begin dr:=(-1*b[1]*c[2]+b[0]*c[3])/k; ds:=(-b[0]*c[2]+b[1]*c[3])/k; end; r:=r+dr; s:=s+ds; until ((abs(ds/s)) and (abs(dr/r))); //Roots of calculation D:=r*r-4*(-s); if D>0 then begin edit5.text:=floattostr(((-r-sqrt(D))/2)); edit6.text:=floattostr(((-r+sqrt(D))/2)); end; if D=0 then begin edit5.text:=floattostr(-(-r/2)); edit6.text:='-' ; end; if D0 then begin edit5.text:='-'; edit6.text:='-'; end; end; end.

Вложения

project.2.7z (3.29 Мб, 2 просмотров)

External sigfpe lazarus что за ошибка

runewalsh писал(а): %единицыинули — синтаксис FPC для двоичных литералов (чисел в двоичной системе счисления).
OR любого числа с %111111 выставляет ему младшие 6 битов и не трогает остальные.

viktor96 писал(а): Однако заметил что если изменить первую и последнюю единицу на нули, то неизбежно возвращается ошибка.

Ну тк, слева направо:

runewalsh писал(а): 5: PM / Precision (inexact result) mask
4: UM / Underflow mask
3: OM / Overflow mask
2: ZM / Zero-divide mask
1: DM / Denormalized operand mask
0: IM / Invalid operation mask

> Set8087CW(%111111);
А так не надо делать, хотя ты почти ничего и не сломал. В контрольном слове есть другие биты с другими функциями, которые ты этим вызовом зануляешь. Set8087CW(Get8087CW or %111111) же. И да, это достаточно сделать один раз в начале программы.

Да, теперь буду знать, программу исправил, сделал только один вызов в начале программы, теперь я чувствую что программу можно назвать почти универсальной для любого графика типа y=f(x). В дальнейшем займусь подробным изучением аппаратной части, что бы не наломать дров) Спасибо вам огромное!!)
Оставлю код своей программы здесь чтобы желающие могли им воспользоваться для примера. Можете её модернизировать, я разрешаю)
Код: Выделить всё program GoodWorkGraph;
uses Graph,SysUtils,CRT,Math;
var
c:char;
x,y,y1,step_x,step_y:real;
CenterCordinatXY:array [0..1] of integer;
sizeXp,sizeXm,sizeYp,sizeYm:integer;
const
gradient=40;
x_max=639;
y_max=479;
l=10;
speed=5;
< ********************************************************************** >
procedure GraphCHK;
var Gd,Gm:smallint;
begin
Gd:=VGA;
Gm:=VGAHi;
InitGraph(Gd,Gm,»);
if GraphResult <> grOk then
begin
write(‘Ошибка’);
halt(1);
end;
end;
< ********************************************************************** >
procedure SetCenter(var CnCrd:array of integer); //Установка центра
var st_x,st_y:real;
begin
st_x:=(x_max+1)/(sizeXp+sizeXm);
st_y:=(y_max+1)/(sizeYp+sizeYm);
CnCrd[0]:=round(st_x*sizeXm);
CnCrd[1]:=y_max-round(st_y*sizeYm);
end;

procedure SetSize (var sXp,sXm,sYp,sYm:integer); //Установка размера графика как в положительных так и отрицательных
begin //значениях X и Y
write(‘set size X+: ‘); readln(sXp);
write(‘set size X-: ‘); readln(sXm);
write(‘set size Y+: ‘); readln(sYp);
write(‘set size Y-: ‘); readln(sYm);
end;

procedure DrawGrid;
var loop,metka,gipfu:integer;
begin
Line(0,CenterCordinatXY[1],x_max,CenterCordinatXY[1]);
Line(CenterCordinatXY[0],0,CenterCordinatXY[0],y_max);
step_x:=x_max/(sizeXp+sizeXm);
step_y:=y_max/(sizeYp+sizeYm);
<******************************************************************************>
MoveTo(CenterCordinatXY[0],CenterCordinatXY[1]); //обрисовка меток по X+
loop:=0; metka:=0;
while GetX begin
if (step_x>=20) then
begin
if loop mod round(step_x) = 0 then
begin
Line(GetX,GetY+l,GetX,GetY-l);
OutTextXY(GetX-l,GetY+2*l,IntToStr(metka));
inc(metka);
end;
end
else
begin
gipfu:=round(gradient/step_x);
if loop mod round(step_x*gipfu) = 0 then
begin
Line(GetX,GetY+l,GetX,GetY-l);
OutTextXY(GetX-l,GetY+2*l,IntToStr(metka));
inc(metka,gipfu);
end;
end;
inc(loop);
MoveTo(GetX+1,GetY);
end;
<***************************************************************************************************************>
MoveTo(CenterCordinatXY[0],CenterCordinatXY[1]); //обрисовка меток по X-
loop:=0; metka:=0;
while GetX>0 do
begin
if (step_x>=20) then
begin
if loop mod round(step_x) = 0 then
begin
Line(GetX,GetY+l,GetX,GetY-l);
OutTextXY(GetX-l,GetY+2*l,IntToStr(-metka));
inc(metka);
end;
end
else
begin
gipfu:=round(gradient/step_x);
if loop mod round(step_x*gipfu) = 0 then
begin
Line(GetX,GetY+l,GetX,GetY-l);
OutTextXY(GetX-l,GetY+2*l,IntToStr(-metka));
inc(metka,gipfu);
end;
end;
inc(loop);
MoveTo(GetX-1,GetY);
end;
<***************************************************************************************************************>
MoveTo(CenterCordinatXY[0],CenterCordinatXY[1]); //обрисовка меток по Y+
loop:=1; if (step_y>=20) then metka:=1 else metka:=round(gradient/step_y);
while GetY begin
if (step_y>=20) then
begin
if loop mod round(step_y) = 0 then
begin
Line(GetX-l,GetY,GetX+l,GetY);
OutTextXY(GetX+l+2,GetY-2,IntToStr(metka));
inc(metka);
end;
end
else
begin
gipfu:=round(gradient/step_y);
if loop mod round(step_y*gipfu) = 0 then
begin
Line(GetX-l,GetY,GetX+l,GetY);
OutTextXY(GetX+l+2,GetY-2,IntToStr(metka));
inc(metka,gipfu);
end;
end;
inc(loop);
MoveTo(GetX,GetY-1);
end;
<***************************************************************************************************************>
MoveTo(CenterCordinatXY[0],CenterCordinatXY[1]); //обрисовка меток по Y-
loop:=1; if (step_y>=20) then metka:=1 else metka:=round(gradient/step_y);
while GetY>0 do
begin
if (step_y>=20) then
begin
if loop mod round(step_y) = 0 then
begin
Line(GetX-l,GetY,GetX+l,GetY);
OutTextXY(GetX+l+2,GetY-2,IntToStr(-metka));
inc(metka);
end;
end
else
begin
gipfu:=round(gradient/step_y);
if loop mod round(step_y*gipfu) = 0 then
begin
Line(GetX-l,GetY,GetX+l,GetY);
OutTextXY(GetX+l+2,GetY-2,IntToStr(-metka));
inc(metka,gipfu);
end;
end;
inc(loop);
MoveTo(GetX,GetY+1);
end;
end;

function F(x:real):real; //y=ln(x+5)
begin
F:=ln(x+5)*step_y;
end;

procedure DrawFuntcion; //Обрисовка графика
var
loop:integer;
begin;
x:=-CenterCordinatXY[0]/step_x;y:=0;y1:=0; loop:=-CenterCordinatXY[0];
while loop begin
y:=F(x);
y1:=F(x+(1/step_x));
if not(IsInfinite(y) or IsNaN(y)) then
if not (IsInfinite(y1) or IsNaN(y1)) then
Line(loop+CenterCordinatXY[0],CenterCordinatXY[1]-round(y),loop+1+CenterCordinatXY[0],CenterCordinatXY[1]-round(y1));
x:=x+(1/step_x);
inc(loop);
end;
end;

begin
Set8087CW(Get8087CW or %111111);
SetSize(sizeXp,sizeXm,sizeYp,sizeYm);
SetCenter(CenterCordinatXY);
GraphCHK;
DrawGrid;
DrawFuntcion;
repeat
c:=ReadKey;
if c=#75 then MoveLeft;
if c=#80 then MoveDown;
if c=#77 then MoveRight;
if c=#72 then MoveUp;
until c=#27;
CloseGraph;
end.

Lazarus

* * *

  • Free Pascal
  • Website
  • Downloads
  • Wiki
  • Documentation
  • Bugtracker
  • Mailing List
  • Lazarus
  • Website
  • Downloads (Laz+FPC)
  • Packages (OPM)
  • FAQ
  • Wiki
  • Documentation (RTL/FCL/LCL)
  • Bugtracker
  • CCR Bugs
  • IRC channel
  • GIT
  • Mailing List
  • Other languages
  • Foundation
  • Website
  • Useful Wiki Links
  • Project Roadmap
  • Getting the Source
  • Screenshots
  • How to use the forum

External sigfpe lazarus что за ошибка

I am making a charting program and encountered very weird error. The
exception raised is: ‘External: SIGFPE’. In file ‘lcltype.pp’ at line
3009. On that line is the MulDiv() function, and the operation I am doing
is just assigning font height. I then remembered the question i asked
days ago about 1/0 and Ln(0). Sven suggested to use SetExceptionMask.

I tried this in my FormCreate:

SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow,
exUnderflow]);

Now the program crashes every time it start. I also tested to put the
above line on an empty project, same error happened in gtk2winapi.inc!

Could anyone explain what’s SIGFPE? Why there is a SetExceptionMask? Why a
normal empty form application will generate SIGFPE with these masks, and
how to trace down to the cause of this error?

2013-03-07 08:53:37 UTC
Post by Xiangrong Fang
Could anyone explain what’s SIGFPE?

SIGFPE stands for SIGnal Floating Point Exception, that is caused by a
probably invalid operation involving floating points.

Post by Xiangrong Fang
Why there is a SetExceptionMask?
Probably to override the same thing already done by (implicitly used)
libraries, e.g. gtk2

Post by Xiangrong Fang
Why a normal empty form application will generate SIGFPE with these masks,
and how to trace down to the cause of this error?

Because setting the mask means telling the processor to generate (or not to
generate? I forgot) SIGFPE for the given operations. e.g. exZeroDivide may
trigger SIGFPE if there’s a division by zero with floating point operation.
How to trace? You already get it, the program will report the line that
causes it, you can directly go to the respective line to see what happens.
But this requires that the code lies in the program space (not in external
library) and the code is compiled with runtime error backtrace (-gl).
Otherwise, the program can only report as deep as it can find.


View this message in context: http://free-pascal-lazarus.989080.n3.nabble.com/Lazarus-What-s-External-SIGFPE-tp4029706p4029715.html
Sent from the Free Pascal — Lazarus mailing list archive at Nabble.com.

Xiangrong Fang
2013-03-07 09:04:13 UTC

Post by leledumbo
Because setting the mask means telling the processor to generate (or not to
generate? I forgot) SIGFPE for the given operations. e.g. exZeroDivide may
trigger SIGFPE if there’s a division by zero with floating point operation.
How to trace? You already get it, the program will report the line that
causes it, you can directly go to the respective line to see what happens.
But this requires that the code lies in the program space (not in external
library) and the code is compiled with runtime error backtrace (-gl).
Otherwise, the program can only report as deep as it can find.

I don’t understand:

1) even if I set the masks, why an empty LCL application generate SIGFPE?
It means that somewhere GTK or whatever library *indeed* do things like
1/0, only that they are normally hidden/not reported?

2) I already found the problem in my code which is a like look like:

*if tbLog.Down then Y := exp(Y);*

And Y is a big number e.g. 2500, which caused floating point overflow.
The problem was that the number itself should be Log()ed, so that exp()
only restore its original value. That was my bug, but the weird thing is
that SIGFPE is generated in unit LCLType on the line that set font height,
which is very innocent, and after I commented out the font.Height
operation, the SIGFPE slipped to somewhere else, but NEVER on the line that
generated it!

Could you explain why? and how to locate where the SIGFPE occurred?

Kostas Michalopoulos
2013-03-07 09:37:34 UTC

Most likely it is your GTK+ theme. Many GTK+ themes and theme engines abuse
floating point calculations which go unnoticed normally since the vast
majority of C/C++ programs do not check for them. The solution is to do
something like (IIRC):

Which disables all floating point exceptions. Alternatively switch to a
theme that doesn’t mess FP calculations, bu you can’t guarantee that your
users will have it.

Post by leledumbo
Because setting the mask means telling the processor to generate (or not to
generate? I forgot) SIGFPE for the given operations. e.g. exZeroDivide may
trigger SIGFPE if there’s a division by zero with floating point operation.
How to trace? You already get it, the program will report the line that
causes it, you can directly go to the respective line to see what happens.
But this requires that the code lies in the program space (not in external
library) and the code is compiled with runtime error backtrace (-gl).
Otherwise, the program can only report as deep as it can find.

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

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