Firoz
Firoz

Reputation: 7454

Truncate number of digit of double value in C#

How can i truncate the leading digit of double value in C#,I have tried Math.Round(doublevalue,2) but not giving the require result. and i didn't find any other method in Math class.

For example i have value 12.123456789 and i only need 12.12.

Upvotes: 16

Views: 60066

Answers (13)

Guru Stron
Guru Stron

Reputation: 142213

In .NET Core 3.0 and later versions, three additional rounding strategies are available through the MidpointRounding enumeration. In this case MidpointRounding.ToZero or MidpointRounding.ToNegativeInfinity Can be of interest.

The following:

Console.WriteLine(Math.Round(12.128, 2,MidpointRounding.ToZero));
Console.WriteLine(Math.Round(12.123456789, 2,MidpointRounding.ToZero));

Results in:

12.12
12.12

Demo @sharplab.io

Upvotes: 1

CaptainSkyWalker
CaptainSkyWalker

Reputation: 11

I use a little formatting class that I put together which can add gaps and all sorts.

Here is one of the methods that takes in a decimal and return different amounts of decimal places based on the decimal display setting in the app

 public decimal DisplayDecimalFormatting(decimal input, bool valueIsWeightElseMoney)
    {
        string inputString = input.ToString();

        if (valueIsWeightElseMoney)
        {
            int appDisplayDecimalCount = Program.SettingsGlobal.DisplayDecimalPlacesCount;

            if (appDisplayDecimalCount == 3)//0.000
            {
                inputString = String.Format("{0:#,##0.##0}", input, displayCulture);
            }
            else if (appDisplayDecimalCount == 2)//0.00
            {
                inputString = String.Format("{0:#,##0.#0}", input, displayCulture);
            }
            else if (appDisplayDecimalCount == 1)//0.0
            {
                inputString = String.Format("{0:#,##0.0}", input, displayCulture);
            }
            else//appDisplayDecimalCount 0   //0
            {
                inputString = String.Format("{0:#,##0}", input, displayCulture);
            }

        }
        else
        {
            inputString = String.Format("{0:#,##0.#0}", input, displayCulture);
        }

        //Check if worked and return if worked, else return 0
        bool itWorked = false;
        decimal returnDec = 0.00m;
        itWorked = decimal.TryParse(inputString, out returnDec);

        if (itWorked)
        {
            return returnDec;
        }
        else
        {
            return 0.00m;
        }

    }

Upvotes: 0

JayJay
JayJay

Reputation: 12535

object number = 12.123345534;   
string.Format({"0:00"},number.ToString());

Upvotes: -1

PSsam
PSsam

Reputation: 649

There are a lot of answers using Math.Truncate(double). However, the approach using Math.Truncate(double) can lead to incorrect results. For instance, it will return 5.01 truncating 5.02, because multiplying of double values doesn't work precisely and 5.02*100=501.99999999999994

5.02*100=501.99999999999994

If you really need this precision, consider, converting to Decimal before truncating.

public static double Truncate(double value, int precision)
{
    decimal power = (decimal)Math.Pow(10, precision);
    return (double)(Math.Truncate((decimal)value * power) / power);
}

Still, this approach is ~10 times slower.

Upvotes: 3

George P
George P

Reputation: 1

For vb.net use this extension:

Imports System.Runtime.CompilerServices

Module DoubleExtensions

    <Extension()>
    Public Function Truncate(dValue As Double, digits As Integer)

        Dim factor As Integer
        factor = Math.Pow(10, digits)

        Return Math.Truncate(dValue * factor) / factor

    End Function
End Module

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1500785

EDIT: It's been pointed out that these approaches round the value instead of truncating. It's hard to genuinely truncate a double value because it's not really in the right base... but truncating a decimal value is more feasible.

You should use an appropriate format string, either custom or standard, e.g.

string x = d.ToString("0.00");

or

string x = d.ToString("F2");

It's worth being aware that a double value itself doesn't "know" how many decimal places it has. It's only when you convert it to a string that it really makes sense to do so. Using Math.Round will get the closest double value to x.xx00000 (if you see what I mean) but it almost certainly won't be the exact value x.xx00000 due to the way binary floating point types work.

If you need this for anything other than string formatting, you should consider using decimal instead. What does the value actually represent?

I have articles on binary floating point and decimal floating point in .NET which you may find useful.

Upvotes: 35

Carlos Oliveira
Carlos Oliveira

Reputation: 49

double original = 12.123456789;  

double truncated = Truncate(original, 2);  

Console.WriteLine(truncated.ToString());
// or 
// Console.WriteLine(truncated.ToString("0.00"));
// or 
// Console.WriteLine(Truncate(original, 2).ToString("0.00"));


public static double Truncate(double value, int precision)
{
    return Math.Truncate(value * Math.Pow(10, precision)) / Math.Pow(10, precision);
}

Upvotes: 4

Robin Day
Robin Day

Reputation: 102478

This code....

double x = 12.123456789;
Console.WriteLine(x);
x = Math.Round(x, 2);
Console.WriteLine(x);

Returns this....

12.123456789
12.12

What is your desired result that is different?

If you want to keep the value as a double, and just strip of any digits after the second decimal place and not actually round the number then you can simply subtract 0.005 from your number so that round will then work. For example.

double x = 98.7654321;
Console.WriteLine(x);
double y = Math.Round(x - 0.005, 2);
Console.WriteLine(y);

Produces this...

98.7654321
98.76

Upvotes: 3

Philippe Leybaert
Philippe Leybaert

Reputation: 171804

This could work (although not tested):

public double RoundDown(this double value, int digits)
{
     int factor = Math.Pow(10,digits);

     return Math.Truncate(value * factor) / factor;
}

Then you simply use it like this:

double rounded = number.RoundDown(2);

Upvotes: 3

LukeH
LukeH

Reputation: 269398

What have you tried? It works as expected for me:

double original = 12.123456789;

double truncated = Math.Truncate(original * 100) / 100;

Console.WriteLine(truncated);    // displays 12.12

Upvotes: 27

JonoW
JonoW

Reputation: 14229

How about:

double num = 12.12890;
double truncatedNum = ((int)(num * 100))/100.00;

Upvotes: 3

user159335
user159335

Reputation:

I'm sure there's something more .netty out there but why not just:-

double truncVal = Math.Truncate(val * 100) / 100;
double remainder = val-truncVal;

Upvotes: 1

Dan McClain
Dan McClain

Reputation: 11920

If you are looking to have two points after the decimal without rounding the number, the following should work

string doubleString = doublevalue.ToString("0.0000"); //To ensure we have a sufficiently lengthed string to avoid index issues
Console.Writeline(doubleString
             .Substring(0, (doubleString.IndexOf(".") +1) +2)); 

The second parameter of substring is the count, and IndexOf returns to zero-based index, so we have to add one to that before we add the 2 decimal values.

This answer is assuming that the value should NOT be rounded

Upvotes: 0

Related Questions