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!!
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.