doublevalue.ToString() loses decimal places in C# - c#

The ToString() of a double value, causes losing of the decimal places
(1521.6666666666667).ToString() ==> "1521.66666666667"
Is there any way to save all the decimal places when converting to string
Also
(1521.6666666666667).ToString("F13"); => "1521.6666666666700"
(1521.6666666666667).ToString("0.0000000000000"); => "1521.6666666666700
Does this have to do with size of the double value

The solution to this is reading the documentation. Seriously It is NOT "ToString" that is loosing it.
Let me quote the float data Type from https://msdn.microsoft.com/en-us/library/b1e65aza.aspx:
Precision: 7 digits.
The numbers are in your source, they are never in the float. Not properly. The value is rounded.

You have to format the string.
(1521.6666666666667).ToString("R");

decimal d = 1521.6666666666667M;
d.ToString();
According to the documentation:
Compared to floating-point types, the decimal type has more precision and a smaller range.
Specifically, decimal has 28-29 significant digits, rather than 15-16 for double.

You can use Decimal instead of Double:
(1521.6666666666667M).ToString(); // note "M"
Another possibility (if you have to use Double) is "R" format:
(1521.6666666666667).ToString("R");

Use The Round-trip ("R") Format Specifier, which will attempts to ensure that a numeric value that is converted to a string is parsed back into the same numeric value. This format is supported only for the Single, Double, and BigInteger types.
But for Double and Single values, the "R" format specifier in some cases fails to successfully round-trip the original value and also offers relatively poor performance. Instead, we recommend that you use the "G17" format specifier for Double values and the "G9" format specifier to successfully round-trip Single values.
From MSDN:
In some cases, Double values formatted with the "R" standard numeric format string do not successfully round-trip if compiled using the /platform:x64 or /platform:anycpu switches and run on 64-bit systems.
Resource: Standard Numeric Format Strings.

Related

remove decimal points from percentage and keep percent symbol in .net

I am trying converting decimal to string which are in this format 0.85 to 85% by using below code, but i am always getting like this
85.00 %
and the code i am using like this below
item.ModifiedObject.Diversity.ToString("p", CultureInfo.CurrentCulture);
I am not sure where i am doing wrong, here i need to remove decimal places and at the same time i need to keep percent symbol with this.
Could any one suggest any suggestion on this that would be great full to me.
PS: I do not want to use split() function with respect to value
It's always useful to look at the documentation first, so let's visit it
The Percent ("P") Format Specifier
The percent ("P") format specifier multiplies a number by 100 and
converts it to a string that represents a percentage. The precision
specifier indicates the desired number of decimal places. If the
precision specifier is omitted, the default numeric precision supplied
by the current PercentDecimalDigits property is used.
Eg
decimal d = 1.23M;
Console.WriteLine(d.ToString("P0"));
Console.WriteLine(d.ToString("P1"));
Console.WriteLine(d.ToString("P2"));
or
decimal d = 1.23M;
Console.WriteLine($"{d:P0}");
Console.WriteLine($"{d:P1}");
Console.WriteLine($"{d:P2}");
Output
123%
123.0%
123.00%

Convert.ToSingle(string) C# conversion ambiguity

I have this code:
string x = "-0.228469369833477";
Single s = Convert.ToSingle(x);
Console.WriteLine(s);
The console outputs: -2,284694E+14 .
What can I do to make it output: -0.228469369833477?
To output the number in its original form:
var s = -0.228469369833477;
Console.WriteLine(s.ToString("0.#######################"));
Note that s is likely a double, not a single. By using single you're very likely losing digits. To get enough precision to represent all of the digits, use Convert.ToDouble() instead.
To ensure that the number gets parsed properly in your locale, use CultureInfo.InvariantCulture, as other answers have stated.
A decimal will give you 28-29 significant digits of precision, with better precision and without the scientific notation problems.
Further Reading
Custom Numeric Format Strings
Single s = Single.Parse(x, CultureInfo.InvariantCulture);
If you want it to output that exact number, you can't use a float because it doesn't give you the precision you want. Try using a double.
double s = Double.Parse(x, CultureInfo.InvariantCulture);
Well, '.' is treated as a thousand separator (and ',' as decimal one) in your current culture (e.g. Russian Culture - "RU-ru" works like that) and since thousand separator ignored on conversion you have -228469369833477 (or -2,284694E+14).
string x = "-0.228469369833477";
// To ensure that '.' is treated as decimal separator
// lets put culture explicitly - CultureInfo.InvariantCulture
Single s = Convert.ToSingle(x, CultureInfo.InvariantCulture);
Console.WriteLine(s);
However, you have too many digits to represent for a Single and all you can return is -0.2284694 (not -0.228469369833477). If you want exact correspondence you have to use Double instead of Single:
Double s = Convert.ToDouble(x, CultureInfo.InvariantCulture);
// -0.228469369833477
Console.WriteLine(s, CultureInfo.InvariantCulture);
You can use
Console.WriteLine(string.Format("{0:N8}", s));
to output the single to 8 decimal places.
You can also specify the culture while doing the string formatting:
Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0:N8}", s));
Here's a working fiddle: https://dotnetfiddle.net/nS9qXh

ToString("D3") is not working

double Cost = 0.03;
var ttt = Cost.ToString("D3");
and
System.FormatException: Format specifier was invalid.
Why?
http://msdn.microsoft.com/en-us/library/dwhawy9k(v=vs.110).aspx#DFormatString
Says it's ok?
Take another look at your MSDN link, just a few sections higher up in the same document:
"D" or "d"
Decimal
Result: Integer digits with optional negative sign.
Supported by: Integral types only.
Precision specifier: Minimum number of digits.
Default precision specifier: Minimum number of digits required.
More information: The Decimal("D") Format Specifier.
1234 ("D") -> 1234
-1234 ("D6") -> -001234
(Emphasis mine)
If you want to ensure three digits to the left of decimal point (this is what 'D' does) with a floating-point type value, you will need to use a Custom Numeric Format String.
Cost.ToString("000.########");
But based on your comments, you really want it to the right of the decimal point, in which case the 'F' strings will work:
Cost.ToString("F3");
And if you're worried about the leading zero, you can do this:
Cost.ToString(".000");
based on your comment (4.4546 should be displayed as a string "4.455"), this should work:
var cost = 4.4546d;
var ttt = cost.ToString("0.000");
Probally 'Cost' is a floating point value. The "D" is a 'decimal' format specifier and doesn't works with floats.
Maybe what you need is in this article: http://msdn.microsoft.com/en-us/library/dd260048(v=vs.110).aspx

How to know if a double string is round-trip safe?

I have a text representation of a double and want to know if it's safe to round-trip it to double and back. How do I know this if I also want to accept any kind of number-style of the input? Or how do I know if any precision is lost when a double-string is parsed with Double.Parse? Or how do I ToString a double to match the same format as another double-string? An answer to any of these questions would be a solution I think.
Use the R format specifier to convert the double to a string:
myDouble.ToString("R")
See The Round-trip ("R") Format Specifier on MSDN.
The round-trip ("R") format specifier guarantees that a numeric value that is converted to a string will be parsed back into the same numeric value. This format is supported only for the Single, Double, and BigInteger types.
(emphasis mine)
Of course, this is not round-trip safe for several reasons:
The number format gets lost when parsing a String to a double, since the double does not contain any information about its visual representation.
While the string representation will normally be decimal, double is a binary floating point number. So 0.1 in double will not be exactly 0.1, since the binary representation of 0.1 does not have finitely many digits. You can parse to decimal instead of double in order to avoid this problem.
I would suggest building a struct that stores both the number and the string representation.

Formatting a String to be Converted to Double

I'm trying to convert a string to double. The incoming string is always going to be a whole number...no decimals. So, for example "90".
double percentToCheck = Convert.ToDouble(String.Format("{0:0.00}", SomeEntity.KeyIDs.SomePercentTrigger));
SomePercentTrigger is the % that I will be converting.
I get a "string is not in the correct format" error so how should I format this string? I've got to format it because if I don't I get the same error with just this during the conversion:
double percentToCheck = Convert.ToDouble(SomeEntity.KeyIDs.SomePercentTrigger);
UPDATED:
SomePercentTrigger is simply a string such as "80"..it'll always be a whole number too.
Update:
Your string is "52.0".
It must be the '.' that causes the FormatException.
You are probably on a machine where '.' is not set as the decimal point (e.g. I live in Germany and use German regional settings. Our decimal point is ',' )
To get around this problem you need to parse the string using CultureInfo.InvariantCulture.
var value = double.Parse(myString, CultureInfo.InvariantCulture);
InvariantCulture should be used for the parts of your application that revolve around data storage. Make sure you use it as well when converting doubles to strings Console.WriteLine(value.ToString(CultureInfo.InvariantCulture));
I suspect that SomeEntity.KeyIDs.SomePercentTrigger has some invalid characters in it (something other than digits, '.' and a optional leading '-'), say for example "80%"
So you're getting a FormatException on this line
double percentToCheck = Convert.ToDouble(String.Format("{0:0.00}", SomeEntity.KeyIDs.SomePercentTrigger));
because {0:0.00} formatting rules are only valid for numeric values.
Also you get the very same exception here:
double percentToCheck = Convert.ToDouble(SomeEntity.KeyIDs.SomePercentTrigger);
because "80%" can not be converted into a double.
You should either
put some logging right in front of the failing statement
or debug that code
and see what the actual content of SomeEntity.KeyIDs.SomePercentTrigger is.
Use double.Parse(string) or alternatively double.TryParse(string, out value)
It doesn't make sense to try to format a string. You would have to parse it to a number first in order to format it. Anyhow, there is no problem in parsing a number without decimals as a double, so the string is probably not containing what you think it does.
If the string contains a number in integer format, parse the string as an integer, and then convert the integer to a double:
double percentToCheck = (double)Int32.Parse(SomeEntity.KeyIDs.SomePercentTrigger);

Categories

Resources