Wrong parsing from string to double - c#

double value = double.Parse("4655.927411110702", CultureInfo.InvariantCulture);
Why this parsing is getting me result: 4655.9274111107025?
Somehow it adds to my number 5 at the end. How should I convert this string to double and have a correct result?

You can't. Not all numbers can be represented exactly in double precision floating point, and the closest such double to 4655.927411110702 is 4655.927411110702450969256460666656494140625, and the default formatting you're using trims off the majority of the "joke" digits.
C# does have a decimal type. Can you not use that?
decimal value = decimal.Parse("4655.927411110702", CultureInfo.InvariantCulture);

Related

Format a number value with minimal decimal points

I need to format a number (decimal) into a string with minimal decimal points.
for example, let's say the minimal decimal point is 3
123.123654 => 123.123654
123.12 => 123.120
123.1 => 123.100
123 => 123.000
What is the best way to achieve this result?
If you use really a decimal the decimal places are preserved, so you can write:
decimal d = 123.120m;
Console.WriteLine(d); // 123.120
If you can't do this you can always provide a format with ToString:
Console.WriteLine(d.ToString("N3"));
Reading: Standard numeric format strings, especially. numeric format specifier
As juharr pointed out this shows just 3 decimal places. You can use string.Format:
string result = string.Format("{0:0.000##################}", d);

C# - invariant culture

I'm trying to convert a double to a decimal with a dot instead of a comma. I feel like I have tried every single possible way (except a working one) so I'm out of ideas.
double amount = myUsd / price;
string amountAsString = amount.ToString();
decimal value = Decimal.Parse(amountAsString, CultureInfo.InvariantCulture);
This one gives a FormatException for example.
Thanks
As Hans Passant said, if you Parse in the same way as you Format you'll avoid a lot of issues -> Use string amountAsString = amount.ToString(CultureInfo.InvariantCulture);
EDIT
Since you're passing in an exponential notation you need to tell the Parser this. This worked with your example value:
decimal value = Decimal.Parse(amountAsString, System.Globalization.NumberStyles.Float, CultureInfo.InvariantCulture);
But I suggest NOT formatting it as a Double. First convert it to a Decimal. Then parse it as a Decimal:
double amount = myUsd / price;
Decimal decAmount = (Decimal)amount;
string amountAsString = decAmount.ToString(CultureInfo.InvariantCulture);
decimal value = Decimal.Parse(amountAsString, CultureInfo.InvariantCulture);
Then it'll never get formatted in exponential notation.
Also see this C# Fiddle snippet

Format int to string with decimals

I am trying to format a string using string.Format method to produce a fixed decimal string from an int data type.
I have tried following code :
sOutputString = string.Format(
"Days:{0:D1} Hours:{1:D1} Minutes:{2:D1} Seconds:{3:D1} Miliseconds:{4:D1}",
objTimeCalculate.Days,
objTimeCalculate.Hours,
objTimeCalculate.Minutes,
objTimeCalculate.Seconds,
objTimeCalculate.Miliseconds);
The values of the properties Days, Hours, Minutes, Seconds are int data type and formatted using the D format specified. However I need decimal values produced in the string.
Output should be :
sOutputString = Days : double_value Hours : double_value Minutes : double_value Seconds : double_value Miliseconds : integer_value
Since the property days can go beyond reach of the integer datatypes reach.
Given that objTimeCalculate is a TimeSpan all those variables are int. Therefore they dont have a decimal value.
However we could use the format string F1 which will return with a fixed decimal value, however this will always be 0.
Example:
var objTimeCalculate =(DateTime.Now - DateTime.UtcNow);
var sOutputString = string.Format(
"Days:{0:F1} Hours:{1:F1} Minutes:{2:F1} Seconds:{3:F1} Miliseconds:{4:F1}",
objTimeCalculate.Days,
objTimeCalculate.Hours,
objTimeCalculate.Minutes,
objTimeCalculate.Seconds,
objTimeCalculate.Milliseconds);
Result:
Days:0.0 Hours:9.0 Minutes:29.0 Seconds:59.0 Miliseconds:996.0
You can consult Standard Numeric Format Strings for more details.
"F" or "f" Fixed-point
Result: Integral and decimal digits with optional negative sign.
Supported by: All numeric types. Precision specifier: Number of
decimal digits. Default precision specifier: Defined by
NumberFormatInfo.NumberDecimalDigits.
The Fixed-Point ("F") Format Specifier.
You are looking F specifier:
sOutputString = string.Format(
"Days:{0:F2} Hours:{1:F2} Minutes:{2:F2} Seconds:{3:F2} Miliseconds:{4:F2}",
objTimeCalculate.Days,
objTimeCalculate.Hours,
objTimeCalculate.Minutes,
objTimeCalculate.Seconds,
objTimeCalculate.Miliseconds);

c# how to prevent double value truncation when converting to string

Double x = 11.123456789123456;
string y = Convert.ToString(x);
//gives y=11.1234567891235
//y should be =11.123456789123456
From the above code how can I prevent the last digit(6) from being truncated
Use
string y = x.ToString("G17");
or
string y = x.ToString("R");
as written here:
By default, the return value only contains 15 digits of precision although a maximum of 17 digits is maintained internally. If the value of this instance has greater than 15 digits, ToString returns PositiveInfinitySymbol or NegativeInfinitySymbol instead of the expected number. If you require more precision, specify format with the "G17" format specification, which always returns 17 digits of precision, or "R", which returns 15 digits if the number can be represented with that precision or 17 digits if the number can only be represented with maximum precision.
Note that not all the numbers can be represented exactly...
11.123456789123458.ToString("G17") == "11.123456789123457"
double is only precise up to 15-16 digits, try using decimal type
See Msdn
Decimal
The reason this is happening is because Double occupies 8 bytes and has precision of 15-16 digits.
Use Decimal instead
Decimal x = 11.123456789123456M;
string y = Convert.ToString(x);
//gives y=11.12345678912356
Refer this link, look for answer by cds333

Formatting a decimal value with ToString() to have commas as thousand separators where the amount of decimal places is unknown

I have many decimals, each rounded differently:
decimal quantity = Decimal.Round(item.Quantity.Value, 2,
MidpointRounding.AwayFromZero);
decimal difference = Decimal.Round(quantity * eva, 0,
MidpointRounding.AwayFromZero);
When binding to the UI, I convert to string like this:
string Quantity = quantity.ToString("G", CultureInfo.InvariantCulture);
string Difference = difference.ToString("G", CultureInfo.InvariantCulture);
Is there a generic way to insert commas for thousand separators while keeping the original decimal rounding the same?
Try using Format.
double d = 1.234567;
String output = d.ToString("#,##0.##");
Also,
double d = 123456789.1;
string format = d.ToString().
IndexOf(NumberFormatInfo.CurrentInfo.NumberDecimalSeparator)
>=0 ? "#,##0.00" : "#,##0";
Console.WriteLine (d.ToString(format));
For anyone wondering, I ended up using String.Format(new CultureInfo("en-US"), "{0:N}", difference) and changed the N depending on how many decimal places I needed.
You can use the "N" format specifier and supply the number of digits you want any number to retain. If you want each number to potentially have a different number of digits you wall have to determine the number to supply to the format string each time.
quantity.ToString("N(digits)");
Complete documentation is at http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx#NFormatString

Categories

Resources