Recent

Author Topic: curiosity with sigfpe  (Read 2789 times)

yogo1212

  • New Member
  • *
  • Posts: 22
curiosity with sigfpe
« on: February 02, 2015, 10:31:50 pm »
hi :-D

i've got a puzzle to solve and i don't think i'll manage on my own ;-)

under certain conditions there is a division-by-zero-exception with non-zero values.
that exception changes to an 'invalid operaion'-exception when the writeln is present.

Strange..

anyone got a clue, why that is?

Code: [Select]
An unhandled exception occurred at $0000000000400282 :
EDivByZero : Division by zero
  $0000000000400282
  $000000000040030A

with a writeln in front of the branch the output looks like this:
Code: [Select]
-0.0008417963982 < -2.455074909E-42
An unhandled exception occurred at $00000000004003B7 :
EInvalidOp : Invalid floating point operation
  $00000000004003B7
  $00000000004004AA

can someone explain what happens?

Just in case anyone wonders: I want to find the maximum factor to advance dir so that it doesn't leave a unit cube. The method is called once for every dimension. it works 99.99 % of the time but when getting close to the edge of a voxel it crashes.

Here is the extracted example:

Code: [Select]
#!/usr/bin/instantfpc

{$Mode ObjFpc}

uses SysUtils, Math;

type
{$IF sizeof(Single) = sizeof(Integer)}
  Tglfloatsizedint = Integer;
{$ELSE}
  {$ERROR size: glfloatsizedint}
{$ENDIF}

  Pglfloatsizedint = ^Tglfloatsizedint;

TIntFloat = record
case boolean of
False: (intval: Tglfloatsizedint);
True: (floatval: Single);
end;

const
  glfloatsignbitindex = ((sizeof(Single) shl 3) - 1);
  // TODO this gives warning 'range check error while evaluating constant'
  glfloatsignbit: Tglfloatsizedint = 1 shl glfloatsignbitindex;

procedure DoProgressVectorComponent(const pos, dir: Single; var Result: Single);
var
offset: TIntFloat;
begin
//This gives a float with same sign of dir
offset.floatval := 1;
offset.intval := offset.intval or (Pglfloatsizedint(@dir)^ and glfloatsignbit);
// and adds it to pos
offset.floatval := pos - offset.floatval;
offset.intval := (offset.intval and not glfloatsignbit) or
(Pglfloatsizedint(@dir)^ and glfloatsignbit);
// TODO there was a sigfpe .. and again. after some time of doing nothing

writeln(FloatToStr(offset.floatval) + ' < ' + FloatToStr(dir));

if offset.floatval < dir then
Result := Min(offset.floatval / dir, Result);
  // no else necessary because result is expected to be 1 at most.
end;


var
pos, dir, Result: Single;

begin
Pglfloatsizedint(@dir)^ := -2147481896;
Pglfloatsizedint(@pos)^ := -1082144555;
DoProgressVectorComponent(pos, dir, Result);
writeln(Result);
end.

bigeno

  • Sr. Member
  • ****
  • Posts: 266
Re: curiosity with sigfpe
« Reply #1 on: February 02, 2015, 10:49:06 pm »
Your dir variable is single. Single have range 1.5E-45 .. 3.4E38

yogo1212

  • New Member
  • *
  • Posts: 22
Re: curiosity with sigfpe
« Reply #2 on: February 06, 2015, 02:17:23 am »
I understand why an error occurs (8-bit exponent) - I want to know why different exceptions are being raised depending on the same line depending on the presence of a writeln  :)

Leledumbo

  • Hero Member
  • *****
  • Posts: 8819
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: curiosity with sigfpe
« Reply #3 on: February 06, 2015, 07:24:49 am »
Compiling your code on an x86_64-linux machine even gives EAccessViolation:
Code: [Select]
An unhandled exception occurred at $0000000000400343:
EAccessViolation: Access violation
  $0000000000400343 line 43 of test.pas
  $0000000000400416 line 54 of test.pas
The difference probably triggered by the default exception mask on each platform. Call SetExceptionMask([]) at program start to enable all of them, that's what you should actually get.

For why you get different exception based on WriteLn existence, recompile with -gl. I guess the expression that you want to WriteLn is the exception source for EInvalidOp.

yogo1212

  • New Member
  • *
  • Posts: 22
Re: curiosity with sigfpe
« Reply #4 on: February 15, 2015, 10:58:43 am »
Thank you!

Not only do you offer a decent explanation - but also tools!

Nice  :D

 

TinyPortal © 2005-2018