[fpc-pascal] Floating point question

James Richters james.richters at productionautomation.net
Wed Feb 7 02:21:33 CET 2024


>IMO, the computations of AA+BB/CC (right hand side) should be carried out the same way, regardless of the type 
>on the left hand side of the assignment. So I would expect the values in DD, EE and FF being the same.

In this example DD hold the value 8427.02246100000 because DD it defined as a single and a single cannot hold the value 8427.02291666666666625000, there aren’t enough bits.

There is a typo on line:
   WRITELN ( 'EE = ',FF: 20 : 20 ) ;
	
It should have been 
   WRITELN ( 'EE = ',EE: 20 : 20 ) ;

And the result of it should have been:
EE = 8427.02291666666680000000

Which is not the same as 
FF = 8427.02291666666666625000
Again because 8427.02291666666666625000 won’t fit in a double.

The intention with all that was to show that everything works correctly if variables are used.  
The problem is when you use constants you get the 8427.0224... for everything, even when you have defined a double or an extended


>That said: wouldn't it make more sense to give EVERY FP CONSTANT the FP type with the best available precision? 
Yes, that is the old way, before the change in 2.2, but there are times when it would be more efficient to reduce the precision in the example of:
Const 
MyConst = 2.0;
That doesn't have to be floating point, and if you later use it as the denominator in a divide, it's less efficient than it would be if it was an integer.. I argue that on modern computers, who cares, but if you do want to reduce precision to increase performance, it NEEDS to be done in a way that guarantees no loss of precision with no modification of code.  The changes in v2.2 fails in this regard.   The thing I don't understand is that this was released as the default for all modes and indeed with no good way to turn it off for extended, even though it was already known that there would be inaccuracies when using constants with divides.   The change in 2.2 should NOT have been the default for everyone, it should have been an option for those who want performance at the cost of precision, but nearly everyone will not notice the performance increase on a modern computer, but we will all do not want to risk a loss of precision...  


>GG in this case would have the same value as HH, because the computation involving the constants 
>(hopefully done by the compiler) would be done with the best available precision. 

Yes, it would be!  And that is precisely why this is a bug!  GG not matching HH is a problem.
GG and HH should be identical, the compiler should to math exactly the same way as an executing program, otherwise it's a mess.

The computation SHOULD always be done at maximum precision, and that's the way it used to work before this: 
https://wiki.freepascal.org/User_Changes_2.2.0#Floating_point_constants
"Old behaviour: all floating point constants were considered to be of the highest precision available on the target platform"
This is the correct way that guarantees precision. 

"New behaviour: floating point constants are now considered to be of the lowest precision which doesn't cause data loss"
This is GREAT if you can pull it off in a way that doesn't cause data loss in ANY condition.   I believe this bug can be fixed and we can have efficiency and guaranteed no data loss, and then the "Effect" and "Remedy" below would not be needed...
But if it's not possible to guarantee no data loss, and the "Effect" is still a possibility, then this entire thing should be an OPTION.

" Effect: some expressions, in particular divisions of integer values by floating point constants, may now default to a lower precision than in the past. "  
What????  This IS data loss!!!  This precisely describes the BUG.  This is the reason this should NEVER have been made the default for everyone,  it should have required a compiler directive to turn on this behavior.  This lower precision is in direct violation of the 'New behavior' statement!
There is NO reason why anyone writing a Pascal program would expect this behavior.  It's NOT the way Pascal has EVER behaved.

" Remedy: if more precision is required than the default, typecast the floating point constant to a higher precision type, e.g. extended(2.0). Alternatively, you can use the -CF command line option to change the default precision of all floating point constants in the compiled modules. "
This is unreasonable.  How is anyone supposed to know that now to get it to work correctly as it should work, we need to cast out constants, old code should work the way it always did, and people writing new code will NEVER expect this needs to be done.
On top of that the -CF option only works for -CF32 and -CF64 so its no solution for Extended.. why do I need a special option to do things correctly?'

How about this.. if one variable is defined as a Double or Extended, then shut this 'feature' off, because it's asking for trouble.   Nobody uses Doubles or Extended in a program because they want low precision results.


James




More information about the fpc-pascal mailing list