为什么使用decimal(int [])构造函数?

时间:2016-04-15 13:55:25

标签: c# .net refactoring decimal

我在Windows 7上使用Visual Studio 2013维护一个C#桌面应用程序。在代码中的某处有以下行,它尝试使用Decimal(Int32 [])构造函数创建一个0.01十进制值:

decimal d = new decimal(new int[] { 1, 0, 0, 131072 });

第一个问题是,它与以下不同吗?

decimal d = 0.01M;

如果没有什么不同,为什么开发人员会遇到像这样编码的麻烦?

我需要更改此行才能创建动态值。类似的东西:

decimal d = (decimal) (1 / Math.Pow(10, digitNumber));

我会以这种方式引起一些不受欢迎的行为吗?

6 个答案:

答案 0 :(得分:12)

当小数点的来源由位组成时,对我来说似乎很有用。

.NET中使用的十进制有一个基于一系列位参数的实现(不仅仅是一个位流,就像int一样),因此在使用位构造小数时非常有用你通过一个字节blob(一个插槽,一块内存等)返回一个小数的其他系统进行通信。

现在很容易将位组转换为小数。无需花哨的转换代码。此外,您可以根据标准中定义的输入构造一个小数,这样便于测试.NET框架。

答案 1 :(得分:8)

decimal(int[] bits)构造函数允许您给出小数的按位定义,您创建的位必须是4 int数组,其中:

位0,1和2构成96位整数。

位3包含比例因子和符号

它只是让你能够从你的例子中得到十分精确的十进制定义,我认为你不需要这种精确度。

有关使用该构造函数的详细信息,请参阅here;有关可能更适合您的其他构造函数,请参阅here

如果digitNumber是16位指数,那么更具体地回答你的问题,那么decimal d = new decimal(new int[] { 1, 0, 0, digitNumber << 16 });会做你想要的,因为指数进入数组中最后一个int的第16-23位

答案 2 :(得分:3)

xml中的定义是

    //
    // Summary:
    //     Initializes a new instance of System.Decimal to a decimal value represented
    //     in binary and contained in a specified array.
    //
    // Parameters:
    //   bits:
    //     An array of 32-bit signed integers containing a representation of a decimal
    //     value.
    //
    // Exceptions:
    //   System.ArgumentNullException:
    //     bits is null.
    //
    //   System.ArgumentException:
    //     The length of the bits is not 4.-or- The representation of the decimal value
    //     in bits is not valid.

因为一些未知的原因,原始开发人员希望以这种方式初始化他的小数。也许他只是想在将来混淆某人。

如果将其更改为

,则可能会影响您的代码
decimal d = 0.01m;

因为

(new decimal(new int[] { 1, 0, 0, 131072})) == 0.01m

答案 3 :(得分:2)

你应该完全知道decimal如何存储在内存中。

您可以使用此方法生成所需的值

public static decimal Base10FractionGenerator(int digits)
{
    if (digits < 0 || digits > 28)
        throw new ArgumentException($"'{nameof(digits)}' must be between 0 and 28");

    return new decimal(new[] { 1, 0, 0, digits << 16 });
}

一样使用它
Console.WriteLine(Base10FractionGenerator(0));
Console.WriteLine(Base10FractionGenerator(2));
Console.WriteLine(Base10FractionGenerator(5));

结果如下

  

1
  0.01
  0.00001

答案 4 :(得分:2)

您正在讨论的特定构造函数从四个32位值生成一个小数。遗憾的是,较新版本的公共语言基础结构(CLI)未指定其确切格式(可能是为了允许实现支持不同的十进制格式),现在仅保证至少一个特定的精度和十进制数范围。但是,早期版本的CLI确实像Microsoft的实现那样定义了这种格式,因此它可能在Microsoft的实现中保持这种方式以实现向后兼容。但是,不排除CLI的其他实现将以不同方式解释Decimal构造函数的四个32位值。

答案 5 :(得分:1)

小数是精确的数字,你可以使用==或!=来测试相等性。

也许,这行代码来自某个特定时间段有意义的其他地方。

我要清理它。