3

I need to format numbers with commas as thousand seperators, for example:

1234 = 1,234
1234.50 = 1,234.50
12345.60 = 12,345.60
123456.70 = 123,456.70
1234567.80 = 1,234,567.80
etc etc

This needs to work for numbers with decimal values or without i.e. both 1234567.80 and 1234567

This is for Actionscript 2 in a Coldfusion / Flash application, so normal actionscript is being used. I have seen a couple of solutions on the net but none quite do the trick.

So far I have the function below, but it is not formatting correctly when decimals are provided.For example: 21898.5 becomes 2,188,8.5.

Please could you help me find the bug or offer an alternative solution that fulfils the requriements. Thanks

_global.NumberFormat = function(theNumber)
        {
            var myArray:Array;
            var numberPart:String;
            var decPart:String;
            var result:String = '';
            var numString:String = theNumber.toString();

            if(theNumber.indexOf('.') > 0)
            {
                myArray = theNumber.split('.');
                numberPart = myArray[0];
                decPart = myArray[1];
            }
            else
            {
                numberPart = numString;
            }

            while (numString.length > 3)
            {
                var chunk:String = numString.substr(-3);
                numString = numString.substr(0, numString.length - 3);
                result = ',' + chunk + result;
            }   
            if (numString.length > 0)
            {
                    result = numString + result;
            }   

            if(theNumber.indexOf('.') > 0)
            {
                result = result + '.' + decPart;
            }


            //alert('Result: ' + result);

            return result;
        }
Paolo Broccardo
  • 1,942
  • 6
  • 34
  • 51

3 Answers3

3

You could try this:

_global.NumberFormat = function(numString)
{
    numString = String(numString);
    var index:Number = numString.indexOf('.');
    var decimal:String;
    if(index > 0) {
        var splitByDecimal:Array = numString.split(".");
        //return NumberFormat(splitByDecimal[0])+"."+splitByDecimal[1];
        numString = splitByDecimal[0];
        decimal = splitByDecimal[1];
    } else if(index === 0) {
        return "0"+numString;
    }
    var result:String = '';
    while (numString.length > 3 ) {
        var chunk:String = numString.substr(-3);
        numString = numString.substr(0, numString.length - 3);
        result = ',' + chunk + result;
    }
    result = numString + result;
    if(decimal) result = result + "." + decimal;
    return result;
}

It splits the number by the decimal if present(compensating for an illegal '.01234' if required), and uses recursion so call itself on the split element.

For your example numbers this traces:

1,234
1,234.50
12,345.60
123,456.70
1,234,567.80

Just for fun

This is why your original code didn't work:

  1. After creating a string representation of the number (var numString:String = theNumber.toString();) you then carried on using the actual number rather than the string version.
  2. After assigning a value to number part you then continued to perform operations on numString rather than numberPart.

A corrected version looks like this:

_global.NumberFormat = function(theNumber)
{
    var myArray:Array;
    var numberPart:String;
    var decPart:String;
    var result:String = '';
    var numString:String = theNumber.toString();

    if(numString.indexOf('.') > 0)
    {
        myArray = numString.split('.');
        numberPart = myArray[0];
        decPart = myArray[1];
    }
    else
    {
        numberPart = numString;
    }

    while (numberPart.length > 3)
    {
        var chunk:String = numberPart.substr(-3);
        numberPart = numberPart.substr(0, numberPart.length - 3);
        result = ',' + chunk + result;
    }   
    if (numberPart.length > 0)
    {
        result = numberPart + result;
    }   

    if(numString.indexOf('.') > 0)
    {
        result = result + '.' + decPart;
    }


    //alert('Result: ' + result);

    return result;
}
shanethehat
  • 15,460
  • 11
  • 57
  • 87
  • Thanks - unfortunately that does not compile either. – Paolo Broccardo Nov 14 '11 at 14:20
  • It's working fine for me in CS4/AS2/FP8. Can you give some more details about your setup and what compile error you're receiving? – shanethehat Nov 14 '11 at 14:30
  • @Cheeky - I've amended to use your preferred declaration style. This also required changing the name of the recursive function call, which you may have missed. – shanethehat Nov 14 '11 at 14:33
  • Thanks - I have tried again and again there are errors. I am running a Coldfusion 9 page that uses cfform, which uses flash and can be manipulated with actionscript2. Therefore I do not get any information when there is a compile error other than it just doesn't display the form. What I have been able to determine are the problem lines by commenting them out: `_global.NumberFormat = function (numString:String):String` has to be `_global.NumberFormat = function (numString)` or it does not compile. – Paolo Broccardo Nov 14 '11 at 14:57
  • Also the line `return NumberFormat(splitByDecimal[0])+"."+splitByDecimal[1];` is erroring, presumably because I had to change the function declaration the way I detailed in my last comment to get the function to work. – Paolo Broccardo Nov 14 '11 at 14:58
  • I've made the changes you described, and removed the use of recursion. Hopefully that'll do the job now. – shanethehat Nov 14 '11 at 15:23
  • Thanks again, but unfortunately the function doesn't do anything now. It sends back the same number (e.g. 1234, 12345) without any commas. – Paolo Broccardo Nov 14 '11 at 15:37
  • @cheeky - I've managed to recreate your error by offering the function numbers instead of strings, which I guess your form must also be doing.. I've updated my answer to cast the incoming data as a string. – shanethehat Nov 14 '11 at 17:50
0
public static function formatNumberString(value:Number,separator:String):String {
var result:String = "";
var digitsCount:Number = value.toString().length;

separator = separator || ",";

for (var i:Number = 0; i < digitsCount; i++) {
  if ((digitsCount - i) % 3 == 0 && i != 0) {
    result += separator;
  }
    result += value.toString().charAt(i);
  }
  return result;
}
Reijii
  • 49
  • 3
-1

Try this out, works fine for me:

var largeNumber:String=new String(1000000.999777);
var fAr:Array=largeNumber.split(".");
var reg:RegExp=/\d{1,3}(?=(\d{3})+(?!\d))/;

while(reg.test(fAr[0]))
fAr[0]=fAr[0].replace(reg,"$&,");
var res:String=fAr.join(".");
trace(res);

Trace: 1,000,000.999777