Greetings everyone,
I came across an approximation to calculating the log of an number (to about 6 digits in precision):
https://stackoverflow.com/questions/39821367/very-fast-approximate-logarithm-natural-log-function-in-cA straightforward pascal implementation shows that it is about twice as fast as using the built-in log function.
function fasterlog(a: single): single; // 6 digits acc
type
TFI = packed record
case Integer of
0: (FloatAccess: single);
1: (IntAccess: int32);
end;
var
m, r, s, t, f, i: single;
e, g: Int32;
begin
e := (TFI(a).IntAccess - $3f2aaaab) and $ff800000;
g := TFI(a).IntAccess-e;
m := TFI(g).FloatAccess;
i := e * 1.19209290E-7;
f := m - 1.0;
s := f * f;
// Compute log1p(f) for f in [-1/3, 1/3]
r := 0.230836749*f-0.279208571;
t := 0.331826031*f-0.498910338;
//r := FMASingle(r,s,t);
r := r*s+t;
r := r*s+f;
Result := i*0.693147182+r;
end;
As explained in the link the algorithm splits the number in mantissa and exponent and adds the logarithm of both; in the former case an approximation is used.
To do this efficiently some bit manipulation is used.
A few question arose for me:
- Can a typecast be also executed on an expression (effectively getting rid of the variable g in the above code); something like:
m := TFI(TFI(a).IntAccess-e).FloatAccess;
- I wanted to utilize the FMA function (fused multiplication and addition) as used in the original code; the compiler however raised: "..Error: The function used, is not supported by the selected instruction set: FMA"; the CPU on my computer (as probably most) should allow the usage, yet there is no 'FMA' option in the fpu compiler settings.
- Is there an introduction how to use assembler within the pascal code? Is there any restrictions on which registers can be used; is the compiler capable of using more advanced instructions such as the equivalent of the above FMA command?
If some light could be shed on these question, it would be highly appreciated.
Best to everyone.