Bluefire
Bluefire

Reputation: 14119

Split number into groups of 3 digits

I want to make a method that takes a variable of type int or long and returns an array of ints or longs, with each array item being a group of 3 digits. For example:

int[] i = splitNumber(100000);
// Outputs { 100, 000 }

int[] j = splitNumber(12345);
// Outputs { 12, 345 }

int[] k = splitNumber(12345678);
// Outputs { 12, 345, 678 }
// Et cetera

I know how to get the last n digits of a number using the modulo operator, but I have no idea how to get the first n digits, which is the only way to make this method that I can think of. Help please!

Upvotes: 2

Views: 7195

Answers (6)

Lance U. Matthews
Lance U. Matthews

Reputation: 16606

You can use this with the System.Linq namespace from .NET 3.5 and above:

int[] splitNumber(long value)
{
    LinkedList<int> results = new LinkedList<int>();

    do
    {
        int current = (int) (value % 1000);

        results.AddFirst(current);
        value /= 1000;
    } while (value > 0);

    return results.ToArray();// Extension method
}

I use LinkedList<int> to avoid having to Reverse a list before returning. You could also use Stack<int> for the same purpose, which would only require .NET 2.0:

int[] splitNumber(long value)
{
    Stack<int> results = new Stack<int>();

    do
    {
        int current = (int) (value % 1000);

        results.Push(current);
        value /= 1000;
    } while (value > 0);

    return results.ToArray();
}

Upvotes: 1

DotNetUser
DotNetUser

Reputation: 6612

By converting into a string and then into int array

int number = 1000000;
string parts = number.ToString("N0", new NumberFormatInfo()
                                            {
                                                NumberGroupSizes = new[] { 3 },
                                                NumberGroupSeparator = "."
                                            });

By using Maths,

public static int[] splitNumberIntoGroupOfDigits(int number)
{
    var numberOfDigits = Math.Floor(Math.Log10(number) + 1); // compute number of digits

    var intArray = new int[Convert.ToInt32(numberOfDigits / 3)]; // we know the size of array
    var lastIndex = intArray.Length -1; // start filling array from the end

    while (number != 0)
    {
        var lastSet = number % 1000;
        number = number / 1000;

        if (lastSet == 0)
        {
            intArray[lastIndex] = 0;  // set of zeros
            --lastIndex;                    
        }
        else if (number == 0)
        {
            intArray[lastIndex] = lastSet; // this could be your last set
            --lastIndex;                    
        }
        else
        {
            intArray[lastIndex] = lastSet;
            --lastIndex;                    
        }
    }

    return intArray;
}

Upvotes: 5

driis
driis

Reputation: 164301

Without converting to string:

int[] splitNumber(int value)
{ 
    Stack<int> q = new Stack<int>();
    do 
    {
        q.Push(value%1000);
        value /= 1000;
    } while (value>0);
    return q.ToArray();
}

This is simple integer arithmetic; first take the modulo to get the right-most decimals, then divide to throw away the decimals you already added. I used the Stack to avoid reversing a list.

Edit: Using log to get the length was suggested in the comments. It could make for slightly shorter code, but in my opinion it is not better code, because the intent is less clear when reading it. Also, it might be less performant due to the extra Math function calls. Anyways; here it is:

int[] splitNumber(int value)
{
    int length = (int) (1 + Math.Log(value, 1000));
    var result = from n in Enumerable.Range(1,length)
                 select ((int)(value / Math.Pow(1000,length-n))) % 1000;
    return result.ToArray();           
}

Upvotes: 6

Guffa
Guffa

Reputation: 700412

You can first find out how large the number is, then use division to get the first digits, and modulo to keep the rest:

int number = 12345678;

int len = 1;
int div = 1;
while (number >= div * 1000) {
  len++;
  div *= 1000;
}

int[] result = new int[len];
for (int i = 0; i < result.Length; i++) {
  result[i] = number / div;
  number %= div;
  div /= 1000;
}

Upvotes: 1

DotNetRussell
DotNetRussell

Reputation: 9857

Convert to string

Get length

If length modulus 3 == 0

String substring it into ints every 3

else if Find remainder such as one or two left over

Substring remainder off of front of string

Then substring by 3 for the rest

Upvotes: 1

mr5
mr5

Reputation: 588

Try converting it to string first and do the parsing then convert it back to number again

Upvotes: 4

Related Questions