All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sonar.l10n.delphi.rules.community-delphi.MathFunctionSingleOverload.html Maven / Gradle / Ivy

The newest version!

Why is this an issue?

High-precision overloads (Double and Extended) of the standard math functions are preferred over the single-precision (Single) overloads, for stability and platform independent behaviour.

Firstly, single-precision numbers are only fully accurate for a relatively small range of numbers. Routines that produce very small or very large numbers may be very inaccurate when using Single - for example, integers larger than 16777216 cannot be stored accurately.

Secondly, the single-precision overloads can return extended-precision values on 32-bit Windows in some cases.

Delphi carries out single-precision floating point calculations using extended-precision values. In 64-bit, the standard math functions invariably truncate their result to single-precision as expected. In 32-bit, however, the standard math functions do not truncate their result to single-precision. This means that on 32-bit Windows, these functions unexpectedly return an Extended instead of a Single.

For example, the following code will print 1,000,000,000,000 on 32-bit and 999,999,995,904 on 64-bit:

procedure Example;
var
  MyNum: Double;
begin
  MyNum := Power(10, 12); // Uses Single overload, which claims to return Single
  Writeln(MyNum);
end;

The following code will print 1,000,000,000,000 on both 32-bit and 64-bit:

procedure Example;
var
  MyNum: Double;
begin
  MyNum := Power(Double(10), 12); // Uses Double overload, which claims to return Double
  Writeln(MyNum);
end;

Note that in Delphi, the type of a number literal is the smallest possible type that can hold that value. This means that integer and floating point literals are usually interpreted as a Single.

How to fix it

If possible, refactor your code to use the Double or Extended overloads:

procedure Example(MyNum: Single);
begin
  Power(MyNum, 2);
end;
procedure Example(MyNum: Double);
begin
  Power(MyNum, 2);
end;

Otherwise, cast the number to Double or Extended before invocation:

procedure Example(MyNum: Integer);
begin
  Power(MyNum, 2);
end;
procedure Example(MyNum: Integer);
begin
  Power(Double(MyNum), 2);
end;

Resources





© 2015 - 2024 Weber Informatics LLC | Privacy Policy