【问题标题】:Set the precision for Decimal numbers in C#在 C# 中设置小数的精度
【发布时间】:2018-06-21 02:08:23
【问题描述】:

是否可以全局更改 C# 中小数的精度?

在 TypeScript 中,我使用框架 Decimal.js,我可以像 Decimal.set({ precision: 15}) 那样全局更改十进制运算的精度。这意味着该操作将最多返回 15 个十进制数字。

  • TypeScript:操作5/3返回1.66666666666667
  • C# 操作5m/3m 返回1.6666666666666666666666666667

C# 中的 Decimal 值是否有类似的设置?如何在 C# 中完成此操作?

【问题讨论】:

  • 不,没有办法全局设置decimal的任意精度。
  • 你想用更少的数字显示它但用所有数字计算还是你需要四舍五入?
  • @Zorkind 嗯,这取决于规模因素...单位理论上可以是苹果公司的市值,以数十亿美元为单位,拥有 0.1% 股份数量的人可能想知道最多最后一分钱它值多少钱。不要假设你一无所知的信息,你很可能会错。
  • @PatrickArtner 我希望数字不超过我指定的精度。完美的解决方案类似于 Decimal.js 的做法。否则每一个提议都是受欢迎的。

标签: c# decimal


【解决方案1】:

这不是您要问的,但您可以在全局范围内初始化 NumberFormatInfo 对象并使用它来格式化小数。这是一个例子:

using System.Globalization;

NumberFormatInfo setPrecision = new NumberFormatInfo();    
setPrecision.NumberDecimalDigits = 2;    
decimal test = 1.22223;

Console.Write(test.ToString("N", setPrecision)); //Should write 1.23

setPrecision.NumberDecimalDigits = 3;
test = 5m/3m;

Console.Write(test.ToString("N", setPrecision)); //Should write 1.667

MSDN 链接:https://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo(v=vs.110).aspx

NumberDecimalDigits 使用示例:https://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo.numberdecimaldigits(v=vs.110).aspx

【讨论】:

  • 很好,一旦你设置了值,如何清除它?。
【解决方案2】:

decimal 精度没有通用设置。你最好的机会是在你的扩展中实现这些方法。

var decimalValue = 5m/3m;
var str = decimalValue.ToString("0.##############");//1.66666666666667

或者你可以使用Round;

var decimalValue = 5m/3m;
decimalValue = decimal.Round(decimalValue, 6, MidpointRounding.AwayFromZero);
【解决方案3】:

Decimal.js 的文档声明如下:

精度

一个结果的最大个有效数字 操作。

所有返回 Decimal 的函数都会将返回值四舍五入为 精度有效数字,除了 Decimal、absoluteValue、ceil、 floor, negated, round, toDecimalPlaces, toNearest 和 truncated。

好吧,如果你真的需要全局的这种行为,那么只需实现一个包装器类型来做到这一点,你就有一个很好的规范可供参考:

public struct RoundedDecimal
{
    public static int Precision { get; private set; }

    public static Decimal AbsoluteValue(
        RoundedDecimal d) => Math.Abs(d.value);

    //same with ceiling, floor, etc.

    private readonly decimal value;

    public RoundedDecimal(decimal d)
    {
        value = Decimal.Round(d, Precision);
    }

    public static void SetPrecision(int precision)
    {
        Precision = precision; /*omitted argument validation*/ }

     public static implicit operator Decimal(
         RoundedDecimal d) => d.value;

    public static explicit operator RoundedDecimal(
        decimal d) => new RoundedDecimal(d);

    public static RoundedDecimal operator +(
        RoundedDecimal left, RoundedDecimal right) =>
           new RoundedDecimal(left.value + right.value);

    //etc.
}

就性能而言,这不会令人印象深刻,但如果它的行为您需要,那么一定要实现它!

免责声明:在我的手机上编写的代码,所以它肯定有错误......只是试图让这个想法得到理解。

【讨论】:

  • 你必须有一个相当大的手机......或微型 USB 键盘......这种格式比我见过的在电脑上写的要好。干得好。
猜你喜欢
  • 2018-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-03
  • 1970-01-01
  • 2021-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多