SetRoundMode(rmUp) and RoundTo(4.1, 0) - Unexpected result

Viewed 307

Yet another question about rounding - I know :)

I can't wrap my head around why the following happens:

    SetRoundMode(rmUp);
    try
      Result := RoundTo(4.1, 0); //Result = 4???
    finally
      SetRoundMode(rmNearest);
    end;

I would expect the result to be 5 for any input larger than 4, having specifically specified the RoundMode to be rmUp.

If I check the code for RoundTo, it bypasses the current FPU settings for some reason (System.Math.pas, ln 1025):

@@ValidRange:
  fnstcw  word ptr [esp]   { save }
  word ptr [esp+2] { scratch }
  and     word ptr [esp+2], $f0ff { clean RC/PC bits. }
  or      word ptr [esp+2], $0300 { round to nearest even / full precision }
  fldcw   word ptr [esp+2]

If I comment this out, it works as expected. Why is that done? Can I safely use my "corrected" version? (Sure, I can easily write a function that does what I want, but seeing as I already use Math, I don't like re-inventing the wheel for no reason.)

The documentation is also confusing. It mentions that SimpleRoundTo is affected by the FPU, but not RoundTo. Neither is...

1 Answers
Related