# Extract decimal part of a Decimal

Posted on

#### Question :

I’m having trouble formulating a good way to extract the decimal part of a `decimal` variable, so far the existing implementation on the system is this:

``````public static bool getCasasDecimais(decimal val, out int result)
{
string[] split = val.ToString().Split('.');
return int.TryParse(split[split.Length-1], out result);
}
``````

But it has a problem, you have to adapt the code depending on the culture in which the program is running because of the number division by the decimal point.

I’m trying to find some other implementation to remove that part of the number, preferably something that does not handle a `string` to perform such an operation. The only way I came to mind was by using `Truncate` :

``````decimal number = 12.5523;
var x = number - Math.Truncate(number);
``````

But for some reason, this implementation does not seem very robust, I do not really know why, but I’d like to see other possible implementations before deciding which one I’ll use.

After a comment from the user dcastro in the question, I decided to retry the implementation specified above and it does not return the expected value, since I want to have the decimal digits in an integer, not just the decimal part.

``````Exemplo: 45.545
Resultado proveniente da implementação com Math.Truncate: 0.545
``````

The question remains, is there a way to get this value without manipulating the number as a string?

You can get the decimal part as an integer in the way you expect, without using Strings, using `Math.Floor` as follows: counting how many decimal places there are in the resulting number and multiplying the decimal part by the power of the number of houses:

``````public static void Main()
{
decimal numero = 45.545M;
int parteDecimal = ObterCasasDecimais(numero);
Console.WriteLine(parteDecimal); // resulta 545
}

static int ObterCasasDecimais(decimal numero)
{
decimal resultado = numero - Math.Floor(numero);
int parteDecimal = Convert.ToInt32((double)resultado * Math.Pow(10, qtdCasas));
return parteDecimal;
}

{
return BitConverter.GetBytes(decimal.GetBits(num));
}
``````

See the code working In this .Net Fiddle

## Performance:

I did some performance tests using your current method (with Strings) and the method I proposed (using Floor) and I concluded that when calling only once, or in a loop with few iterations, the string method is faster . When there are many iterations, the Floor method performs better. In practice, if they are called only once and not within loops, the difference is paltry so use the method you find most convenient.

The code I used to test was more or less this:

``````int TotalNumeros = 1000;
decimal[] decimais =
{
2.50M, 3.2345M, 54.4004M, 32.1212M, 123123.3244325M, 3112.453M, 1.2M, 43.12M, 9994.2342M, 24324.2M, 5345.0M, 3123.00M, 123134.456456M
};

Random random = new Random();
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < TotalNumeros; i++)
{
decimal number = decimais[random.Next(decimais.Length - 1)]; // pega um número aleatório do array de decimais
int resultado = ObterCasasDecimais(number); // Método proposto para resposta (Floor)
}
stopwatch.Stop();

stopwatch.Reset();
stopwatch.Start();
for (int i = 0; i < TotalNumeros; i++)
{
decimal number = decimais[random.Next(decimais.Length - 1)];// pega um número aleatório do array de decimais
getCasasDecimais(number, out resultado); // método atual (String)
}
stopwatch.Stop();

``````

I found a simple and efficient solution:

• Removes the integer part and converts the result to string: `Math.Abs((decimal)numero) % 1`
• Remove the “0.” of the result: `Substring(2)`
• Converts the resulting string to an Int32: `Convert.ToInt32`
• The final code looks like this:

``````decimal numero = 123.5489m;
int fracao = Convert.ToInt32((Math.Abs(numero) % 1).ToString().Substring(2));
Console.WriteLine("Fracao: " + fracao);
``````

Original code removed from here .

Well, the simplest way to solve the culture problem is to use `CultureInfo.InvariantCulture` . So the good working of the code no longer depends on the machine where it runs.

``````val.ToString(CultureInfo.InvariantCulture)
``````

Try the following:
float x = 1.466;
string nu = (Mathf.Abs (x)% 1) .ToString (“N1”) Substring (2);
int milliseconds = System.Convert.ToInt32 (nu);

OUTPUT: 4
where: N1 – formats in a decimal, N2 – two …
Substring remove “1.”;

It is not the best practice that is solved in a timer to get the milliseconds.

Posted in qnaTagged