Hi all,
After I investigated CCR below, I found an rounding issue. The issue is, we can get different result
Between Linux and Windows platform when we do the decimal rounding with string format or print
function.
Refer to the screenshots first.
Pic1 Windows program and result.
Pic1 Windows program and result.
Pic2 & PIC3 Linux program and result
Pic2 Linux Program
Pic3 Linux Result
I use the same simple program on Linux and Windows to describe this situation.
On Windows, from Pic1, the variables is
D3 = 37.114500000000000 D3 = 37.115
D4 = 37.113500000000002 result d4 = 37.114
d5 = 37.116500000000002 d5 = 37.117
On Linux, from Pic2, the variables is
D3 = 37.114500000000000 D3 = 37.114
D4 = 37.113500000000002 result d4 = 37.114
d5 = 37.116500000000002 d5 = 37.117
The apparent difference is the value of D3 in result. This was also the behavior of this CCR.
After searching Google, I find the reason are the different algorithm used in Linux and Windows when doing the decimal Roun Ding.
On Windows, decimal rounding uses the common rounding off. However, on Linux, it uses the banking rounding.
Decimal rounding takes different algorithm principle between GNU C library in Linux and CRT library in Windows.
Refer to the explanation as below.
Common Method (Windows C + + used)
This method was commonly used in mathematical applications and for example in accounting. It's the one generally taught in elementary mathematics classes. This method is also known as asymmetric arithmetic rounding or round-half-up (asymmetric implementation)
1. Divide it by the unit to which it was to be rounded
2. Round it to the nearest whole number, unless it ends in exactly. 5
3. If it ends in exactly. 5 and then add 0.5
4. Multiply it by the unit to which it was to be rounded
Examples (rounded to hundredths):
- 3.0448→304.48→304→3.04
- 3.0450→304.50→305→3.05 matched (D3)
- 3.0452→304.52→305→3.05 matched (D5)
- -3.0448→-304.48→-304→-3.04
- -3.0450→-304.50→-304→-3.04
- -3.0452→-304.52→-305→-3.05
As the name implies, this can introduce a bias:if all the unrounded numbers had four decimal places, say, then in our Exa Mple the expected average of the rounded numbers would be 0.0005 higher than that of the unrounded numbers.
Round-to-even method (Linux/C + + used)
This method, also known as unbiased rounding , convergent rounding , Statistician ' s rounding , Dutch rounding , Gaussian rounding , or bankers ' Rounding , exactly replicates the common method of rounding except when the digit (s) following the rounding digit star TS with a five and have no non-zero digits after it.
Despite the custom of rounding the number 4.5 up to 5, in fact 4.5 was no nearer to 5 than it's to 4 (it's 0.5 away from both). When dealing with large sets of scientific or statistical data, where trends is important, traditional rounding on Averag e biases the data upwards slightly. Over a large set of data, or when many subsequent rounding operations is performed as in digital signal processing, the R Ound-to-even rule tends to reduce the total rounding error, with (on average) a equal portion of numbers rounding up as R Ounding down. This generally reduces upwards skewing of the result.
The new algorithm becomes (only rule 3. Changes):
1. Divide it by the unit to which it was to be rounded
2. Round it to the nearest whole number, unless it ends in exactly. 5
3. If it ends in exactly. 5, then round towards the nearest even whole number
4. Multiply it by the unit to which it was to be rounded
Examples (rounded to hundredths):
- 3.0448→304.48→304→3.04
- 3.0450→304.50→304→3.04 matched (D3)
- 3.0452→304.52→305→3.05 matched (D5)
- -3.0448→-304.48→-304→-3.04
- -3.0450→-304.50→-304→-3.04
- -3.0452→-304.52→-305→-3.05
More details, refer to
<1> http://www.cnblogs.com/samcn/archive/2009/06/05/1497094.html
<2> https://zh.wikipedia.org/wiki/%E6%95%B0%E5%80%BC%E4%BF%AE%E7%BA%A6
<3> Https://en.wikipedia.org/wiki/Rounding#Round_half_to_even
There is a switch for Linux to decide which kind of rounding used when programming.
Banking rounding for Decimal rounding off on Linux