Recent

Author Topic: StrToFloat - formatted  (Read 2281 times)

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 1050
Re: StrToFloat - formatted
« Reply #45 on: June 27, 2022, 12:58:32 pm »
The basic assumption here is, that a binary value is not exact, when it isn't equal to a decimal value. Or, more broadly: you cannot simply translate any floating point number into a different numeral system, with the same accuracy. Obvious example: 1/3 is 0.1 in base 3, or 0.4 in base 12, but it has no accurate representation in base 2 or 10. That's why early computers used BCD to calculate in base 10, because that's the norm.

But it's probably missing the point, as fractions crop up during math in either case. So it's useless trying to keep things "exact". It's far more practical to look at the amount of significant digits you need. And that's where floating-point math excels. In fixed-point math (currency), as shown you lose accuracy fast, while with floating-point the amount of significant figures stays as high as will fit the container size.

In short: for math, always use the largest format floating-point number available, which is extended (x86/AMD64 only), or double (everything else). And only compare your chosen amount of significant figures.

Well, ok, perhaps not if you're calculating 3D geometry. Although Kerbal Space Program doesn't agree ;)

PascalDragon

  • Hero Member
  • *****
  • Posts: 4305
  • Compiler Developer
Re: StrToFloat - formatted
« Reply #46 on: June 27, 2022, 01:18:13 pm »
Don't underestimate fixed point types. Depending on your use case they might be better. ;)
« Last Edit: June 28, 2022, 01:23:42 pm by PascalDragon »

BrunoK

  • Sr. Member
  • ****
  • Posts: 313
  • Retired programmer
Re: StrToFloat - formatted
« Reply #47 on: June 27, 2022, 06:07:12 pm »
... So 5.125 can only be approximated and the math system can't simply show 5.125, because what if you did try to use the number that 5.125 is approximated as?
Well, as a special case 5.125 is exactly stored in double as 0.640625 × (2 ^ 3)

J-G

  • Hero Member
  • *****
  • Posts: 815
Re: StrToFloat - formatted
« Reply #48 on: June 27, 2022, 06:21:31 pm »
... So 5.125 can only be approximated and the math system can't simply show 5.125, because what if you did try to use the number that 5.125 is approximated as?
Well, as a special case 5.125 is exactly stored in double as 0.640625 × (2 ^ 3)
My point was that using my test program, all three 'types' return an incorrect value -
Currency = 5.1248,
Double &
Extended =  5.12499999999999
FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

BrunoK

  • Sr. Member
  • ****
  • Posts: 313
  • Retired programmer
Re: StrToFloat - formatted
« Reply #49 on: June 27, 2022, 08:06:00 pm »
This bit of code should be able to test for GOOD or BAD using the caption but there is no way to guarantee an exactly double. If 4 decimal digits are all you need, use a currency, otherwise design you own fixed point.
Code: Pascal  [Select][+][-]
  1. procedure TForm1.TPI_ValEditingDone(Sender: TObject);
  2. type
  3.   TDecMulFact = 0..3;
  4. const
  5.   cMultFact : array[TDecMulFact] of integer =
  6.                 (1,
  7.                  10,
  8.                  100,
  9.                  1000);
  10. var
  11.   lUInt64 : UInt64;
  12.   lDecimals : integer;
  13.   lStr : ShortString;
  14.   i : integer;
  15. begin
  16.   if not TryStrToFloat(TPI_Val.Caption, TPI) then begin
  17.     OK.Caption:='Invalid entry';
  18.     Exit;
  19.   end;
  20.   lStr := TPI_Val.Caption;
  21.   lDecimals := 0; // Init
  22.   for i:=1 to length(lStr) do begin
  23.     if lStr[i]='.' then begin
  24.       lDecimals := length(lStr) - i;
  25.       lStr := Copy(lStr, 1, i-1) + Copy(lStr, i+1, length(lStr) - i);
  26.       break;
  27.     end;
  28.   end;
  29.   if not (lDecimals in [low(TDecMulFact)..High(TDecMulFact)]) then begin
  30.     OK.Caption:='Too many decimals';
  31.     Exit;
  32.   end;
  33.  
  34.   lUInt64 := StrToInt(lStr); // Note lDecimals has nb of digits after '.'
  35.   Good := ((lUInt64 * G1) mod cMultFact[lDecimals]) = 0;
  36.  
  37.   if good then
  38.     OK.Caption:='GOOD'
  39.   else
  40.     OK.Caption:='BAD';

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 1050
Re: StrToFloat - formatted
« Reply #50 on: June 28, 2022, 12:45:41 pm »
... So 5.125 can only be approximated and the math system can't simply show 5.125, because what if you did try to use the number that 5.125 is approximated as?
Well, as a special case 5.125 is exactly stored in double as 0.640625 × (2 ^ 3)
My point was that using my test program, all three 'types' return an incorrect value -
Currency = 5.1248,
Double &
Extended =  5.12499999999999

The thing is, as soon as you start doing math to it, you get rounding errors. When you take a decimal number and convert that to binary, you're doing math to it. And the other way around, of course. It is exactly the same as with integer math, only the fractions (rounding errors) are a lot smaller.

If you don't want any rounding errors: use Planck units.

winni

  • Hero Member
  • *****
  • Posts: 3125
Re: StrToFloat - formatted
« Reply #51 on: June 28, 2022, 12:52:09 pm »

If you don't want any rounding errors:

Use an analogue computer, not a binary one.


PascalDragon

  • Hero Member
  • *****
  • Posts: 4305
  • Compiler Developer
Re: StrToFloat - formatted
« Reply #52 on: June 28, 2022, 01:24:33 pm »
Don't underestimate fixed floating point. Depending on your use case they might be better. ;)
Did you mean fixed _decimal_ point ?

I meant fixed point types. But yeah, thank you for pointing that out... :-[

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 1050
Re: StrToFloat - formatted
« Reply #53 on: July 03, 2022, 10:49:09 pm »

If you don't want any rounding errors:

Use an analogue computer, not a binary one.
That doesn't really make a difference. It's about resolution. Even if you have an ultimately exact analog computer, you have to feed it with starting values, and at the end you have to extract the answer. Analog-to-Decimal-converters don't have infinite precision. That's the whole point.

Even more so: that's also the main problem with quantum computers. Even if we ignore the fact, that they aren't real quantum computers until they can use quantum entanglement, which they can't, the output contains all the possible solutions at the same time. Every time you calculate and read it, each bit has the value of one of the possible solutions, within the error margins...

They would work better when analog, but unfortunately in quantum mechanics everything is an integer.

So, until they can synchronize turning the entangled particles into a wave function totally synchronously and resolve that perfectly into binary words, as many times as there are solutions, it is just noise.

So, even on that scale it's integers all the way down :D

PascalDragon

  • Hero Member
  • *****
  • Posts: 4305
  • Compiler Developer
Re: StrToFloat - formatted
« Reply #54 on: July 04, 2022, 01:33:17 pm »

If you don't want any rounding errors:

Use an analogue computer, not a binary one.
That doesn't really make a difference. It's about resolution. Even if you have an ultimately exact analog computer, you have to feed it with starting values, and at the end you have to extract the answer. Analog-to-Decimal-converters don't have infinite precision. That's the whole point.

But you wouldn't have the rounding errors during the computation which is a real issue (no pun intended) with floating point maths.

 

TinyPortal © 2005-2018