The following code rounds correctly when #AMT is positive, but not when it’s negative:
DEFINE DATA LOCAL
1 #AMT (P7.2)
1 #PCT (P3.2)
1 #TMP (P7.2)
1 #RESULT (P7.2)
1 #TYPE (A23)
END-DEFINE
ASSIGN #PCT = 50
WRITE TITLE LEFT JUSTIFIED
'0.10 + (-0.07 * 50 / 100):' /
'Correct answer is 0.06, or 0.14 if +0.07 used instead'
MOVE 'Neg w/ round, COMPUTE' TO #TYPE
ASSIGN #AMT = -0.07
ASSIGN #RESULT = 0.1
COMPUTE ROUNDED #RESULT = #RESULT + (#AMT * #PCT / 100) /*No rounding on expression in parenthesis!
DISPLAY #TYPE #AMT #PCT #RESULT
MOVE 'Pos w/ round, COMPUTE' TO #TYPE
ASSIGN #AMT = 0.07
ASSIGN #RESULT = 0.1
COMPUTE ROUNDED #RESULT = #RESULT + (#AMT * #PCT / 100) /*Expression in parenthesis is rounded!
DISPLAY #TYPE #AMT #PCT #RESULT
END
If the expression is simpler, with no parenthesis, then rounding of negative numbers is correct:
MOVE 'Neg w/ round, ADD' TO #TYPE
ASSIGN #AMT = -0.07
ASSIGN #RESULT = 0.1
COMPUTE ROUNDED #TMP = #AMT * #PCT / 100
ADD #TMP TO #RESULT
DISPLAY #TYPE #AMT #PCT #RESULT
Is this a bug in Natural, or am I not understanding some rule about intermediate results?
We’re running Natural 8.3.7 on AIX 6.1.
Thanks,
Loren Bergeson
Hi Lars,
I believe this is a simple case of arithmetic. Keep in mind that the ‘Compute Rounded’ statement applies to the entire expression that you are evaluating, rather than to each element, regardless of the use of parenthesis within that expression.
So in your case, the answer is correct, as you are asking to have the full statement rounded ( 0.1 + -0.035 = 0.065 = 0.07).
In the documentation for the ‘Rounded’ option, it states: “the last position of the result will be rounded up if the first truncated decimal position of the value being assigned contains a value greater than or equal to 5.” This is still true for negative values, where you will be ‘rounding away from zero’ to the next value based on the truncated decimal.
Thanks, don’t know why I couldn’t see that myself – it makes sense that the rounding doesn’t happen until the entire expression is evaluated.
You probably weren’t thinking of the rules in place for floating point division.
For example, normally when a 7.2 field is divided, the resultant values are truncated beyond the explicit operands in use.
Dividend / Divisor = Result
If Dividend is P7.2, Divisor is P3 and Result is P7.2, the calculation will be performed internally in floating point and the values assigned to result will be truncated to the second decimal point.
In the case of ‘Compute Rounded’, the internal precision of the entire result expression is increased by one digit before the result is rounded. So, all of the variables assigned in your expression (as P7.2) are actually calculated as P7.3 until the rounding takes place.
If, instead of adding the extra digit of precision, truncation were to occur (such as the addition calculation of two P7.2 with no ‘Rounded’ option) your example above would be:
0.1 + -0.07 / 2 = 0.1 + -0.03 = 0.07, which given the similarity between this truncation and the true rounded result makes the calculation ambiguous to an uninformed observer.