{"id":1363,"date":"2014-03-29T16:54:58","date_gmt":"2014-03-29T16:54:58","guid":{"rendered":"http:\/\/joelinoff.com\/blog\/?p=1363"},"modified":"2014-03-29T16:54:58","modified_gmt":"2014-03-29T16:54:58","slug":"simple-algorithm-to-insert-commas-commaize-in-9-languages","status":"publish","type":"post","link":"https:\/\/joelinoff.com\/blog\/?p=1363","title":{"rendered":"Simple algorithm to insert commas (commaize) in 9 languages"},"content":{"rendered":"<p><a name=\"top\"><\/a><br \/>\nThis project contains nine different language implementations of a simple algorithm named &#8220;commaize&#8221; that inserts commas into a number. The languages are: bash, c++, java, javascript, perl, php, python, ruby and tcl. My hope is that it will be a useful reference.<br \/>\n<!--more--><\/p>\n<h1>Contents<\/h1>\n<ol>\n<li><a href=\"#intro\">Introduction<\/a><\/li>\n<li><a href=\"#downloads\">Downloads<\/a><\/li>\n<li><a href=\"#files\">Download Files<\/a><\/li>\n<li><a href=\"#installation\">Installation<\/a><\/li>\n<li><a href=\"#impbash\">Bash Implementation<\/a><\/li>\n<li><a href=\"#impgxx\">C++ Implementation<\/a><\/li>\n<li><a href=\"#impjava\">Java Implementation<\/a><\/li>\n<li><a href=\"#impjs\">Javascript Implementation<\/a><\/li>\n<li><a href=\"#impperl\">Perl Implementation<\/a><\/li>\n<li><a href=\"#impphp\">PHP Implementation<\/a><\/li>\n<li><a href=\"#imppython\">Python Implementation<\/a><\/li>\n<li><a href=\"#impruby\">Ruby Implementation<\/a><\/li>\n<li><a href=\"#imptcl\">Tcl Implementation<\/a><\/li>\n<li><a href=\"#platforms\">Tested Platforms<\/a><\/li>\n<li><a href=\"#license\">License<\/a><\/li>\n<\/ol>\n<p><a name=\"intro\"><\/a><\/p>\n<h1>Introduction<\/h1>\n<p>I created it because I sometimes have to work on code written in a variety of languages. Having an example like this is really helpful as a reference for languages that I rarely use (like tcl). Note that because these implementations are meant to act as a reference, they are not optimized.<\/p>\n<p>This project contains the algorithm coded in complete standalone programs. Each program prints a similar list of formatted data in 3 columns. The first column is the test number, the second is the language specific format of the input and the third column is the output. That third column must be identical for all programs. In some cases there is a fourth column to remind me of what the row is for. This is what the output looks like for the python implementation (commaize.py):<\/p>\n<pre>\r\n$ .\/commaize.py\r\n   1                    1                     1\r\n   2                   12                    12\r\n   3                  123                   123\r\n   4                 1234                 1,234\r\n   5                12345                12,345\r\n   6               123456               123,456\r\n   7              1234567             1,234,567\r\n   8             12345678            12,345,678\r\n   9            123456789           123,456,789\r\n  10                 1.23                  1.23\r\n  11                12.34                 12.34\r\n  12               123.45                123.45\r\n  13              1234.56              1,234.56\r\n  14             12345.67             12,345.67\r\n  15            123456.78            123,456.78\r\n  16           1234567.89          1,234,567.89\r\n  17           12345678.9          12,345,678.9\r\n  18                  1.0                     1\r\n  19                   -1                    -1\r\n  20                  -12                   -12\r\n  21                 -123                  -123\r\n  22                -1234                -1,234\r\n  23               -12345               -12,345\r\n  24              -123456              -123,456\r\n  25             -1234567            -1,234,567\r\n  26            -12345678           -12,345,678\r\n  27           -123456789          -123,456,789\r\n  28                -1.23                 -1.23\r\n  29               -12.34                -12.34\r\n  30              -123.45               -123.45\r\n  31             -1234.56             -1,234.56\r\n  32            -12345.67            -12,345.67\r\n  33           -123456.78           -123,456.78\r\n  34          -1234567.89         -1,234,567.89\r\n  35          -12345678.9         -12,345,678.9\r\n  36                 -1.0                    -1\r\n  37            123456789           123,456,789\r\n  38           12345678,9          12.345.678,9  # EU style\r\n  39            12345.123             12,345.12  # 2 decimal places\r\n  40                12345             12,345.00  # 2 decimal places\r\n  41           12345.1251             12,345.13  # 2 decimal places\r\n  42           1234567.89           1,234,567.9  # 1 decimal place\r\n<\/pre>\n<p>Note that there are two compiled languages: c++ and java so there is a Makefile that will run the compilations. You will have to edit it to pick up the correct compiler. When you do you will see that I used gcc-4.8.2 installed locally on my Mac as described here: <a href=\"http:\/\/joelinoff.com\/blog\/?p=1003\">http:\/\/joelinoff.com\/blog\/?p=1003<\/a> because I wanted the latest C++-11 features.<\/p>\n<p>The javascript implementation requires browser rendering so it has an associated commaize.html file.<\/p>\n<p>All of the source code is freely available based on the MIT license. See the LICENSE.txt file for details.<\/p>\n<p><a name=\"downloads\"><\/a><\/p>\n<h1><a href=\"#top\">&uarr;<\/a> Downloads<\/h1>\n<p>All of the implementations are available to download. There are three archive formats: tar.bz2, tar.gz and zip. <\/p>\n<table>\n<thead>\n<tr>\n<th>File<\/th>\n<th>Size<\/th>\n<th>Checksum<\/th>\n<th>Extract Command<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td align=\"left\">\n   <a href=\"http:\/\/projects.joelinoff.com\/commaize\/commaize.tar.bz2\">commaize.tar.bz2<\/a>\n  <\/td>\n<td align=\"RIGHT\">13K<\/td>\n<td align=\"RIGHT\">60400<\/td>\n<td align=\"left\">\n  <code>tar jxf commaize.tar.bz2<\/code>\n  <\/td>\n<\/tr>\n<tr>\n<td align=\"left\">\n   <a href=\"http:\/\/projects.joelinoff.com\/commaize\/commaize.tar.gz\">commaize.tar.gz<\/a>\n  <\/td>\n<td align=\"RIGHT\">14K<\/td>\n<td align=\"RIGHT\">5113<\/td>\n<td align=\"left\">\n  <code>tar zxf commaize.tar.gz<\/code>\n  <\/td>\n<\/tr>\n<tr>\n<td align=\"left\">\n   <a href=\"http:\/\/projects.joelinoff.com\/commaize\/commaize.zip\">commaize.zip<\/a>\n  <\/td>\n<td align=\"RIGHT\">21K<\/td>\n<td align=\"RIGHT\">54782<\/td>\n<td align=\"left\">\n  <code>unzip commaize.zip<\/code>\n  <\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><a name=\"files\"><\/a><\/p>\n<h1><a href=\"#top\">&uarr;<\/a> Download Files<\/h1>\n<p>The archives contain the following files in a local commaize directory.<\/p>\n<table>\n<thead>\n<tr>\n<th>File<\/th>\n<th>Description<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td align=\"LEFT\">commaize.html<\/td>\n<td align=\"LEFT\">HTML file that references commaize.js.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\">commaize.cc<\/td>\n<td align=\"LEFT\">The C++ implementation. Uses some features from C++11.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\">commaize.java<\/td>\n<td align=\"LEFT\">The java (1.6) implementation.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\">commaize.js<\/td>\n<td align=\"LEFT\">The javascript implementation.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\">commaize.pl<\/td>\n<td align=\"LEFT\">The perl (5.12) implementation.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\">commaize.php<\/td>\n<td align=\"LEFT\">The php (5.4) implementation.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\">commaize.py<\/td>\n<td align=\"LEFT\">The python (2.7) implementation.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\">commaize.rb<\/td>\n<td align=\"LEFT\">The ruby (0.9.6, 1.8.7) implementation.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\">commaize.sh<\/td>\n<td align=\"LEFT\">The bash implementation.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\">commaize.tcl<\/td>\n<td align=\"LEFT\">The tcl (8.6) implementation.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\">golden.txt<\/td>\n<td align=\"LEFT\">The golden output for testing.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\">LICENSE.txt<\/td>\n<td align=\"LEFT\">The source code license information.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\">Makefile<\/td>\n<td align=\"LEFT\">Builds and tests the implementations. Here are some interesting targets.<\/p>\n<ol>\n<li>all &#8211; check, build and test<\/li>\n<li>build &#8211; build the executables for C++ and java<\/li>\n<li>check &#8211; check the language compilers\/interpreters<\/li>\n<li>clean &#8211; clean up<\/li>\n<li>test &#8211; run the tests<\/li>\n<\/ol>\n<p>    You will need to modify this file for your environment.\n   <\/td>\n<tr>\n<td align=\"LEFT\">README.txt<\/td>\n<td align=\"LEFT\">Information about the project.<\/td>\n<\/tr>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><a name=\"installation\"><\/a><\/p>\n<h1><a href=\"#top\">&uarr;<\/a> Installation<\/h1>\n<p>The package is available in 3 formats: bzipped tar format, gzipped tar format and zip format. The following example shows how to download, install and run the project using the bzipped tar format.<\/p>\n<pre class=\"lang:default decode:true \" title=\"Installation Example\" >$ # Installation example.\r\n$ # There are three ways to download the project.\r\n$ wget http:\/\/projects.joelinoff.com\/commaize\/commaize.tar.bz2\r\n$ wget http:\/\/projects.joelinoff.com\/commaize\/commaize.tar.gz\r\n$ wget http:\/\/projects.joelinoff.com\/commaize\/commaize.zip\r\n\r\n$ # There are three ways to extract the project.\r\n$ tar jxf commaize.tar.bz2\r\n$ #tar zxf commaize.tar.gz\r\n$ #unzip commaize.zip\r\n\r\n$ # Here is the basic recipe but note that you MUST edit the\r\n$ # Makefile to point to the correct local c++ compiler.\r\n$ cd commaize\r\n$ edit Makefile  # change the GXX compiler references\r\n$ make\r\n  [output snipped]\r\n  # ================================================================\r\n  # test\r\n  # ================================================================\r\n    1  test-commaize.class.out          passed\r\n    2  test-commaize.exe.out            passed\r\n    3  test-commaize.php.out            passed\r\n    4  test-commaize.pl.out             passed\r\n    5  test-commaize.py.out             passed\r\n    6  test-commaize.rb.out             passed\r\n    7  test-commaize.sh.out             passed\r\n    8  test-commaize.tcl.out            passed\r\n  \r\n  TOTAL:      8\r\n  PASSED:     8\r\n  FAILED:     0<\/pre>\n<p><a name=\"impbash\"><\/a><\/p>\n<h1><a href=\"#top\">&uarr;<\/a> Bash Implementation<\/h1>\n<p>This is the bash implementation.<\/p>\n<pre class=\"lang:default decode:true \" title=\"Bash Implementation\" >#!\/bin\/bash\r\n\r\n#\r\n# Insert thousands separator into a number and, optionally, specify\r\n# the number of decimal places.\r\n#\r\n# Here are some examples that demonstrate how it is used.\r\n#\r\n#    x=$(commaize 1234)                      # 1,234\r\n#    x=$(commaize -1234)                     # -1,234\r\n#    x=$(commaize 12345.678)                 # 12,345.678\r\n#    x=$(commaize -12345.678)                # -12,345.678\r\n#    x=$(commaize 12345.678 2)               # 12,345.69\r\n#    x=$(commaize 12345.678 1)               # 12,345.7\r\n#    x=$(commaize 1234 -1 \".\")               # 1.234\r\n#    x=$(commaize \"1234567,89\" -1 \".\" \",\")   # EU format: 1.234.567,89\r\n#\r\n# The arguments are:\r\n#\r\n#   $1 == number\r\n#   $2 == decimal places (default: -1 -> do nothing)\r\n#   $3 == thousands separator (default: \",\")\r\n#   $4 == decimal point (default: \".\")\r\n#\r\nfunction commaize() {\r\n    local num=\"$1\"\r\n    local dpl=-1\r\n    local sep=\",\"\r\n    local dpt=\".\"\r\n    if [[ \"$2\" != \"\" ]] ; then dpl=$2 ; fi\r\n    if [[ \"$3\" != \"\" ]] ; then sep=\"$3\" ; fi\r\n    if [[ \"$4\" != \"\" ]] ; then dpt=\"$4\" ; fi\r\n\r\n    if (( $dpl >= 0 )) ; then\r\n        fmt=\"%.${dpl}f\"\r\n        num=$(printf \"$fmt\" $num)\r\n    fi\r\n\r\n    local neg=\"\"\r\n    if [[ \"${num:0:1}\" == \"-\" ]] ; then\r\n        neg=\"-\"\r\n        # Strip off the leading minus sign.\r\n        numl=$((${#num} - 1))\r\n        num=${num:1:$numl}\r\n    fi\r\n\r\n    local parts=($(echo \"$num\" | tr \"$dpt\" \"\\n\"))\r\n    local nparts=${#parts[@]}\r\n    if (( $nparts > 2 )) ; then\r\n        echo \"ERROR: invalid string: $num\"\r\n        exit 1\r\n    fi\r\n\r\n    # Insert the separators.\r\n    characteristic=${parts[0]}\r\n    result=''\r\n    j=$(( ${#characteristic} % 3 ))\r\n    for (( i=0; i<${#characteristic}; i++ )); do\r\n        k=$(( $i % 3))\r\n        if (( $k == $j )) &#038;&#038; (( $i > 0 )) ; then\r\n            result=\"$result$sep\"\r\n        fi\r\n        digit=${characteristic:$i:1}\r\n        result=\"$result$digit\"\r\n    done\r\n\r\n    # There was a decimal point, append\r\n    # the mantissa.\r\n    if (( $nparts == 2 )) ; then\r\n        mantissa=\"${parts[1]}\"\r\n        if (( $dpl < 0 )) ; then\r\n            # Strip off trailing zeros if dpl was not not specified.\r\n            # Convert 1.0 --> 1\r\n            mantissa=$(echo \"$mantissa\" | sed -e 's\/0$\/\/g')\r\n        fi\r\n        if (( ${#mantissa} > 0 )) ; then\r\n            result=\"$result$dpt$mantissa\"\r\n        fi\r\n    fi\r\n    echo \"$neg$result\"\r\n}\r\n\r\n# Main\r\nidx=0\r\ndata=(1 12 123 1234 12345 123456 1234567 12345678 123456789\r\n    1.23 12.34 123.45 1234.56 12345.67 123456.78 1234567.89 12345678.9\r\n    1.0\r\n    -1 -12 -123 -1234 -12345 -123456 -1234567 -12345678 -123456789\r\n    -1.23 -12.34 -123.45 -1234.56 -12345.67 -123456.78 -1234567.89 -12345678.9\r\n    -1.0\r\n    '123456789')\r\nfor datum in ${data[@]}; do\r\n    result=$(commaize $datum)\r\n    idx=$(($idx + 1))\r\n    printf \"%4d %20s  %20s\\n\" $idx $datum $result\r\ndone\r\n\r\ndatum=\"12345678,9\"\r\nresult=$(commaize $datum -1 '.' ',')\r\nidx=$(($idx + 1))\r\nprintf \"%4d %20s  %20s  # EU style\\n\" $idx $datum $result\r\n\r\ndata=(12345.123 12345 12345.1251)\r\nfor datum in ${data[@]}; do\r\n    result=$(commaize $datum 2)\r\n    idx=$(($idx + 1))\r\n    printf \"%4d %20s  %20s  # 2 decimal places\\n\" $idx $datum $result\r\ndone\r\n\r\ndatum=1234567.89\r\nresult=$(commaize $datum 1)\r\nidx=$(($idx + 1))\r\nprintf \"%4d %20s  %20s  # 1 decimal place\\n\" $idx $datum $result\r\n<\/pre>\n<p><a name=\"impgxx\"><\/a><\/p>\n<h1><a href=\"#top\">&uarr;<\/a> C++ Implementation<\/h1>\n<p>This is the C++ implementation. It uses C++-11 constructs so it will not work on platforms that do not have a recent C++ compiler. In my case I had to install an updated version of the C++ compiler to handle C++-11 constructs from <a href=\"http:\/\/joelinoff.com\/blog\/?p=1003\">http:\/\/joelinoff.com\/blog\/?p=1003<\/a>.<\/p>\n<p>This is how I compiled it.<\/p>\n<pre class=\"lang:sh decode:true \" title=\"Compile\" >$ # First install the compiler. The default is too old.\r\n$ # You can skip this step if you have newer version.\r\n$ cd ~\/work\r\n$ mkdir -p gcc\/4.8.2\r\n$ cd gcc\/4.8.2\r\n$ wget http:\/\/projects.joelinoff.com\/gcc-4.8.2.\/Makefile\r\n&lt;output snipped&gt;\r\n$ wget http:\/\/projects.joelinoff.com\/gcc-4.8.2.\/bld.sh\r\n&lt;output snipped&gt;\r\n$ make\r\n&lt;output snipped&gt;\r\n\r\n$ # Now compile your program.\r\n$ cd ~\/work\/commaize\r\n$ CXX_RTFDIR=~\/work\/gcc\/4.8.2\/rtf\r\n$ export PATH=\"${CXX_RTFDIR}\/bin:${PATH}\"\r\n$ export LD_LIBRARY_PATH=\"$(CXX_RTFDIR)\/lib:$(CXX_RTFDIR)\/lib64:${LD_LIBRARY_PATH}\"\r\n$ export LD_RUN_PATH=\"${CXX_RTFDIR}\/lib:${CXX_RTFDIR}\/lib64:${LD_LIBRARY_PATH}\"\r\n$ g++ --version  # make sure that you have the correct version\r\n&lt;output snipped&gt;\r\n$ g++ -g -Wall -std=c++11 -o commaize.exe commaize.cc\r\n&lt;output snipped&gt;\r\n\r\n$ # Run it.\r\n$ .\/commaize.exe\r\n&lt;output snipped&gt;<\/pre>\n<p>This is the source code.<\/p>\n<pre class=\"lang:c++ decode:true \" title=\"C++ Implementation\" >\/\/ ================================================================\r\n\/\/ Commaize a number.\r\n\/\/ ================================================================\r\n#include &lt;cstdlib&gt;\r\n#include &lt;string&gt;\r\n#include &lt;iostream&gt;\r\n#include &lt;iomanip&gt;\r\nusing namespace std;\r\n\r\ntemplate &lt;typename T&gt; string commaize_tostring(T in) {return to_string(in);}\r\nstring commaize_tostring(const string&amp; in) {return in;}\r\n\r\n\/**\r\n * Insert thousands separator into a number and, optionally, specify\r\n * the number of decimal places.\r\n * \r\n * Here are some examples that demonstrate how it is used.\r\n * \r\n *   string x;\r\n *   x=commaize(1234)                            # 1,234\r\n *   x=commaize(-1234)                           # -1,234\r\n *   x=commaize(12345.678)                       # 12,345.678\r\n *   x=commaize(-12345.678)                      # -12,345.678\r\n *   x=commaize(12345.678, dpl=2)                # 12,345.69\r\n *   x=commaize(12345.678, dpl=1)                # 12,345.7\r\n *   x=commaize(1234,sep='.')                    # 1.234\r\n *   x=commaize(\"1234567,89\", sep='.', dpt=',')  # EU: 1.234.567,89\r\n * \r\n * The arguments are:\r\n * \r\n * @param num  The number: int, float or string.\r\n * @param dpl  Decimal places (default: -1 -&gt; do nothing).\r\n * @param sep  Thousands separator (default: \",\").\r\n * @param dpt  Decimal point (default: \".\").\r\n * @returns a formatted string.\r\n *\/\r\ntemplate &lt;typename T&gt;\r\nstring commaize(T num, int dpl=-1, char sep=',', char dpt='.')\r\n{\r\n  string characteristic = commaize_tostring(num);\r\n  if (dpl &gt;= 0) {\r\n    \/\/ Use sprintf() to do the rounding.\r\n    double val = atof(characteristic.c_str());\r\n    char fmt[128];\r\n    char tmp[128];\r\n    sprintf(fmt, \"%%.%df\", dpl);\r\n    sprintf(tmp, fmt, val);\r\n    characteristic = tmp;\r\n  }\r\n\r\n  string neg=\"\";\r\n  if (characteristic[0] == '-') {\r\n    neg = \"-\";\r\n    characteristic = characteristic.substr(1, string::npos);\r\n  }\r\n\r\n  string mantissa = \"\";\r\n  size_t pos = characteristic.find(dpt);\r\n  if (pos != string::npos) {\r\n    \/\/ There is a decimal point, break out\r\n    \/\/ the characteristic and the mantissa\r\n    \/\/ because we only care about the\r\n    \/\/ characteristic for commas. We will\r\n    \/\/ append the mantissa at the end.\r\n    mantissa = characteristic.substr(pos+1);\r\n\r\n    \/\/ Trim trailing zeros.\r\n    if (dpl &lt; 0) {\r\n      while (mantissa.size() &gt; 0 &amp;&amp; mantissa[mantissa.size()-1] == '0') {\r\n        mantissa = mantissa.substr(0, mantissa.size() - 1);\r\n      }\r\n    }\r\n    characteristic = characteristic.substr(0, pos);\r\n  }\r\n\r\n  \/\/ Insert the commas.\r\n  size_t j = characteristic.size() % 3;\r\n  string result = \"\";\r\n  result.reserve(characteristic.size() + ((characteristic.size()\/3) + 2 + mantissa.size()));\r\n  for(size_t i=0; i&lt;characteristic.size(); i++) {\r\n    if ((i%3) == j &amp;&amp; i &gt; 0) {\r\n      result += sep;\r\n    }\r\n    result += characteristic[i];\r\n  }\r\n  if (!mantissa.empty()) {\r\n    char dpts[2] = {dpt, 0};\r\n    result += string(dpts) + mantissa;\r\n  }\r\n  return neg + result;\r\n}\r\n\r\n\/**\r\n * main\r\n *\/\r\nint main()\r\n{\r\n  string result;\r\n  string str;\r\n  unsigned id = 0;\r\n\r\n  \/\/ Test positive integers.\r\n  size_t nums[] = {1, 12, 123, 1234, 12345, 123456, 1234567, 12345678, 123456789};\r\n  for(auto num : nums) {\r\n    result = commaize(num);\r\n    cout  &lt;&lt; setw(4) &lt;&lt; right &lt;&lt; ++id &lt;&lt; \" \"\r\n          &lt;&lt; right &lt;&lt; setw(20) &lt;&lt; num\r\n          &lt;&lt; \"   \"\r\n          &lt;&lt; right &lt;&lt; setw(20) &lt;&lt; result\r\n          &lt;&lt; endl;\r\n  }\r\n\r\n  \/\/ Test positive doubles.\r\n  double dnums[] = {1.23, 12.34, 123.45, 1234.56, 12345.67, 123456.78, 1234567.89, 12345678.9, 1.0};\r\n  for(auto dnum : dnums) {\r\n    result = commaize(dnum);\r\n    cout  &lt;&lt; setw(4) &lt;&lt; right &lt;&lt; ++id &lt;&lt; \" \"\r\n          &lt;&lt; right &lt;&lt; fixed &lt;&lt; setw(20) &lt;&lt; dnum\r\n          &lt;&lt; \"   \"\r\n          &lt;&lt; right &lt;&lt; setw(20) &lt;&lt; result\r\n          &lt;&lt; endl;\r\n  }\r\n\r\n  \/\/ Test negative integers.\r\n  for(long num: nums) {\r\n    num = -num;\r\n    result = commaize(num);\r\n    cout  &lt;&lt; setw(4) &lt;&lt; right &lt;&lt; ++id &lt;&lt; \" \"\r\n          &lt;&lt; right &lt;&lt; setw(20) &lt;&lt; num\r\n          &lt;&lt; \"   \"\r\n          &lt;&lt; right &lt;&lt; setw(20) &lt;&lt; result\r\n          &lt;&lt; endl;\r\n  }\r\n\r\n  \/\/ Test negative doubles.\r\n  for(auto num: dnums) {\r\n    num = -num;\r\n    result = commaize(num);\r\n    cout  &lt;&lt; setw(4) &lt;&lt; right &lt;&lt; ++id &lt;&lt; \" \"\r\n          &lt;&lt; right &lt;&lt; fixed &lt;&lt; setprecision(2) &lt;&lt; setw(20) &lt;&lt; num\r\n          &lt;&lt; \"   \"\r\n          &lt;&lt; right &lt;&lt; setw(20) &lt;&lt; result\r\n          &lt;&lt; endl;\r\n  }\r\n\r\n  \/\/ String test.\r\n  str = \"123456789\";\r\n  result = commaize(str);\r\n  cout  &lt;&lt; setw(4) &lt;&lt; right &lt;&lt; ++id &lt;&lt; \" \"\r\n        &lt;&lt; right &lt;&lt; setw(20) &lt;&lt; str\r\n        &lt;&lt; \"   \"\r\n        &lt;&lt; right &lt;&lt; setw(20) &lt;&lt; result\r\n        &lt;&lt; endl;\r\n\r\n  \/\/ EU style\r\n  str = \"12345678,9\";\r\n  result = commaize(str, -1, '.', ',');\r\n  cout  &lt;&lt; setw(4) &lt;&lt; right &lt;&lt; ++id &lt;&lt; \" \"\r\n        &lt;&lt; right &lt;&lt; fixed &lt;&lt; setprecision(2) &lt;&lt; setw(20) &lt;&lt; str\r\n        &lt;&lt; \"   \"\r\n        &lt;&lt; right &lt;&lt; setw(20) &lt;&lt; result\r\n        &lt;&lt; \"  # EU style\"\r\n        &lt;&lt; endl;\r\n\r\n  \/\/ dollarize\r\n  \/\/ Round to 2 significant digits.\r\n  double ddata[] = {12345.123, 12345, 12345.1251};\r\n  for(auto datum : ddata) {\r\n    result = commaize(datum, 2);\r\n    cout  &lt;&lt; setw(4) &lt;&lt; right &lt;&lt; ++id &lt;&lt; \" \"\r\n          &lt;&lt; right &lt;&lt; fixed &lt;&lt; setw(20) &lt;&lt; datum\r\n          &lt;&lt; \"   \"\r\n          &lt;&lt; right &lt;&lt; setw(20) &lt;&lt; result\r\n          &lt;&lt; \"  # 2 decimal places\"\r\n          &lt;&lt; endl;\r\n  }\r\n\r\n  \/\/ 1 decimal place.\r\n  string datum = \"1234567.89\";\r\n  result = commaize(datum, 1);\r\n  cout  &lt;&lt; setw(4) &lt;&lt; right &lt;&lt; ++id &lt;&lt; \" \"\r\n        &lt;&lt; right &lt;&lt; fixed &lt;&lt; setw(20) &lt;&lt; datum\r\n        &lt;&lt; \"   \"\r\n        &lt;&lt; right &lt;&lt; setw(20) &lt;&lt; result\r\n        &lt;&lt; \"  # 1 decimal place\"\r\n        &lt;&lt; endl;\r\n}<\/pre>\n<p><a name=\"impjava\"><\/a><\/p>\n<h1><a href=\"#top\">&uarr;<\/a> Java Implementation<\/h1>\n<p>This is the java implementation. You compile it as follows:<\/p>\n<pre class=\"lang:sh decode:true \" title=\"Compile\" >$ javac Commaize.java\r\n&lt;output snipped&gt;\r\n$ java Commaize\r\n&lt;output snipped&gt;<\/pre>\n<p>Here is the source code.<\/p>\n<pre class=\"lang:default decode:true \" title=\"Java Implementation\" >\/\/ Commaize a number.\r\nimport java.util.*;\r\n\r\npublic class Commaize {\r\n\r\n    \/**\r\n     * doubleToString\r\n     *\/\r\n    public static String doubleToString(double in) {\r\n        Double d = in;\r\n        int di = d.intValue();\r\n        if (d == di) {\r\n            \/\/ Optimization for easy floats.\r\n            return String.format(\"%d\", di);\r\n        }\r\n        \r\n        String floatnum = String.format(\"%f\", d);\r\n        \r\n        \/\/ Chop off trailing zeros.\r\n        int i = floatnum.length() - 1;\r\n        while (i >= 0 && floatnum.charAt(i) == '0') {\r\n            i--;\r\n        }\r\n        floatnum = floatnum.substring(0, i+1);\r\n        \r\n        \/\/ Chop off the period if there is no mantissa.\r\n        i = floatnum.length() - 1;\r\n        if (i >= 0 && floatnum.charAt(i) == '.') {\r\n            floatnum = floatnum.substring(0, i);\r\n        }\r\n        \r\n        return floatnum;\r\n    }\r\n    \r\n    \/**\r\n     * Insert thousands separator into a number and, optionally, specify\r\n     * the number of decimal places.\r\n     * \r\n     * Here are some examples that demonstrate how it is used.\r\n     * \r\n     *   string x;\r\n     *   x=commaize(1234)                        # 1,234\r\n     *   x=commaize(-1234)                       # -1,234\r\n     *   x=commaize(12345.678)                   # 12,345.678\r\n     *   x=commaize(-12345.678)                  # -12,345.678\r\n     *   x=commaize(12345.678, 2)                # 12,345.69\r\n     *   x=commaize(12345.678, 1)                # 12,345.7\r\n     *   x=commaize(1234, -1, '.')               # 1.234\r\n     *   x=commaize(\"1234567,89\", -1, '.', ',')  # EU: 1.234.567,89\r\n     * \r\n     * The arguments are:\r\n     * \r\n     * @param num  The number: int, float or string.\r\n     * @param dpl  Decimal places (default: -1 -> do nothing).\r\n     * @param sep  Thousands separator (default: \",\").\r\n     * @param dpt  Decimal point (default: \".\").\r\n     * @returns a formatted string.\r\n     *\/\r\n    public static <T> String commaize(T num, int dpl, char sep, char dpt) {\r\n        String rep = num.toString();\r\n        if (rep.indexOf('E') >= 0) {\r\n            rep = doubleToString(Double.parseDouble(rep));\r\n        }\r\n\r\n        if (dpl > 0) {\r\n            \/\/ Take advantage of built in rounding.\r\n            String fmt = String.format(\"%%.%df\", dpl);\r\n            double value = Double.parseDouble(rep);\r\n            rep = String.format(fmt, value);\r\n        }\r\n\r\n        \/\/ Get the parts of the number (characteristic and mantissa).\r\n        \/\/   123.45\r\n        \/\/   ^  ^^\r\n        \/\/   |  |+--- mantissa\r\n        \/\/   |  +---- decimal point\r\n        \/\/   +------- characteristic\r\n        String characteristic = \"\";\r\n        String mantissa = \"\";\r\n        boolean past_dpt = true;\r\n        for (int i=0; i<rep.length(); i++) {\r\n            char ch = rep.charAt(i);\r\n            if (ch == dpt) {\r\n                past_dpt = false;\r\n            }\r\n            if (past_dpt) {\r\n                characteristic += ch;\r\n            }\r\n            else {\r\n                mantissa += ch;\r\n            }\r\n        }\r\n\r\n        \/\/ Trim trailing zeros.\r\n        if (dpl < 0) {\r\n            int i = mantissa.length() - 1;\r\n            while (i >= 0 && mantissa.charAt(i) == '0') {\r\n                i--;\r\n            }\r\n            \r\n            mantissa = mantissa.substring(0, i+1);\r\n            i = mantissa.length() - 1;\r\n            if (i >= 0 && mantissa.charAt(i) == dpt) {\r\n                \/\/ Eliminate the decimal point separater if there are no\r\n                \/\/ trailing values (e.g. \"1.\").\r\n                mantissa = \"\";\r\n            }\r\n        }\r\n\r\n        \/\/ Handle negative numbers.\r\n        String neg = \"\";\r\n        if (characteristic.charAt(0) == '-') {\r\n            neg = \"-\";\r\n            characteristic = characteristic.substring(1);\r\n        }\r\n\r\n        \/\/ Insert the command moving from left to right.\r\n        String result = \"\";\r\n        int offset = characteristic.length() % 3;  \/\/ offset to first comma\r\n        for(int i=0; i<characteristic.length(); i++) {\r\n            if (((i%3) == offset) &#038;&#038; (i > 0)) {\r\n                result += sep;\r\n            }\r\n            result += characteristic.charAt(i);\r\n        }\r\n\r\n        rep = neg + result + mantissa;\r\n        return rep;\r\n    }\r\n    public static <T> String commaize(T num) {\r\n        return commaize(num, -1, ',', '.');\r\n    }\r\n    public static <T> String commaize(T num, int dpl) {\r\n        return commaize(num, dpl, ',', '.');\r\n    }\r\n\r\n    \/**\r\n     * main.\r\n     *\/\r\n    public static void main(String[] args) {\r\n        int id = 0;\r\n        String result;\r\n        String str;\r\n        String msg;\r\n\r\n        \/\/ Test positive integers.\r\n        int inums[] = new int[] {1, 12, 123, 1234, 12345, 123456, 1234567, 12345678, 123456789};\r\n        for(int val : inums) {\r\n            result = commaize(val);\r\n            msg = String.format(\"%4d %20d %20s\", ++id, val, result);\r\n            System.out.println(msg);\r\n        }\r\n\r\n        \/\/ Test positive floating points.\r\n        double dnums[] = new double[] {1.23, 12.34, 123.45, 1234.56, 12345.67, 123456.78, 1234567.89, 12345678.9, 1.0};\r\n        for(double val : dnums) {\r\n            str = doubleToString(val);\r\n            result = commaize(val);\r\n            msg = String.format(\"%4d %20s %20s\", ++id, str, result);\r\n            System.out.println(msg);\r\n        }\r\n\r\n        \/\/ Test negative integers.\r\n        for(int val : inums) {\r\n            int nval = -val;\r\n            result = commaize(nval);\r\n            msg = String.format(\"%4d %20d %20s\", ++id, nval, result);\r\n            System.out.println(msg);\r\n        }\r\n\r\n        \/\/ Test negative floating points.\r\n        for(double val : dnums) {\r\n            double nval = -val;\r\n            result = commaize(nval);\r\n            str = doubleToString(nval);\r\n            msg = String.format(\"%4d %20s %20s\", ++id, str, result);\r\n            System.out.println(msg);\r\n        }\r\n\r\n        \/\/ String test.\r\n        str = \"123456789\";\r\n        result = commaize(str);\r\n        msg = String.format(\"%4d %20s %20s\", ++id, str, result);\r\n        System.out.println(msg);\r\n\r\n        \/\/ EU style\r\n        str = \"12345678,9\";\r\n        result = commaize(str, -1, '.', ',');\r\n        msg = String.format(\"%4d %20s %20s\", ++id, str, result);\r\n        System.out.println(msg);\r\n\r\n        \/\/ dollarize\r\n        \/\/ Round to 2 significant digits.\r\n        double ddata[] = new double[] {12345.123, 12345, 12345.1251};\r\n        for(double val : ddata) {\r\n            str = doubleToString(val);\r\n            result = commaize(val, 2);\r\n            msg = String.format(\"%4d %20s %20s\", ++id, str, result);\r\n            System.out.println(msg);\r\n        }\r\n\r\n        \/\/ 1 decimal place\r\n        str = \"1234567.89\";\r\n        result = commaize(str, 1);\r\n        msg = String.format(\"%4d %20s %20s\", ++id, str, result);\r\n        System.out.println(msg);\r\n    }\r\n}<\/pre>\n<p><a name=\"impjs\"><\/a><\/p>\n<h1><a href=\"#top\">&uarr;<\/a> Javascript Implementation<\/h1>\n<p>This is the javascript implementation. It consists of two parts: an HTML wrapper and the javascript code. You can run it in your browser by navigating to the HTML page or you can use a local javascript testing environment like rhino.<\/p>\n<p>When you run it in your browser the output looks like this:<\/p>\n<p><a href=\"http:\/\/joelinoff.com\/blog\/wp-content\/uploads\/2014\/03\/Screen-Shot-2014-03-29-at-9.11.19-AM.png\"><img loading=\"lazy\" src=\"http:\/\/joelinoff.com\/blog\/wp-content\/uploads\/2014\/03\/Screen-Shot-2014-03-29-at-9.11.19-AM-1024x872.png\" alt=\"Screen Shot 2014-03-29 at 9.11.19 AM\" width=\"625\" height=\"532\" class=\"alignnone size-large wp-image-1402\" srcset=\"https:\/\/joelinoff.com\/blog\/wp-content\/uploads\/2014\/03\/Screen-Shot-2014-03-29-at-9.11.19-AM-1024x872.png 1024w, https:\/\/joelinoff.com\/blog\/wp-content\/uploads\/2014\/03\/Screen-Shot-2014-03-29-at-9.11.19-AM-300x255.png 300w, https:\/\/joelinoff.com\/blog\/wp-content\/uploads\/2014\/03\/Screen-Shot-2014-03-29-at-9.11.19-AM-624x531.png 624w, https:\/\/joelinoff.com\/blog\/wp-content\/uploads\/2014\/03\/Screen-Shot-2014-03-29-at-9.11.19-AM.png 1283w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><\/a><\/p>\n<p>Here is the HTML source code.<\/p>\n<pre class=\"lang:xhtml decode:true \" title=\"HTML\" >&lt;!DOCTYPE HTML&gt;\r\n&lt;html&gt;\r\n  &lt;head&gt;\r\n    &lt;title&gt;commaize&lt;\/title&gt;\r\n    &lt;script type=\"text\/javascript\" src=\"commaize.js\"&gt;&lt;\/script&gt;\r\n  &lt;\/head&gt;\r\n  &lt;body&gt;\r\n    &lt;div id=\"place\"&gt;\r\n    &lt;\/div&gt;\r\n  &lt;\/body&gt;\r\n&lt;\/html&gt;<\/pre>\n<p>Here is the javascript source code. Note that this implementation deliberately avoids the use of libraries like jquery. For a production system you definitely want to use javascript libraries to make your code easier to read and more maintainable.<\/p>\n<pre class=\"lang:js decode:true \" title=\"Javascript Implementation\" >\/\/ This is raw javascript on purpose.\r\nwindow.onload = function() {\r\n    \/\/ I would normally recommend using jquery ready() but since I\r\n    \/\/ want to keep this example as simple as possible, jquery is\r\n    \/\/ assumed to not be available.\r\n\r\n\r\n    \/\/ ================================================================\r\n    \/\/ Test a condition and report a message.\r\n    \/\/ ================================================================\r\n    function assert(condition, description)\r\n    {\r\n        if(!condition) {\r\n            alert('ASSERTION: ' + description + ': ' + condition);\r\n        }\r\n    }\r\n    \r\n    \/\/ ================================================================\r\n    \/\/ Commaize a number.\r\n    \/\/    Insert thousands separator into a number and, optionally, specify\r\n    \/\/    the number of decimal places.\r\n    \/\/    \r\n    \/\/    Here are some examples that demonstrate how it is used.\r\n    \/\/    \r\n    \/\/      x=commaize(1234)                        # 1,234\r\n    \/\/      x=commaize(-1234)                       # -1,234\r\n    \/\/      x=commaize(12345.678)                   # 12,345.678\r\n    \/\/      x=commaize(-12345.678)                  # -12,345.678\r\n    \/\/      x=commaize(12345.678, 2)                # 12,345.69\r\n    \/\/      x=commaize(12345.678, 1)                # 12,345.7\r\n    \/\/      x=commaize(1234, -1, '.')               # 1.234\r\n    \/\/      x=commaize(\"1234567,89\", -1, '.', ',')  # EU: 1.234.567,89\r\n    \/\/    \r\n    \/\/    The arguments are:\r\n    \/\/    \r\n    \/\/    @param num  The number: int, float or string.\r\n    \/\/    @param dpl  Decimal places (default: -1 -&gt; do nothing).\r\n    \/\/    @param sep  Thousands separator (default: \",\").\r\n    \/\/    @param dpt  Decimal point (default: \".\").\r\n    \/\/    @returns a formatted string.\r\n    \/\/ ================================================================\r\n    function commaize(num, dpl=-1, sep=',', dpt='.')\r\n    {\r\n        var snum = num.toString();\r\n        assert(snum.indexOf(sep) &lt; 0, 'found \"' + sep + '\" in \"' + snum + '\"');\r\n\r\n        \/\/ Format to N decimal places.\r\n        if (dpl &gt; 0) {\r\n            snum = parseFloat(snum).toFixed(dpl).toString();\r\n        }\r\n\r\n        \/\/ Split into parts.\r\n        var parts = snum.split(dpt);  \/\/ 123 or 123.45\r\n        assert( parts.length &lt; 3, 'too many parts: ' + parts.length);\r\n\r\n        \/\/ Get the characteristic and mantissa.\r\n        \/\/   123.45\r\n        \/\/   ^  ^^\r\n        \/\/   |  |+--- mantissa\r\n        \/\/   |  +---- decimal point\r\n        \/\/   +------- characteristic\r\n        var characteristic = parts[0];\r\n        var mantissa = parts.length == 1 ? '' : dpt + parts[1];\r\n\r\n        \/\/ Handle negative numbers.\r\n        var neg = '';\r\n        if (characteristic[0] == '-') {\r\n            neg = '-';\r\n            characteristic = characteristic.slice(1);  \/\/ strip off the negative\r\n        }\r\n\r\n        \/\/ Clean up the mantissa. Remove trailing zeros unless a specific\r\n        \/\/ number of decimal places (dpl) was specified.\r\n        \/\/    1.000 &gt; 1\r\n        if (mantissa.length &amp;&amp; dpl &lt; 0) {\r\n            \/\/ Make sure that 1.0 --&gt; 1\r\n            while (mantissa.slice(-1) == '0') {\r\n                mantissa = mantissa.slice(0, -1);\r\n            }\r\n            if (mantissa == dpt) {\r\n                mantissa = \"\";\r\n            }\r\n        }\r\n\r\n        \/\/ Insert the commas moving from left to right.\r\n        var result = '';  \/\/ where to put the result\r\n        var offset = characteristic.length % 3  \/\/ offset to start inserting commas\r\n        for(var i=0; i&lt;characteristic.length; i++) {\r\n            if ((i%3) == offset &amp;&amp; i) {\r\n                \/\/ if we are at the digit where a separator needs to be\r\n                \/\/ pre-pended, prepend the separator.\r\n                result += sep ;\r\n            }\r\n            result += characteristic[i];\r\n        }\r\n\r\n        return neg + result + mantissa;\r\n    }\r\n\r\n    \/\/ ================================================================\r\n    \/\/ main\r\n    \/\/ ================================================================\r\n    function main()\r\n    {\r\n        \/\/ This function will generate a table on the page with the\r\n        \/\/ filled in contents of the commaize function for the examples\r\n        \/\/ that we are interested in.\r\n        var rowidx = 0;\r\n        row = function(val, result, msg='')\r\n        {\r\n            var s1 = \"\" + rowidx;\r\n            var s2 = \"\" + val;\r\n            var s3 = \"\" + result;\r\n            var html = '';\r\n\r\n            rowidx++;\r\n\r\n            \/\/ Pad.\r\n            while (s1.length &lt; 4) {s1 = ' ' + s1;}\r\n            while (s2.length &lt; 20) {s2 = ' ' + s2;}\r\n            while (s3.length &lt; 20) {s3 = ' ' + s3;}\r\n\r\n            html += s1 + ' ' + s2 + '  ' + s3;\r\n            if (msg.length &gt; 0) {\r\n                html += '  ' + msg;\r\n            }\r\n            html += '\\n';\r\n            \r\n            return html;\r\n        }\r\n\r\n        var place = document.getElementById('place');\r\n        var html = '';\r\n        html += '&lt;pre&gt;\\n';\r\n        html += 'BEGIN\\n';\r\n\r\n        \/\/ Rows of data here.\r\n        var data = [1, 12, 123, 1234, 12345, 123456, 1234567, 12345678, 123456789,\r\n                    1.23, 12.34, 123.45, 1234.56, 12345.67, 123456.78, 1234567.89, 12345678.9,\r\n                    1.0,\r\n                    -1, -12, -123, -1234, -12345, -123456, -1234567, -12345678, -123456789,\r\n                    -1.23, -12.34, -123.45, -1234.56, -12345.67, -123456.78, -1234567.89, -12345678.9,\r\n                    -1.0,\r\n                    '123456789',\r\n                   ];\r\n        for(var i=0; i&lt;data.length; i++) {\r\n            var datum = data[i];\r\n            var result = commaize(datum);\r\n            html += row(datum, result);\r\n        }\r\n\r\n        \/\/ EU style\r\n        var datum = \"12345678,9\";\r\n        var result = commaize(datum, -1, '.', ',');  \/\/ EU style\r\n        html += row(datum, result, '# EU style');\r\n\r\n        \/\/ dollarize\r\n        \/\/ Round to 2 significant digits.\r\n        var data1 = [12345.123, 12345, 12345.1251,];\r\n        for(var i=0; i&lt;data1.length; i++) {\r\n            datum = data1[i];\r\n            result = commaize(datum, 2);\r\n            html += row(datum, result, '# 2 decimal places');\r\n        }\r\n\r\n        \/\/ 1 decimal place\r\n        datum = \"1234567.89\";\r\n        result = commaize(datum, 1)\r\n        html += row(datum, result, '# 1 decimal place');\r\n\r\n        html += 'END\\n';\r\n        html += '&lt;\/pre&gt;\\n';\r\n        place.innerHTML = html;\r\n    }\r\n\r\n    main();\r\n}<\/pre>\n<p><a name=\"impperl\"><\/a><\/p>\n<h1><a href=\"#top\">&uarr;<\/a> Perl Implementation<\/h1>\n<p>This is the perl implementation.<\/p>\n<pre class=\"lang:default decode:true \" title=\"Perl Implementation\" >#!\/usr\/bin\/env perl\r\n#\r\n# Example that shows how to insert commas into a number.\r\n#\r\nuse strict;\r\nuse warnings;\r\n\r\n&amp;main;\r\n\r\n# ================================================================\r\n# main\r\n# ================================================================\r\nsub main\r\n{\r\n    my @data = (1, 12, 123, 1234, 12345, 123456, 1234567, 12345678, 123456789,\r\n\t\t1.23, 12.34, 123.45, 1234.56, 12345.67, 123456.78, 1234567.89, 12345678.9,\r\n\t\t1.0,\r\n\t\t-1, -12, -123, -1234, -12345, -123456, -1234567, -12345678, -123456789,\r\n\t\t-1.23, -12.34, -123.45, -1234.56, -12345.67, -123456.78, -1234567.89, -12345678.9,\r\n\t\t-1.0,\r\n\t\t'123456789',\r\n\t);\r\n\r\n    my $idx = 1;\r\n    foreach my $datum (@data) {\r\n        my $result = &amp;commaize($datum);\r\n\tprintf(\"%4d %20s  %20s\\n\", $idx++, $datum, $result);\r\n    }\r\n\r\n    # EU style\r\n    my $datum = \"12345678,9\";\r\n    my $result = &amp;commaize($datum, -1, \".\", \",\");  # EU style\r\n    printf(\"%4d %20s  %20s  # EU style\\n\", $idx++, $datum, $result);\r\n\r\n    # dollarize\r\n    # Round to 2 significant digits.\r\n    my @ddata = (12345.123, 12345, 12345.1251,);\r\n    for $datum (@ddata) {\r\n\t$result = &amp;commaize($datum, 2);\r\n        printf(\"%4d %20s  %20s  # 2 decimal places\\n\", $idx++, $datum, $result);\r\n    }\r\n\r\n    # 1 decimal place\r\n    $datum = \"1234567.89\";\r\n    $result = &amp;commaize($datum, 1);\r\n    printf(\"%4d %20s  %20s  # 1 decimal place\\n\",$idx++, $datum, $result);\r\n}\r\n\r\n# ================================================================\r\n# Insert thousands separator into a number and, optionally, specify\r\n# the number of decimal places.\r\n#    \r\n# Here are some examples that demonstrate how it is used.\r\n#    \r\n#   x=commaize(1234)                        # 1,234\r\n#   x=commaize(-1234)                       # -1,234\r\n#   x=commaize(12345.678)                   # 12,345.678\r\n#   x=commaize(-12345.678)                  # -12,345.678\r\n#   x=commaize(12345.678, 2)                # 12,345.69\r\n#   x=commaize(12345.678, 1)                # 12,345.7\r\n#   x=commaize(1234, -1, \".\")               # 1.234\r\n#   x=commaize(\"1234567,89\", -1, \".\", \",\")  # EU: 1.234.567,89\r\n#    \r\n# The arguments are:\r\n#    \r\n#   @param num  The number: int, float or string.\r\n#   @param dpl  Decimal places (default: -1 -> do nothing).\r\n#   @param sep  Thousands separator (default: \",\").\r\n#   @param dpt  Decimal point (default: \".\").\r\n#   @returns a formatted string.\r\n# ================================================================\r\nsub commaize\r\n{\r\n    my $num = shift;\r\n    my $dpl = shift;\r\n    my $sep = shift;\r\n    my $dpt = shift;\r\n\r\n    $dpl = -1  if( !defined($dpl) );\r\n    $sep = \",\" if( !defined($sep) );\r\n    $dpt = \".\" if( !defined($dpt) );\r\n\r\n    # Format to N decimal places.\r\n    my $rep = $num;\r\n    if ($dpl &gt;= 0) {\r\n\tmy $fmt = \"%.${dpl}f\";\r\n\t$rep = sprintf($fmt, $num);\r\n    }\r\n\r\n    # Split into parts.\r\n    # Using split is tricky here because the split value is unknown,\r\n    # i work around that using this simple brute force approach.\r\n    my @parts = ();\r\n    my @chars = split(\/\/, $rep);\r\n    my $idx = 0;\r\n    for my $char (@chars) {\r\n\tif ($char eq $dpt) {\r\n\t    $idx++;\r\n\t}\r\n\telse {\r\n\t    if ($#parts &lt;= $idx) {\r\n\t\tpush(@parts, \"\");\r\n\t    }\r\n\t    $parts[$idx] .= $char;\r\n\t}\r\n    }\r\n\r\n    # Get the characteristic and mantissa.\r\n    #   123.45\r\n    #   ^  ^^\r\n    #   |  |+--- mantissa\r\n    #   |  +---- decimal point\r\n    #   +------- characteristic\r\n    my $characteristic = $parts[0];\r\n    my $mantissa = \"\";\r\n    $mantissa = \"$dpt$parts[1]\" if $#parts &gt; 1;\r\n\r\n    # Handle negative numbers.\r\n    my $neg = \"\";\r\n    if (substr($characteristic, 0, 1) eq \"-\") {\r\n\t$neg = \"-\";\r\n\t$characteristic = substr($characteristic, 1);\r\n    }\r\n\r\n    # Insert the commas moving from left to right.\r\n    my $result = \"\";  # where to put the result\r\n    my $offset = length($characteristic) % 3;  # offset to start inserting commas\r\n    for(my $i=0; $i&lt;length($characteristic); $i++) {\r\n\tif (($i % 3) == $offset &amp;&amp; $i) {\r\n\t    $result .= $sep;\r\n\t}\r\n\t$result .= substr($characteristic, $i, 1);\r\n    }\r\n\r\n    my $final = $neg . $result . $mantissa;\r\n    return $final;\r\n}<\/pre>\n<p><a name=\"impphp\"><\/a><\/p>\n<h1><a href=\"#top\">&uarr;<\/a> PHP Implementation<\/h1>\n<p>This is the PHP implementation. This is how you run it.<\/p>\n<pre class=\"lang:sh decode:true \" title=\"How to run it\" >$ php -f commaize.php<\/pre>\n<p>This is the source code.<\/p>\n<pre class=\"lang:default decode:true \" title=\"PHP Implementation\" >&lt;?php\r\n#\r\n# Example that shows how to insert commas into a number.\r\n#\r\n\r\n# ================================================================\r\n# Insert thousands separator into a number and, optionally, specify\r\n# the number of decimal places.\r\n#    \r\n# Here are some examples that demonstrate how it is used.\r\n#    \r\n#   x=commaize(1234)                            # 1,234\r\n#   x=commaize(-1234)                           # -1,234\r\n#   x=commaize(12345.678)                   # 12,345.678\r\n#   x=commaize(-12345.678)                  # -12,345.678\r\n#   x=commaize(12345.678, 2)                # 12,345.69\r\n#   x=commaize(12345.678, 1)                # 12,345.7\r\n#   x=commaize(1234, -1, \".\")               # 1.234\r\n#   x=commaize(\"1234567,89\", -1, \".\", \",\")  # EU: 1.234.567,89\r\n# \r\n# The arguments are:\r\n#    \r\n# @param num  The number: int, float or string.\r\n# @param dpl  Decimal places (default: -1 -&gt; do nothing).\r\n# @param sep  Thousands separator (default: \",\").\r\n# @param dpt  Decimal point (default: \".\").\r\n# @returns a formatted string.\r\n# ================================================================\r\nfunction commaize($num, $dpl=-1, $sep=\",\", $dpt=\".\") {\r\n    $rep = $num;\r\n\r\n    # Format to N decimal places.\r\n    if ($dpl &gt;= 0) {\r\n        $fmt = \"%.${dpl}f\";\r\n        $rep = sprintf($fmt, $num);\r\n    }\r\n\r\n    # Split into parts.\r\n    $parts = explode($dpt, $rep);\r\n\r\n\r\n    # Get the characteristic and mantissa.\r\n    #   123.45\r\n    #   ^  ^^\r\n    #   |  |+--- mantissa\r\n    #   |  +---- decimal point\r\n    #   +------- characteristic\r\n    $characteristic = $parts[0];\r\n    $mantissa = count($parts) == 1 ? \"\" : $dpt . $parts[1];\r\n\r\n    # Handle negative numbers.\r\n    $neg = \"\";\r\n    if ($characteristic[0] == \"-\") {\r\n        $neg = \"-\";\r\n        $characteristic = substr($characteristic, 1);\r\n    }\r\n\r\n    # Clean up the mantissa. Remove trailing zeros unless a specific\r\n    # number of decimal places (dpl) was specified.\r\n    #    1.000 &gt; 1\r\n    if (strlen($mantissa) and $dpl &lt; 0) {\r\n        # Make sure that 1.0 --&gt; 1\r\n        $mantissa = rtrim($mantissa, \"0\");\r\n        $mantissa = rtrim($mantissa, $dpt);\r\n    }\r\n\r\n    # Insert the commas moving from left to right.\r\n    $result = \"\";  # where to put the result\r\n    $offset = strlen($characteristic) % 3;  # offset to start inserting commas\r\n    for($i=0; $i&lt;strlen($characteristic); $i++) {\r\n        if (($i%3) == $offset and $i &gt; 0) {\r\n            $result .= $sep;\r\n        }\r\n        $result .= $characteristic[$i];\r\n    }\r\n\r\n    $final = $neg . $result . $mantissa;\r\n    return $final;\r\n}\r\n\r\n# ================================================================\r\n# main\r\n# ================================================================\r\nfunction main() {\r\n    $data = array (1, 12, 123, 1234, 12345, 123456, 1234567, 12345678, 123456789,\r\n                   1.23, 12.34, 123.45, 1234.56, 12345.67, 123456.78, 1234567.89, 12345678.9,\r\n                   1.0,\r\n                   -1, -12, -123, -1234, -12345, -123456, -1234567, -12345678, -123456789,\r\n                   -1.23, -12.34, -123.45, -1234.56, -12345.67, -123456.78, -1234567.89, -12345678.9,\r\n                   -1.0,\r\n                   '123456789',\r\n                   );\r\n    $idx = 1;\r\n    foreach($data as $datum) {\r\n        $result = commaize($datum);\r\n        echo sprintf(\"%4d %20s  %20s\\n\", $idx++, \"$datum\", $result);\r\n    }\r\n\r\n    # EU style\r\n    $datum = \"12345678,9\";\r\n    $result = commaize($datum, -1, \".\", \",\");\r\n    echo sprintf(\"%4d %20s  %20s  # EU style\\n\", $idx++, \"$datum\", $result);\r\n\r\n    # dollarize\r\n    # Round to 2 significant digits.\r\n    $data = array(12345.123, 12345, 12345.1251,);\r\n    foreach($data as $datum) {\r\n        $result = commaize($datum, 2);\r\n        echo sprintf(\"%4d %20s  %20s  # 2 decimal places\\n\", $idx++, \"$datum\", $result);\r\n    }\r\n\r\n    # 1 decimal place\r\n    $datum = \"1234567.89\";\r\n    $result = commaize($datum, 1);\r\n    echo sprintf(\"%4d %20s  %20s  # 1 decimal place\\n\", $idx++, \"$datum\", $result);\r\n}\r\n\r\nmain();\r\n?&gt;<\/pre>\n<p><a name=\"imppython\"><\/a><\/p>\n<h1><a href=\"#top\">&uarr;<\/a> Python Implementation<\/h1>\n<p>This is the python implementation. Note that I use asserts because they are available natively.<\/p>\n<pre class=\"lang:default decode:true \" title=\"Python Implementation\" >#!\/usr\/bin\/env python\r\n'''\r\nExample that shows how to insert commas into a number.\r\n'''\r\nimport re\r\n\r\n\r\ndef commaize(num, dpl=-1, sep=',', dpt='.'):\r\n    '''\r\n    Insert thousands separator into a number and, optionally, specify\r\n    the number of decimal places.\r\n    \r\n    Here are some examples that demonstrate how it is used.\r\n    \r\n      x=commaize(1234)                            # 1,234\r\n      x=commaize(-1234)                           # -1,234\r\n      x=commaize(12345.678)                       # 12,345.678\r\n      x=commaize(-12345.678)                      # -12,345.678\r\n      x=commaize(12345.678, dpl=2)                # 12,345.69\r\n      x=commaize(12345.678, dpl=1)                # 12,345.7\r\n      x=commaize(1234,sep='.')                    # 1.234\r\n      x=commaize(\"1234567,89\", sep='.', dpt=',')  # EU: 1.234.567,89\r\n    \r\n    The arguments are:\r\n    \r\n    @param num  The number: int, float or string.\r\n    @param dpl  Decimal places (default: -1 -&gt; do nothing).\r\n    @param sep  Thousands separator (default: \",\").\r\n    @param dpt  Decimal point (default: \".\").\r\n    @returns a formatted string.\r\n    '''\r\n    rep = str(num)  # convert the int or float number to a string\r\n    assert rep.find(sep) &lt; 0  # no separators allowed\r\n\r\n    # Format to N decimal places.\r\n    if dpl &gt;= 0:\r\n        fmt = '%.' + str(dpl) + 'f'\r\n        rep = fmt % (float(num))\r\n\r\n    # Split into parts.\r\n    parts = rep.split(dpt)  # 123 or 123.45\r\n    assert len(parts) &lt; 3   # multiple dpts not allowed\r\n\r\n    # Get the characteristic and mantissa.\r\n    #   123.45\r\n    #   ^  ^^\r\n    #   |  |+--- mantissa\r\n    #   |  +---- decimal point\r\n    #   +------- characteristic\r\n    characteristic = parts[0]\r\n    mantissa = \"\" if len(parts) == 1 else dpt + parts[1]\r\n\r\n    # Handle negative numbers.\r\n    neg = ''\r\n    if characteristic[0] == '-':\r\n        neg = '-'\r\n        characteristic = characteristic[1:]  # strip off the negative\r\n\r\n    # Check our assumption that both the characteristic and the mantissa\r\n    # are integers at this point.\r\n    assert re.match(r'^\\d+$', characteristic)  # empty strings are not allowed\r\n    if len(mantissa):  # empty strings are allowed\r\n        assert re.match(r'^' + dpt + '\\d+$', mantissa)\r\n\r\n    # Clean up the mantissa. Remove trailing zeros unless a specific\r\n    # number of decimal places (dpl) was specified.\r\n    #    1.000 &gt; 1\r\n    if len(mantissa) and dpl &lt; 0:\r\n        # Make sure that 1.0 --&gt; 1\r\n        mantissa = mantissa.rstrip('0')\r\n        mantissa = mantissa.rstrip(dpt)\r\n\r\n    # Insert the commas moving from left to right.\r\n    result = ''  # where to put the result\r\n    offset = len(characteristic) % 3  # offset to start inserting commas\r\n    for i in range(len(characteristic)):\r\n        if (i%3) == offset and i:\r\n            # if we are at the digit where a separator needs to be\r\n            # pre-pended, prepend the separator.\r\n            result += sep \r\n        result += characteristic[i]\r\n\r\n    final = neg + result + mantissa\r\n    return final\r\n\r\n\r\ndef main():\r\n    '''\r\n    Test the method.\r\n    '''\r\n    idx = [0]\r\n    def incidx():\r\n        idx[0] += 1\r\n        return idx[0]\r\n\r\n    data = [1, 12, 123, 1234, 12345, 123456, 1234567, 12345678, 123456789,\r\n            1.23, 12.34, 123.45, 1234.56, 12345.67, 123456.78, 1234567.89, 12345678.9,\r\n            1.0,\r\n            -1, -12, -123, -1234, -12345, -123456, -1234567, -12345678, -123456789,\r\n            -1.23, -12.34, -123.45, -1234.56, -12345.67, -123456.78, -1234567.89, -12345678.9,\r\n            -1.0,\r\n            '123456789',\r\n            ]\r\n    for datum in data:\r\n        result = commaize(datum)\r\n        print('%4d %20s  %20s' % (incidx(), str(datum), result))\r\n\r\n    # EU style\r\n    datum = \"12345678,9\"\r\n    result = commaize(datum, sep='.', dpt=',')  # EU style\r\n    print('%4d %20s  %20s  # EU style' % (incidx(), str(datum), result))\r\n\r\n    # dollarize\r\n    # Round to 2 significant digits.\r\n    data = [12345.123, 12345, 12345.1251,]\r\n    for datum in data:\r\n        result = commaize(datum, dpl=2)\r\n        print('%4d %20s  %20s  # 2 decimal places' % (incidx(), str(datum), result))\r\n\r\n    # 1 decimal place\r\n    datum = \"1234567.89\"\r\n    result = commaize(datum, dpl=1)\r\n    print('%4d %20s  %20s  # 1 decimal place' % (incidx(), str(datum), result))\r\n\r\n\r\nif __name__ == '__main__':\r\n    main()<\/pre>\n<p><a name=\"impruby\"><\/a><\/p>\n<h1><a href=\"#top\">&uarr;<\/a> Ruby Implementation<\/h1>\n<p>This is the ruby implementation.<\/p>\n<pre class=\"lang:default decode:true \" title=\"Ruby Implementation\" >#!\/usr\/bin\/env ruby\r\n\r\n# ================================================================\r\n# Insert thousands separator into a number and, optionally, specify\r\n# the number of decimal places.\r\n#    \r\n# Here are some examples that demonstrate how it is used.\r\n#    \r\n#   x=commaize(1234)                        # 1,234\r\n#   x=commaize(-1234)                       # -1,234\r\n#   x=commaize(12345.678)                   # 12,345.678\r\n#   x=commaize(-12345.678)                  # -12,345.678\r\n#   x=commaize(12345.678, 2)                # 12,345.69\r\n#   x=commaize(12345.678, 1)                # 12,345.7\r\n#   x=commaize(1234, -1, '.')               # 1.234\r\n#   x=commaize(\"1234567,89\", -1, '.', ',')  # EU: 1.234.567,89\r\n#    \r\n# The arguments are:\r\n#    \r\n#   @param num  The number: int, float or string.\r\n#   @param dpl  Decimal places (default: -1 -> do nothing).\r\n#   @param sep  Thousands separator (default: \",\").\r\n#   @param dpt  Decimal point (default: \".\").\r\n#   @returns a formatted string.\r\n# ================================================================\r\ndef commaize(num, dpl=-1, sep=',', dpt='.')\r\n  snum = num.to_s\r\n  raise \"invalid number format\" unless snum.count(sep.to_s) == 0\r\n\r\n  # Format to N decimal places.\r\n  if (dpl >= 0) then\r\n    fmt = '%.' << dpl.to_i.to_s << 'f'\r\n    snum = sprintf fmt, snum.to_f\r\n  end\r\n\r\n  # Split into parts.\r\n  parts = snum.split(dpt)\r\n  raise \"invalid number of parts: %d\" % (parts.length) unless parts.length < 3\r\n\r\n  # Get the characteristic and mantissa.\r\n  #   123.45\r\n  #   ^  ^^\r\n  #   |  |+--- mantissa\r\n  #   |  +---- decimal point\r\n  #   +------- characteristic\r\n  characteristic = parts[0]\r\n  mantissa = parts.length > 1 ? dpt + parts[1] : \"\"\r\n\r\n  # Handle negative numbers.\r\n  neg = \"\"\r\n  if (characteristic[0] == '-')\r\n    characteristic = characteristic[1..-1]\r\n    neg = \"-\"\r\n  end\r\n\r\n   # Clean up the mantissa. Remove trailing zeros unless a specific\r\n  # number of decimal places (dpl) was specified.\r\n  #    1.000 > 1\r\n  if (mantissa.length > 0 and dpl < 0) then\r\n    # Make sure that 1.0 --> 1\r\n    while (mantissa[-1] == '0')\r\n      mantissa = mantissa.chomp(\"0\")\r\n    end\r\n    mantissa = mantissa.chomp(dpt)\r\n  end\r\n\r\n  # Insert the commas moving from left to right.\r\n  result = \"\"\r\n  j = characteristic.length % 3\r\n  characteristic.split(\"\").each_with_index do |item, i|\r\n    if ((i%3) == j and i > 0) then\r\n      # if we are at the digit where a separator needs to be\r\n      # pre-pended, prepend the separator.\r\n      result << sep\r\n    end\r\n    result << item\r\n  end\r\n\r\n  if (mantissa.length) then\r\n    result << mantissa\r\n  end\r\n\r\n  return neg + result\r\nend\r\n\r\n# ================================================================\r\n# Test method.\r\n# ================================================================\r\ndef test()\r\n  data = [1, 12, 123, 1234, 12345, 123456, 1234567, 12345678, 123456789,\r\n          1.23, 12.34, 123.45, 1234.56, 12345.67, 123456.78, 1234567.89, 12345678.9,\r\n          1.0,\r\n          -1, -12, -123, -1234, -12345, -123456, -1234567, -12345678, -123456789,\r\n          -1.23, -12.34, -123.45, -1234.56, -12345.67, -123456.78, -1234567.89, -12345678.9,\r\n          -1.0,\r\n          '123456789',\r\n         ]\r\n  idx = 1\r\n  incidx = lambda do\r\n    idx += 1\r\n    return idx\r\n  end\r\n  data.each do |num|\r\n    result = commaize(num)\r\n    print(\"%4d %20s  %20s\\n\" % [incidx.call(), num.to_s, result])\r\n  end\r\n\r\n  # EU style\r\n  datum = \"12345678,9\"\r\n  result = commaize(datum, -1, '.', ',')  # EU style\r\n  print(\"%4d %20s  %20s  # EU style\\n\" % [incidx.call(), datum.to_s, result])\r\n\r\n  # dollarize\r\n  # Round to 2 significant digits.\r\n  data = [12345.123, 12345, 12345.1251,]\r\n  data.each do |num|\r\n    result = commaize(num, 2)\r\n    print(\"%4d %20s  %20s  # 2 decimal places\\n\" % [incidx.call(), num.to_s, result])\r\n  end\r\n  \r\n  # 1 decimal place\r\n  datum = \"1234567.89\"\r\n  result = commaize(datum, dpl=1)\r\n  print(\"%4d %20s  %20s  # 1 decimal place\\n\" % [incidx.call(), datum.to_s, result])\r\n\r\nend\r\n\r\nif __FILE__ == $0\r\n  test()\r\nend<\/pre>\n<p><a name=\"imptcl\"><\/a><\/p>\n<h1><a href=\"#top\">&uarr;<\/a> Tcl Implementation<\/h1>\n<p>This is the tcl implementation.<\/p>\n<pre class=\"lang:default decode:true \" title=\"Tcl Implementation\" >#!\/usr\/bin\/env tclsh\r\n#\r\n# Example that shows how to insert commas into a number.\r\n#\r\n\r\n# ================================================================\r\n# Insert thousands separator into a number and, optionally, specify\r\n# the number of decimal places.\r\n#    \r\n# Here are some examples that demonstrate how it is used.\r\n#    \r\n#   set x [commaize 1234]                  # 1,234\r\n#   set x [commaize -1234]                 # -1,234\r\n#   set x [commaize 12345.678]             # 12,345.678\r\n#   set x [commaize -12345.678]            # -12,345.678\r\n#   set x [commaize 12345.678 2]           # 12,345.69\r\n#   set x [commaize 12345.678 1]           # 12,345.7\r\n#   set x [commaize 1234 -1 \".\"]           # 1.234\r\n#   set x [commaize \"1234567,89\" \".\" \",\"]  # EU: 1.234.567,89\r\n# \r\n# The arguments are:\r\n#    \r\n# @param num  The number: int, float or string.\r\n# @param dpl  Decimal places (default: -1 -> do nothing).\r\n# @param sep  Thousands separator (default: \",\").\r\n# @param dpt  Decimal point (default: \".\").\r\n# @returns a formatted string.\r\n# ================================================================\r\nproc commaize {num {dpl -1} {sep \",\"} {dpt \".\"}} {\r\n    set rep $num\r\n\r\n    # Format to N decimal places.\r\n    if {$dpl >= 0} {\r\n        set fmt \"%.${dpl}f\"\r\n        set rep [format $fmt $num]\r\n    }\r\n\r\n    # Split into parts.\r\n    set parts [split $rep $dpt]\r\n    set size [llength $parts]\r\n\r\n    # Get the characteristic and mantissa.\r\n    #   123.45\r\n    #   ^  ^^\r\n    #   |  |+--- mantissa\r\n    #   |  +---- decimal point\r\n    #   +------- characteristic\r\n    set characteristic [lindex $parts 0]\r\n    if {$size == 1} {\r\n        set mantissa \"\"\r\n    } else {\r\n        set num [lindex $parts 1]\r\n        set mantissa \"${dpt}${num}\"\r\n    }\r\n\r\n    # Trim off trailing zeros.\r\n    if {$dpl < 0} {\r\n        set mantissa [string trimright $mantissa \"0\"]\r\n        set mantissa [string trimright $mantissa $dpt]\r\n    }\r\n\r\n    # Handle negative numbers.\r\n    set neg [string index $characteristic 0]\r\n    if {[string compare $neg \"-\"] == 0} {\r\n        # strip off the negative\r\n        set characteristic [string range $characteristic 1 [string length $characteristic]]\r\n    } else {\r\n        set neg \"\"\r\n    }\r\n\r\n    # Insert the commas moving from left to right.\r\n    set result \"\"\r\n    set offset [expr [string length $characteristic] % 3]\r\n    for {set i 0} {$i < [string length $characteristic]} {incr i} {\r\n        if {[expr $i>0] && [expr ($i%3)] == $offset} {\r\n            append result $sep\r\n        }\r\n        append result [string index $characteristic $i]\r\n    }\r\n\r\n    set final \"${neg}${result}${mantissa}\"\r\n    return $final\r\n}\r\n\r\n# ================================================================\r\n# main\r\n# ================================================================\r\nproc main {} {\r\n    set data [list 1 12 123 1234 12345 123456 1234567 12345678 123456789 \\\r\n            1.23 12.34 123.45 1234.56 12345.67 123456.78 1234567.89 12345678.9 \\\r\n            1.0 \\\r\n            -1 -12 -123 -1234 -12345 -123456 -1234567 -12345678 -123456789 \\\r\n            -1.23 -12.34 -123.45 -1234.56 -12345.67 -123456.78 -1234567.89 -12345678.9 \\\r\n            -1.0 \\\r\n            \"123456789\" \\\r\n            ]\r\n\r\n    set idx 0\r\n    foreach datum $data {\r\n        incr idx\r\n        set result [commaize $datum]\r\n        set f [format \"%4d %20s %20s\" $idx $datum $result]\r\n        puts $f\r\n    }\r\n\r\n    # EU style\r\n    set datum \"12345678,9\"\r\n    incr idx\r\n    set result [commaize $datum -1 \".\" \",\"]\r\n    set f [format \"%4d %20s %20s\" $idx $datum $result]\r\n    puts $f\r\n\r\n    # dollarize\r\n    # Round to 2 significant digits\r\n    set data [list 12345.123 12345 12345.1251]\r\n    foreach datum $data {\r\n        incr idx\r\n        set result [commaize $datum 2]\r\n        set f [format \"%4d %20s %20s\" $idx $datum $result]\r\n        puts $f\r\n    }\r\n\r\n    # 1 decimal place\r\n    set datum \"1234567.89\"\r\n    incr idx\r\n    set result [commaize $datum 1]\r\n    set f [format \"%4d %20s %20s\" $idx $datum $result]\r\n    puts $f\r\n}\r\n\r\nmain<\/pre>\n<p><a name=\"platforms\"><\/a><\/p>\n<h1><a href=\"#top\">&uarr;<\/a> Tested Platforms<\/h1>\n<p>I have tested this on the following platforms. In all cases I had to install an updated versions of the C++ compiler to handle C++-11 constructs from <a href=\"http:\/\/joelinoff.com\/blog\/?p=1003\">http:\/\/joelinoff.com\/blog\/?p=1003<\/a>.<\/p>\n<table>\n<thead>\n<tr>\n<th>Platform<\/th>\n<th>Status><\/th>\n<th>Notes<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td align=\"left\">CentOS 5.5<\/td>\n<td align=\"left\">Passed<\/td>\n<td align=\"left\">Required installion of g++ 4.8.2<\/td>\n<\/tr>\n<tr>\n<td align=\"left\">CentOS 5.8<\/td>\n<td align=\"left\">Passed<\/td>\n<td align=\"left\">Required installation of g++ 4.8.2<\/td>\n<\/tr>\n<tr>\n<td align=\"left\">CentOS 6.5<\/td>\n<td align=\"left\">Passed<\/td>\n<td align=\"left\">Required installation of g++ 4.8.2<\/td>\n<\/tr>\n<tr>\n<td align=\"left\">Mac OS X 10.9.2<\/td>\n<td align=\"left\">Passed<\/td>\n<td align=\"left\">Required installation of g++ 4.8.2<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><a name=\"license\"><\/a><\/p>\n<h1><a href=\"#top\">&uarr;<\/a> License<\/h1>\n<p>This software is licensed under the MIT open source license.<\/p>\n<p>Copyright (c) 2014 by Joe Linoff<\/p>\n<p>Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and\/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:<\/p>\n<p>The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.<\/p>\n<p>THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.<\/p>\n<p>Enjoy!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This project contains nine different language implementations of a simple algorithm named &#8220;commaize&#8221; that inserts commas into a number. The languages are: bash, c++, java, javascript, perl, php, python, ruby and tcl. My hope is that it will be a useful reference.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[37,4,5],"tags":[],"_links":{"self":[{"href":"https:\/\/joelinoff.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1363"}],"collection":[{"href":"https:\/\/joelinoff.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/joelinoff.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/joelinoff.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/joelinoff.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1363"}],"version-history":[{"count":53,"href":"https:\/\/joelinoff.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1363\/revisions"}],"predecessor-version":[{"id":1417,"href":"https:\/\/joelinoff.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1363\/revisions\/1417"}],"wp:attachment":[{"href":"https:\/\/joelinoff.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1363"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/joelinoff.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1363"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/joelinoff.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1363"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}