16

当我尝试转换decimal?string. 情景是

decimal decimalValue = .1211;
string value = (decimalValue * 100).ToString();

当前结果:值 = 12.1100

预期结果:值 = 12.11

请告诉我,这可能是什么原因。

4

7 回答 7

20

Decimal保留数字中的任何尾随零Decimal。如果你想要两位小数,而不是:

decimal? decimalValue = .1211m;
string value = ((decimal)(decimalValue * 100)).ToString("#.##")

http://msdn.microsoft.com/en-us/library/0c899ak8.aspx

或者

string value = ((decimal)(decimalValue * 100)).ToString("N2")

http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx

来自System.Decimal

十进制数是一个浮点值,它由一个符号、一个数值中的每个数字的范围从 0 到 9 以及一个比例因子组成,该比例因子表示分隔整数和小数部分的浮点小数点的位置的数值。

Decimal 值的二进制表示由 1 位符号、96 位整数和用于划分 96 位整数并指定它的哪一部分是小数部分的比例因子组成。比例因子隐含地是数字 10,升为从 0 到 28 的指数。因此,十进制值的二进制表示形式为 ((-2 96到 2 96 ) / 10 (0 到 28) ) ,其中-2 96 -1 等于MinValue,2 96 -1 等于MaxValue。

缩放因子还保留 Decimal 数字中的任何尾随零。尾随零不会影响算术或比较运算中的 Decimal 数的值。但是,如果应用了适当的格式字符串<<,则 ToString 方法可以显示>>尾随零。

评论:

  1. 十进制乘法需要转换为十进制,因为Nullable<decimal>.ToString没有格式提供程序
  2. 正如克里斯指出的那样,您需要处理 is 的Nullable<decimal>情况null。一种方法是使用Null-Coalescing-Operator

    ((decimal)(decimalValue ?? 0 * 100)).ToString("N2")
    

Jon Skeet 的这篇文章值得一读:

.NET 中的十进制浮点数(如果您不耐烦,请尽量保持零)

于 2013-05-15T10:26:27.920 回答
6

由于您使用Nullable<T>as your decimal,Nullable<T>.ToString()方法没有可用于格式化的重载参数。

取而代之的是,您可以将其显式转换为,decimal并且可以使用.ToString()格式化方法。

只需在您的方法中使用"0.00"格式。.ToString()

decimal? decimalValue = .1211M;
string value = ((decimal)(decimalValue * 100)).ToString("0.00");
Console.WriteLine(value);

输出将是;

12.11

这是一个DEMO.

作为替代方案,您可以Nullable<T>.Value在没有任何对话的情况下使用;

string value = (decimalValue * 100).Value.ToString("0.00");

查看更多信息Custom Numeric Format Strings

于 2013-05-15T10:24:14.037 回答
2

或者,您可以指定格式“F2”,如下所示:string val = decVal.ToString("F2")因为这指定了 2 个小数位。

于 2013-05-15T10:25:12.803 回答
2

使用定点 ("F) 格式说明符

   string value = (decimalValue * 100).ToString("F");

默认精度说明符基于NumberFormatInfo.NumberDecimalDigits属性的值,默认值为 2。因此,如果在 "F" 之后不指定数字,则默认指定两位小数。

F0 - No decimal places
F1 - One decimal place
于 2013-05-15T10:26:22.400 回答
1

如果您不想限制为一定数量的小数位数:

decimal? decimalValue = .1211;
string value = decimalValue == null 
               ? "0"
               : decimalValue == 0
               ? "0"
               : (decimalValue * 100).ToString().TrimEnd('0');

这将修剪字符串的任何(如果有的话)尾随零,如果decimalValue为空,也返回“0”。如果值为 0,则返回“0”而不进行修剪。

于 2013-05-15T10:40:27.127 回答
0
String.Format("{0:0.00}", decimalValue * 100);

您可以.Format()用作 ) 的替代方法.ToString("0.00"

于 2013-05-15T10:25:00.650 回答
0

由于decimal?没有ToString(string format)重载,最简单的方法是使用String.Format它,与原始代码相比,它也将提供与null案例一致的结果decimalValue(导致空字符串):

string value = String.Format("{0:#.##}", decimalValue * 100);

但是对于您不清楚的其他数字,还有其他一些考虑因素。

如果您有一个不产生大于 0 的值的数字,它是否显示前导零?也就是说,对于0.001211,它是否显示为0.12.12?如果你想要前导零,请改用它(注意从#.##到的变化0.##):

string value = String.Format("{0:0.##}", decimalValue * 100);

如果您有超过 2 个有效小数位,您希望显示这些吗?所以如果你有.12113405它会显示为12.113405?如果是这样使用:

string value = String.Format("{0:#.############}", decimalValue * 100);

(老实说,我认为一定有比这更好的格式化字符串,尤其是它只支持 12 位小数)

当然,如果您想要前导零多个小数位,只需将上述两者结合起来:

string value = String.Format("{0:0.############}", decimalValue * 100);
于 2013-05-15T10:39:32.570 回答