为什么要使用 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 位值。
我正在 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 位值。