Joe*_*Joe 4 .net c# language-specifications
我想在进行算术运算之前有效地确保十进制值至少具有N(在下面的示例中为3)位置.
显然,我可以用"0.000######....#"解析格式化,但效率相对较低,而且我正在寻找避免转换为字符串/从字符串转换的解决方案.
我尝试过以下解决方案:
decimal d = 1.23M;
d = d + 1.000M - 1;
Console.WriteLine("Result = " + d.ToString()); // 1.230
Run Code Online (Sandbox Code Playgroud)
这似乎适用于所有值<= Decimal.MaxValue - 1在使用Visual Studio 2015在Debug和Release版本中编译时.
但我怀疑编译器可能会优化(1.000 - 1).C#规范中有什么可以保证它始终有效吗?
或者是否有更好的解决方案,例如使用Decimal.GetBits?
UPDATE
继Jon Skeet的回答后,我之前尝试过添加0.000M,但这对dotnetfiddle不起作用.所以我很惊讶地看到它Decimal.Add(d, 0.000M)确实有效. 这是一个dotnetfiddle比较d + 000M和decimal.Add(d,0.000M):dotnetfiddle的结果不同,但使用Visual Studio 2015编译相同的代码时相同:
decimal d = 1.23M;
decimal r1 = decimal.Add(d, 0.000M);
decimal r2 = d + 0.000M;
Console.WriteLine("Result1 = " + r1.ToString()); // 1.230
Console.WriteLine("Result2 = " + r2.ToString()); // 1.23 on dotnetfiddle
Run Code Online (Sandbox Code Playgroud)
所以至少有一些行为似乎依赖于编译器,这并不令人放心.
如果您对编译器将优化运算符感到紧张(尽管我怀疑它会这样做),您可以直接调用该Add方法.请注意,您不需要添加然后减去 - 您只需添加0.000m.例如:
public static decimal EnsureThreeDecimalPlaces(decimal input) =>
decimal.Add(input, 0.000m);
Run Code Online (Sandbox Code Playgroud)
这似乎工作正常 - 如果你对编译器将对常量做什么感到紧张,你可以将这些位保留在一个数组中,只转换一次:
private static readonly decimal ZeroWithThreeDecimals =
new decimal(new[] { 0, 0, 0, 196608 }); // 0.000m
public static decimal EnsureThreeDecimalPlaces(decimal input) =>
decimal.Add(input, ZeroWithThreeDecimals);
Run Code Online (Sandbox Code Playgroud)
我认为这有点超过顶部 - 特别是如果你有好的单元测试.(如果你对你将要部署的编译代码进行测试,那么编译器之后就无法进入 - 我会非常惊讶地看到JIT介入此处.)
| 归档时间: |
|
| 查看次数: |
482 次 |
| 最近记录: |