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?
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:
-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:
#!/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.