How Delphi rounds a currency during multiplication

rate : Currency;
mod1 : Currency;
mod2 : Currency;
mod_rate : Currency;

rate := 29.90;
mod1 := 0.95;
mod2 := 1.39;

mod_rate := rate * mod1 * mod2;

If you perform this calculation in a calculator, you will get a value 39.45295. Since the Delphi data type Currencyis accurate to only 4 decimal places, it internally rounds the value. My testing shows that it uses Banker rounding, so mod_rate should contain a value 39.4530, however in this particular case it is truncated to 39.4529.

I have 40,000 of these calculations, and all of them are correct, except for the above. Here is an example that rounds:

rate := 32.25;
mod1 := 0.90;
mod2 := 1.15;

This is equal 33.37875on the calculator and according to rounding, Banker will go up to 33.3788what Delphi does.

Can someone shed light on what Delphi is doing here?

+4
1

Currency fpu , 64- .

, . 39.45295 : ?

39,45295 = + 39,45294 99999 99999 99845 67899 95771 03240 88111 51981 35375 97656 25

39.45295, .

, .


, fpu Currency, :

mod_rate := rate * mod1 * mod2;
0041D566 DF2D20584200     fild qword ptr [$00425820]
0041D56C DF2D28584200     fild qword ptr [$00425828]
0041D572 DEC9             fmulp st(1)
0041D574 DF2D30584200     fild qword ptr [$00425830]
0041D57A DEC9             fmulp st(1)
0041D57C D835C4D54100     fdiv dword ptr [$0041d5c4]
0041D582 DF3D38584200     fistp qword ptr [$00425838]
0041D588 9B               wait 

fmulp fdiv . , fimul fidiv.

+8

Source: https://habr.com/ru/post/1656413/


All Articles