Set the number of digits after the point in double - c#

In c# double type how can i set the number of digits after the point, i need only 4.
thank you.

You can't. Binary floating point doesn't work like that. You can format a double that way (e.g. using "f4" as the format string), but if you're dealing with values which have a natural number of decimal places, then you should probably be using decimal instead. Could you give us more information about what your values represent?

You can't set the number of digits after the point on the double directly.
You can change the string representation of the double using a format string.
One example would be:
string.Format("{0:0.####}", number);
Or as Jon Skeet points out:
number.ToString("f4")

Use this to compare two floating point numbers to 4 digits in the fraction:
if (Math.Abs(a - b) < 1E-4) {
// close enough
//...
}

Related

Formatting a double as a string correctly in C#?

I want to print out the string represenation of a double without losing precision using ToString() I get the following when I try formatting it as a string:
double i = 101535479557522.5;
i.ToString(); //displays 101535479557523
How do I do this in C#?
If you want it to be exactly the same you should use i.ToString("r") (the "r" is for round-trip). You can read about the different numeric formats on MSDN.
You're running into the limits of the precision of Double. From the docs:
Remember that a floating-point number can only approximate a decimal number, and that the precision of a floating-point number determines how accurately that number approximates a decimal number. By default, a Double value contains 15 decimal digits of precision, although a maximum of 17 digits is maintained internally.
If you want more precision - and particularly maintaining a decimal representation - you should look at using the decimal type instead.

Limiting double to 3 decimal places

This i what I am trying to achieve:
If a double has more than 3 decimal places, I want to truncate any decimal places beyond the third. (do not round.)
Eg.: 12.878999 -> 12.878
If a double has less than 3 decimals, leave unchanged
Eg.: 125 -> 125
89.24 -> 89.24
I came across this command:
double example = 12.34567;
double output = Math.Round(example, 3);
But I do not want to round. According to the command posted above,
12.34567 -> 12.346
I want to truncate the value so that it becomes: 12.345
Doubles don't have decimal places - they're not based on decimal digits to start with. You could get "the closest double to the current value when truncated to three decimal digits", but it still wouldn't be exactly the same. You'd be better off using decimal.
Having said that, if it's only the way that rounding happens that's a problem, you can use Math.Truncate(value * 1000) / 1000; which may do what you want. (You don't want rounding at all, by the sounds of it.) It's still potentially "dodgy" though, as the result still won't really just have three decimal places. If you did the same thing with a decimal value, however, it would work:
decimal m = 12.878999m;
m = Math.Truncate(m * 1000m) / 1000m;
Console.WriteLine(m); // 12.878
EDIT: As LBushkin pointed out, you should be clear between truncating for display purposes (which can usually be done in a format specifier) and truncating for further calculations (in which case the above should work).
I can't think of a reason to explicitly lose precision outside of display purposes. In that case, simply use string formatting.
double example = 12.34567;
Console.Out.WriteLine(example.ToString("#.000"));
double example = 3.1416789645;
double output = Convert.ToDouble(example.ToString("N3"));
Multiply by 1000 then use Truncate then divide by 1000.
If your purpose in truncating the digits is for display reasons, then you just just use an appropriate formatting when you convert the double to a string.
Methods like String.Format() and Console.WriteLine() (and others) allow you to limit the number of digits of precision a value is formatted with.
Attempting to "truncate" floating point numbers is ill advised - floating point numbers don't have a precise decimal representation in many cases. Applying an approach like scaling the number up, truncating it, and then scaling it down could easily change the value to something quite different from what you'd expected for the "truncated" value.
If you need precise decimal representations of a number you should be using decimal rather than double or float.
You can use:
double example = 12.34567;
double output = ( (double) ( (int) (example * 1000.0) ) ) / 1000.0 ;
Good answers above- if you're looking for something reusable here is the code. Note that you might want to check the decimal places value, and this may overflow.
public static decimal TruncateToDecimalPlace(this decimal numberToTruncate, int decimalPlaces)
{
decimal power = (decimal)(Math.Pow(10.0, (double)decimalPlaces));
return Math.Truncate((power * numberToTruncate)) / power;
}
In C lang:
double truncKeepDecimalPlaces(double value, int numDecimals)
{
int x = pow(10, numDecimals);
return (double)trunc(value * x) / x;
}

How do I format a number in C# with commas and decimals?

I have a number with a variable number of digits after the decimal point. I want to format the number with commas and all decimal numbers.
For example: 42,023,212.0092343234
If I use ToString("N") I get only 2 decimals, ToString("f") gives me all decimals no commas. How do I get both?
Not sure (and unable to test right now) but would something like this work?
"#,##0.################"
string.Format("{0:#,##0.############}", value);
will give you up to 12 decimal places.
There is not a custom format specifier for "all following digits", so something like this will be closest to what you want.
Note too that you're limited by the precision of your variable. A double only has 15-16 digits of precision, so as your left-hand side gets bigger the number of decimal places will fall off.
UPDATE: Looking at the MSDN documentation on the System.Double type, I see this:
By default, a Double value contains 15
decimal digits of precision, although
a maximum of 17 digits is maintained
internally.
So I think pdr's on to something, actually. Just do this:
// As long as you've got at least 15 #s after the decimal point,
// you should be good.
value.ToString("#,#.###############");
Here's an idea:
static string Format(double value)
{
double wholePart = Math.Truncate(value);
double decimalPart = Math.Abs(value - wholePart);
return wholePart.ToString("N0") + decimalPart.ToString().TrimStart('0');
}
Example:
Console.WriteLine(Format(42023212.0092343234));
Output:
42,023,212.00923432409763336
Ha, well, as you can see, this gives imperfect results, due (I think) to floating point math issues. Oh well; it's an option, anyway.
Try ToString("N2")
Let's try this
[DisplayFormat(DataFormatString = "{0:0,0.00}")]
Here is the way somewhat to reach to your expectation...
decimal d = 42023212.0092343234M;
NumberFormatInfo nfi = (NumberFormatInfo) CultureInfo.InvariantCulture.NumberFormat.Clone();
nfi.NumberDecimalDigits= (d - Decimal.Truncate(d)).ToString().Length-2;
Console.WriteLine(d.ToString("N",nfi));
For more detail about NumberFormatInfo.. look at MSDN ..
http://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo.aspx

Get the decimal part of a number and the number of places after the decimal point (C#)

Does anyone know of an elegant way to get the decimal part of a number only? In particular I am looking to get the exact number of places after the decimal point so that the number can be formatted appropriately. I was wondering if there is away to do this without any kind of string extraction using the culture specific decimal separator....
For example
98.0 would be formatted as 98
98.20 would be formatted as 98.2
98.2765 would be formatted as 98.2765 etc.
It it's only for formatting purposes, just calling ToString will do the trick, I guess?
double d = (double)5 / 4;
Console.WriteLine(d.ToString()); // prints 1.75
d = (double)7 / 2;
Console.WriteLine(d.ToString()); // prints 3.5
d = 7;
Console.WriteLine(d.ToString()); // prints 7
That will, of course, format the number according to the current culture (meaning that the decimal sign, thousand separators and such will vary).
Update
As Clement H points out in the comments; if we are dealing with great numbers, at some point d.ToString() will return a string with scientific formatting instead (such as "1E+16" instead of "10000000000000000"). One way to overcome this probem, and force the full number to be printed, is to use d.ToString("0.#"), which will also result in the same output for lower numbers as the code sample above produces.
You can get all of the relevant information from the Decimal.GetBits method assuming you really mean System.Decimal. (If you're talking about decimal formatting of a float/double, please clarify the question.)
Basically GetBits will return you 4 integers in an array.
You can use the scaling factor (the fourth integer, after masking out the sign) to indicate the number of decimal places, but you should be aware that it's not necessarily the number of significant decimal places. In particular, the decimal representations of 1 and 1.0 are different (the former is 1/1, the latter is 10/10).
Unfortunately, manipulating the 96 bit integer is going to require some fiddly arithmetic unless you can use .NET 4.0 and BigInteger.
To be honest, you'll get a simpler solution by using the built in formatting with CultureInfo.InvariantCulture and then finding everything to the right of "."
Just to expand on the point about getbits, this expression gets the scaling factor from a decimal called foo:
(decimal.GetBits(foo)[3] & 16711680)>>16
You could use the Int() function to get the whole number component, then subtract from the original.

decimal to double

I have the following test code:
decimal test1 = 0.0500000000000000045656554454M;
double test2 = (double)test1;
This results in test2 showing as 0.05 when debugging. Why is it being rounded to 2 decimal places?
Thanks
The value from that conversion is actually 0.050000000000000009714451465470119728706777095794677734375, as shown by DoubleConverter. That's the exact value of the nearest double to the decimal you converted.
When you use the debugger or normal string formatting, you aren't usually shown the exact result.
The reason is that double can contain no more than 15-16 significant digits.
see double (C# Reference)
You should take a look at this article about floating-point arithmetic and .NET. The rounding occurs due to a combination of how the number gets converted to a double-precision floating point value and how it is formatted when printed, since .NET defaults to 15 decimals for doubles, and your original number contains decimal past the 15th.
You could try test2.ToString("0.000000000000000000000000") to see if you might squeeze out any more information from the number, but I doubt it will.
There are two reasons I can think of:
Due to the different representation of decimal and double. See this article for more information about floating point representation. It is possible that there are not enough bits for the whole number representation in the double.
Due to the way numbers are printed. It is possible that in your printing options, there are less than 18 numbers after the decimal point specified - in which case, you'll get the rounded result.
I would check for tweaking the printing options first to make sure that the problem isn't there first.
.. But know that the only solution for the first problem is stop using double :-)

Categories