C# Convert object to Decimal

匿名 (未验证) 提交于 2019-12-03 03:05:02

问题:

I'm trying to convert an object with the value 0.39999999999999997 to a decimal variable without losing the precision.

object d = 0.39999999999999997; 

I've tried the following methods.

decimal val1 = Convert.ToDecimal(d); // val1 = 0.4 object val2 = Convert.ChangeType(d, Type.GetType("System.Decimal")); // val2 = 0.4 decimal val3 = decimal.Parse(d.ToString()); // val3 = 0.4 decimal val4 = (Decimal) d; // val4 = 0.4 

I know the this is not a problem with the decimal data type not being able to store this value as illustrated below.

decimal val5 = 0.39999999999999997m; // val5 = 0.39999999999999997; 

How do I convert this object to decimal without losing the precision?

I'm using .NET Framework 3.5 if that matters.

回答1:

I think this is the code you looking for:

object d = 0.39999999999999997; //Unbox value double doubleVal = (double)d;  //Convert to string. R format specifier gives a string that can round-trip to an identical number.   //Without R ToString() result would be doubleAsString = "0.4" string doubleAsString = doubleVal.ToString("R");   //Now that you have doubleAsString = "0.39999999999999997" parse it! decimal decimalVal = decimal.Parse(doubleAsString); 


回答2:

For this to work you will need to assign it similarly

object d = 0.39999999999999997M; 

There is no way for the object to maintain the precision unless you force it to. (If this is not the actual code, you will need to show as how its assigned)

Only then would something like this would work decimal dec = Convert.ToDecimal(d);



回答3:

As you are reading data from database(as you noted in one of the comments, IMO you should have added that in your question) I think it's a terrible idea to allow converting to double and back while reading from database, because you will lose precision [likely it's stored as fixed point or in a number system that can represent decimals]. I think that you must put some effort to read the stored values directly as decimals(edit your schema or something like that), or if it's not possible, then read them as strings, and use Decimal.Parse() to get actual values.

Actually your number 0.39999999999999997 has 17 decimal places hence it can't be stored as double safely.

P.S. There's a great article regarding .net Doubles and rounding written by Jon Skeet.



回答4:

Decimal d = new Decimal(d);

if d is a double, then according to the documentation MSDN this should keep the precision.

This constructor rounds value to 15 significant digits using rounding to nearest. This is done even if the number has more than 15 digits and the less significant digits are zero.



回答5:

on this page http://msdn.microsoft.com/en-us/library/364x0z75(v=vs.80).aspx it's written "Without the suffix m, the number is treated as a double"
And this code

object o = 0.39999999999999997; Console.WriteLine(o.GetType()); 

shows up System.Double

while this one

object o = 0.39999999999999997m; Console.WriteLine(o.GetType()); 

shows up System.Decimal
So you're just losing your precision without the suffix m.



回答6:

string val = "0.39999999999999997"); decimal d = decimal.Parse(val,     System.Globalization.NumberStyles.AllowDecimalPoint);//0.39999999999999997 


回答7:

object d = 0.399999999999999999999999997M; would work you.



回答8:

Seriously all you have to do is something like this...

object d = 0.39999999999999997;  decimal result; decimal.TryParse(d.ToString(), out result); return result; 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!