Reputation: 826
while building an accounting system, I came across a major problem. Let's say I do an invoice and then, I have to apply a credit with the same amount as a negative value, I sometimes have a rounding problem of 1¢..
My problem is regarding negative values only!
Let's have a look at this script that is testing a specific positive and negative value. For debugging purpose, I also send the parameter expectedResult ;
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="creationCompleteHandler()">
<fx:Script>
<![CDATA[
import mx.formatters.CurrencyFormatter;
import mx.formatters.NumberBaseRoundType;
private function roundDecimal(num:Number, expectedResult:Number):void
{
var rnd:CurrencyFormatter = new CurrencyFormatter();
rnd.precision = 2;
rnd.useThousandsSeparator = false;
rnd.currencySymbol = '';
if (num >= 0)
rnd.rounding = NumberBaseRoundType.NEAREST;
else
rnd.rounding = NumberBaseRoundType.DOWN; // The problem is here, ALWAYS!
var result:Number = Number(rnd.format(num));
if (result != expectedResult)
trace("Error : " + result + " (Expecting " + expectedResult + ")");
else
trace("OK : " + result);
}
protected function creationCompleteHandler():void
{
var num:Number;
var expectedResult:Number;
// Test number 1
num = 5.653;
expectedResult = 5.65;
roundDecimal(num, expectedResult);
roundDecimal(-(num), -(expectedResult));
trace("------------");
// Test number 2
num = 5.655;
expectedResult = 5.66;
roundDecimal(num, expectedResult);
roundDecimal(-(num), -(expectedResult));
trace("------------");
// Test number 3
num = 5.657;
expectedResult = 5.66;
roundDecimal(num, expectedResult);
roundDecimal(-(num), -(expectedResult));
}
]]>
</fx:Script>
</s:WindowedApplication>
Of course I tried to modify the rounding type for negative values, without success..
Have a look at the different rounding types and their results :
//////////// Test 1 ////////////
if (num >= 0)
rnd.rounding = NumberBaseRoundType.NEAREST;
else
rnd.rounding = NumberBaseRoundType.DOWN; // The problem is here, ALWAYS!
OK : 5.65
Error : -5.66 (Expecting -5.65)
------------
OK : 5.66
OK : -5.66
------------
OK : 5.66
OK : -5.66
//////////// Test 2 ////////////
if (num >= 0)
rnd.rounding = NumberBaseRoundType.NEAREST;
else
rnd.rounding = NumberBaseRoundType.UP;
OK : 5.65
OK : -5.65
------------
OK : 5.66
Error : -5.65 (Expecting -5.66)
------------
OK : 5.66
Error : -5.65 (Expecting -5.66)
//////////// Test 3 ////////////
if (num >= 0)
rnd.rounding = NumberBaseRoundType.NEAREST;
else
rnd.rounding = NumberBaseRoundType.NEAREST; // The problem is here, ALWAYS!
OK : 5.65
OK : -5.65
------------
OK : 5.66
Error : -5.65 (Expecting -5.66)
------------
OK : 5.66
OK : -5.66
I'm really stuck here and would appreciate some help.. Thanks a lot!!
Upvotes: 1
Views: 396
Reputation: 1189
Check to see if it's positive or negative and assign a sign to a var (1 or -1), take the absolute value ( Math.abs(value)) and round that. Then multiply it by the sign to get the result.
That way you always get the same result and the whether it is positive or negative doesn't matter.
Upvotes: 1
Reputation: 18747
You are actually expecting the rounding to provide opposite results for negative values than you want for positive. A simple measure would be rounding DOWN for positive values and UP for negative. (Or up for positive and down for negative, valid too). The trick is, NEAREST always rounds up if the value is right in the middle of two possible rounding outcomes, and you want it to round down negative numbers only.
Upvotes: 0