The Round function with a double argument does not consistently
round correctly
Symptom
Customer is using the PowerBuilder Round function with a Double
datatype argument, sometimes it rounds correctly and sometimes it does
not.
Environment
PowerBuilder
Reproducing the Issue
Using the following sample code, the result is not consistent for
the double values entered.
|
1 2 3 4 5 6 7 |
double d_num1,d_num2 decimal new_dnum1, new_dnum2 d_num1 = 2.135 d_num2 = 3.135 new_dnum1 = Round(d_num1,2) new_dnum2 = Round(d_num2,2) Messagebox("Double Datatype Results of Rounding", "2.135 rounded to two decimal places = " +string(new_dnum1) + "~n~r" + "3.135 rounded to two decimal places = " + string(new_dnum2) ) |

Cause
This is not a PowerBuilder bug, it is expected behavior. The PB
Round function is returning a decimal. To assure that you are getting
the correct rounded value, use an argument with a decimal
datatype.
Double and Decimal datatypes have different internal formats to
store numbers. A PB Double datatype is an approximate numeric datatype
and is subject to rounding errors after arithmetic operations. A PB
Decimal data type is an exact numeric datatype. Only exact numeric data
types are guaranteed to be accurate to the least significant digit
specified after arithmetic operations. A Decimal datatype is a fixed
point number. It is designed for financial calculation and should be
used when accuracy is required such as in financial fields. In this
specific case, where you are using the PB Round function, you should
always use a decimal datatype argument to assure an accurate rounded
value returned from the function.
This same behavior can be seen in other programming languages. As
an example, this same behavior can be seen when passing a Double to the
Math.Round(Double, Int32) method in a C# or VB application.
Solution
You should always pass a decimal datatype to the PB Round()
function. If you need to round a double value, you can use the code
below to cast it first to a string and then to a decimal.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
double d_num1,d_num2 string s_num1, s_num2 decimal new_dnum1, new_dnum2, dec_num1, dec_num2 d_num1 = 2.135 d_num2 = 3.135 s_num1 = string(d_num1) s_num2 = string(d_num2) dec_num1 = Dec(s_num1) dec_num2 = Dec(s_num2) new_dnum1 = Round(dec_num1,2) new_dnum2 = Round(dec_num2,2) Messagebox("Double Cast to String and Then to Decimal Results of Rounding", "2.135 rounded to two decimal places = " + string(new_dnum1) + "~n~r" + "3.135 rounded to two decimal places = " + string(new_dnum2) ) |
