I’m afraid I don’t qualify for the bonus, because I don’t know what
LargerFloat is.
I am a little bit embarrassed here. The TLargerFloat is a type I wrote for a simple test some time ago and I forgot about it. I was following the TLargeInteger convention (from struct.inc in my current windows system):
After realizing that the Extended type was not made for cross-platform, my point with TLargerFloat was to have a central place to test some types. I decided to use Double for everything, following the equivalence with pythonic doubles for timestamp synchronization in the systems I use.
unit timestamps.types;
{$mode ObjFPC}{$H+}
interface
type
{$IFDEF CPU86}{$IFDEF CPU32}
TLargerFloat = Extended;
{$ENDIF}{$ENDIF}
{$IFDEF CPUX86_64}
TLargerFloat = Double;
{$ENDIF}
implementation
end.
___
So, I guess I finally found why precision was better for explicitly typecasts in Linux (despite the higher granularity of clock_monotonic):
I guess {$MINFPCONSTPREC 64} would avoid explicit typecasting in the following code, is it correct?
unit timestamps;
{$mode objfpc}{$H+}
// {$MINFPCONSTPREC 64}
interface
uses
SysUtils, timestamps.types
{$IFDEF LINUX}
, Linux
, UnixType
{$ENDIF}
{$IFDEF DARWIN}
, ctypes
, MachTime
{$ENDIF}
{$IFDEF WINDOWS}
, Windows
{$ENDIF}
;
function ClockMonotonic : TLargerFloat;
implementation
{$IFDEF LINUX}
function ClockMonotonic: TLargerFloat;
var
tp: timespec;
a, b : TLargerFloat;
begin
clock_gettime(CLOCK_MONOTONIC, @tp);
a := TLargerFloat(tp.tv_sec);
b := TLargerFloat(tp.tv_nsec) * 1e-9;
Result := a+b;
end;
{$ENDIF}
{$IFDEF DARWIN}
{credits:
https://github.com/pupil-labs/pyuvc/blob/master/pyuvc-source/darwin_time.pxi }
var
timeConvert: TLargerFloat = 0.0;
function ClockMonotonic : TLargerFloat;
var
timeBase: mach_timebase_info_data_t;
begin
if timeConvert = 0.0 then begin
mach_timebase_info(@timeBase);
timeConvert :=
(TLargerFloat(timeBase.numer) / TLargerFloat(timeBase.denom) /
TLargerFloat(1000000000.0);
end;
Result := mach_absolute_time() * timeConvert;
end;
{$ENDIF}
{$IFDEF WINDOWS}
var
PerSecond : TLargeInteger;
function ClockMonotonic: TLargerFloat;
var
Count : TLargeInteger;
begin
QueryPerformanceCounter(Count);
Result := TLargerFloat(Count) / TLargerFloat(PerSecond);
end;
initialization
QueryPerformanceFrequency(PerSecond);
{$ENDIF}
end.
On Tue, Feb 6, 2024 at 12:52 PM James Richters <
Show quoted text 83 lines
wrote:
This is my opinion from my testing, but others may have something else to
say.
1) Does it affects constants only?
Not really, if you set a variable with constant terms, it is affected, if
you set a variable with other variables, it is not affected.
Cont
Mycontant := 8432+33/1440.0; //Is affected;
Var
MyDoubleVariable:Double;
MyDoubleVariable := 8432+33/1440.0; //Is affected
Var
MyInteger : Ineger;
MyByte : Byte
MySingle : Single;
MyDouble : Double;
MyInteger := 8432;
MyByte := 33;
MySingle := 1440.0;
MyDouble := MyInteger + MyByte / MySingle; // is NOT affected;
2) Does it affects the LargerFloat type?
I don’t know what you mean by LargerFloat, but Double an d Extended are
affected, and even Real if your platform defines Real as a Double.
Anything that is not Single precision is affected.
3) Should I use {$MINFPCONSTPREC 64} in {$mode objfpc} too to avoid it?
Everyone should use {$MINFPCONSTPREC 64} in all programs until the bug is
fixed, unless you use extended, then you have no good solution. Because you
can’t set it to 80.
4) BONUS: Is the LargerFloat type really the larger, or should one do
something else?
I’m afraid I don’t qualify for the bonus, because I don’t know what
LargerFloat is.
James