Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Formating Numbers

Part of TutorialIntermediate

Description

This function takes a number as a char array and inserts commas in the right places; "1000" becomes "1,000", etc.; for numbers smaller than that, it just returns the original number.

Some overloads were added so that some integers can be converted, too. Negative values and floating-point numbers are not handled.

Example

import std.conv : to;
import std.exception : assumeUnique;

string formatNumber(int i)  { return formatNumber(to!string(i)); }
string formatNumber(long i) { return formatNumber(to!string(i)); }

string formatNumber(const(char)[] n)
{
    char[] number = n.dup;
    for(int i = n.length - 3; i >= 1; i -= 3)
    {
        number=number[0 .. i] ~ "," ~ number[i .. $];
    }
    return assumeUnique(number);
}

version(example) import std.stdio; /* for writefln (for un) */

unittest
{
    version(example) writefln("Running unittest...");
    assert(formatNumber("100") == "100");
    assert(formatNumber("1000") == "1,000");
    assert(formatNumber("10000000") == "10,000,000");
    version(example) writefln("unittest Passed!");
}

version(example)
{
    void main() /* Usage Example */
    {
        writefln(formatNumber(1)); 
        writefln(formatNumber(12));
        writefln(formatNumber(123)); 
        writefln(formatNumber(1234)); 
        writefln(formatNumber(12345)); 
        writefln(formatNumber(123456)); 
        writefln(formatNumber(1234567)); 
        writefln(formatNumber(12345678)); 
        writefln(formatNumber(123456789)); 
        writefln(formatNumber(1234567890)); 
    }
}
else
{
    void main() { }
}

Templated Example

import std.conv : to;
import std.exception : assumeUnique;

string formatNumber(Number)(Number n)
{
    char[] number = to!(char[])(n);
    for(int i = number.length - 3; i >= 1; i -= 3)
    {
        number = number[0 .. i] ~ "," ~ number[i .. $];
    }
    return assumeUnique(number);
}

version(example) import std.stdio; /* for writefln (for un) */

unittest
{
    version(example) writefln("Running unittest...");
    assert(formatNumber("100") == "100");
    assert(formatNumber("1000") == "1,000");
    assert(formatNumber("10000000") == "10,000,000");
    version(example) writefln("unittest Passed!");
}

version(example)
{
    void main() /* Usage Example */
    {
        writefln(formatNumber(1)); 
        writefln(formatNumber(12));
        writefln(formatNumber(123)); 
        writefln(formatNumber(1234)); 
        writefln(formatNumber(12345)); 
        writefln(formatNumber(123456)); 
        writefln(formatNumber(1234567)); 
        writefln(formatNumber(12345678)); 
        writefln(formatNumber(123456789)); 
        writefln(formatNumber(1234567890)); 
    }
}
else
{
    void main() { }
}

Compilation Tips

  • Compile with -version=example to run example.
  • Compile with -unittest to run unittests when the program is run.

Example Call

rdmd FormatNumberExample.d -unittest -version=example

Console Output

Running unittest...
unittest Passed!
1
12
123
1,234
12,345
123,456
1,234,567
12,345,678
123,456,789
1,234,567,890

Source

  • Based on digitalmars.D/32149 by Ameer Armaly.
  • Corrected to get unittest to pass by J C Calvarese.