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

Why use decimal(int [ ]) constructor?

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

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

第一个问题,跟下面的有区别吗?

decimal d = 0.01M;

如果没有什么不同,为什么开发人员要这么麻烦地编码?

我需要更改此行 以创建动态值。类似于:

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

我会这样导致一些不受欢迎的行为吗?

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

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

我会清理它。

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

第 0、1 和 2 位组成 96 位整数。

第 3 位包含比例因子和符号

从你的例子来看,它只是让你对小数的定义非常精确,我认为你不需要那种精确度。

请参阅 here for more detail on using that constructor or here 了解其他可能更适合您的构造函数

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

你应该确切地知道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

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

.NET 中使用的小数有一个基于位参数序列的实现(不只是像 int 那样的一个位流),因此用当您与其他系统通信时的位 return 通过一团字节(一个套接字,来自一段内存等)的十进制。

现在很容易将位集转换为十进制。不需要花哨的转​​换代码。此外,您可以从标准中定义的输入构造一个小数,这也使得测试 .NET 框架也很方便。

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

您所说的特定构造函数从四个 32 位值生成一个小数。不幸的是,较新版本的公共语言基础设施 (CLI) 未指定其确切格式(大概是为了允许实现支持不同的十进制格式),现在仅保证至少特定精度和十进制数范围。但是,早期版本的 CLI 确实定义了与 Microsoft 的实现完全相同的格式,因此它可能在 Microsoft 的实现中保持这种方式以实现向后兼容性。但是,不排除 CLI 的其他实现会以不同方式解释 Decimal 构造函数的四个 32 位值。