Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2024-02

Re: Floating point question (Rafael Picanço)

5 messages · 3 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Rafael Picanço

I have some questions about {$MINFPCONSTPREC 64} and the mentioned change introduced by FPC 2.2 (the "it" from here after).

1) Does it affects constants only?

2) Does it affects the LargerFloat type?

3) Should I use {$MINFPCONSTPREC 64} in {$mode objfpc} too to avoid it?

4) BONUS: Is the LargerFloat type really the larger, or should one do something else?

Best regards,
Rafael

Reply by email

James Richters
to Rafael Picanço

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

Reply by email

Rafael Picanço
to James Richters
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

Reply by email

Bart
to Rafael Picanço
Show quoted text 8 lines
type {$IFDEF CPU86}{$IFDEF CPU32} TLargerFloat = Extended; {$ENDIF}{$ENDIF} {$IFDEF CPUX86_64} TLargerFloat = Double; {$ENDIF}

Why (re-invent the wheel)?
Why not use Math.Float?
IIRC then this is Extended, double or Single depending on CPU type. And always the largest precision the CPU supports.

Bart

Reply by email

Rafael Picanço
to Bart
Why (re-invent the wheel)? Why not use Math.Float? IIRC then this is Extended, double or Single depending on CPU type. And always the largest precision the CPU supports.

Thanks Bart. Math.Float is really great, I will start using it today.

Show quoted text 21 lines
On Tue, Feb 6, 2024 at 6:13 PM Rafael Picanço via fpc-pascal wrote: > type > {$IFDEF CPU86}{$IFDEF CPU32} > TLargerFloat = Extended; > {$ENDIF}{$ENDIF} > > {$IFDEF CPUX86_64} > TLargerFloat = Double; > {$ENDIF} Why (re-invent the wheel)? Why not use Math.Float? IIRC then this is Extended, double or Single depending on CPU type. And always the largest precision the CPU supports. -- Bart

Reply by email