【问题标题】:How to convert System.Decimal bits to string in C#?如何在 C# 中将 System.Decimal 位转换为字符串?
【发布时间】:2011-03-29 07:57:54
【问题描述】:

我希望能够从 System.Decimal 值中获取位,然后将其转换为值的字符串表示形式,就像 Decimal.ToString() 会做的那样,但我很难想出算法.

所以我有这样的事情:

decimal d = 1403.45433M;
int[] nDecimalBits = decimal.GetBits(d);

// How to convert the 4 integers in nDecimalBits to a string
// that contains "1403.45433"?

我知道十进制的二进制布局 - 前 3 个整数包含值位,最后一个整数包含符号位和比例因子。

我尝试使用各种搜索词搜索算法,但小数主要用作“浮点数”的同义词,因此我的搜索找到了不相关问题的答案。

任何帮助将不胜感激。

编辑:为了响应一些答案,我需要将这些位发送到需要重建值的不同平台。 System.Decimal 及其任何成员函数在那里不可用,所以我需要获取这些位并将它们转换为字符串。

如果我有选择,我显然会使用ToString(),但我不需要问。

【问题讨论】:

  • 为什么需要这样做,为什么不能使用“decimal.ToString()”?

标签: c# .net decimal


【解决方案1】:

您可以使用 Decimal 构造函数Decimal(Int32[]) 将您的值转换回:

十进制构造函数(Int32[])

将 Decimal 的新实例初始化为以二进制表示并包含在指定数组中的十进制值。

之后,您可以根据需要使用ToString。 示例:

decimal d = 1403.45433M;
int[] nDecimalBits = decimal.GetBits(d);

decimal d2 = new decimal(nDecimalBits);
string s = d2.ToString();

【讨论】:

  • +1:没有理由在这里重新发明轮子。使用十进制构造函数将位转换回十进制。
  • 你还没有阅读我的信息。我没有重新发明轮子的奇怪冲动——我需要在 .NET 不可用的平台上重建小数的字符串值。我所拥有的只是从服务器的十进制中获得的 4 个整数。我可以发送文本而不是 4 个整数,但我还需要尽量减少网络流量。
  • @xxbbcc:我已经阅读了您的消息... .NET FW 在目标平台上不可用的信息是新的。 ;-) 了解哪些技术在目标平台上可用可能会有所帮助。在 Java 中实现这样的算法(请参阅我对 Bugai13 答案的评论)可能比在 C 中容易得多。我添加了第二个答案,其中包含指向 mono 实现的链接,它仅适用于 uint/ulong 数据类型和一些位移魔法。
【解决方案2】:

它没有算法,但我想它应该有帮助。

十进制位structure:

十进制的二进制表示 数字由一个 1 位符号组成,一个 96 位整数和缩放 用于除整数的因子 编号并指定它的哪一部分 是一个小数。缩放 factor 隐含地是数字 10, 提高到从 0 的指数 到 28 岁。

返回值是一个四元素 32 位有符号整数数组。

第一个、第二个和第三个元素 返回的数组包含低, 96 位的中、高 32 位 整数。

返回的第四个元素 数组包含比例因子和 符号。它由以下内容组成 部分:

位 0 到 15,低位字,是 未使用且必须为零。

位 16 到 23 必须包含一个指数 介于 0 和 28 之间,表示 10 的幂除以整数 号码。

位 24 到 30 未使用,必须 零。

第 31 位包含符号; 0意义 正数,1 表示负数。

【讨论】:

  • 感谢您的回答 - 我已经掌握了这些详细信息。我可以进行二进制到字符串的转换,但十进制是一个更复杂的情况(高整数中的位需要在处理低整数中的位时移动),我还没有找到解决方案。
  • @xxbbcc:我不知道为什么这对你没有帮助......它准确地描述了 Decimal 如何存储在整数数组中的格式。我猜这个算法很简单:你将前三个整数连接成一些大整数数据类型(例如 Java 的 BigInteger 类型),然后使用第 4 个整数来确定小数点的放置位置。如果您在尝试确定算法时告诉我们您究竟卡在哪里,也许会有所帮助。
  • 我的工作期限非常紧迫,目标平台上对小数的支持是在最后一刻加入的。在转换过程中,我必须保留所有十进制数字,因此使用双精度是不可能的 - 不允许舍入错误(小数本身之外),所以我必须在进行时直接进行十进制到字符串的转换输入位。移动正确的位数是我卡住的地方 - int32 是我在转换过程中可以使用的最大数字类型。
【解决方案3】:

你不能只使用十进制构造函数有什么主要原因吗?

new decimal(nDecimalBits).ToString();

【讨论】:

  • 确实是这样,但好像他不喜欢ToString,他想从位中构建十进制字符串(提取96位int值,指数,符号)。
【解决方案4】:

由于你不能使用ToString(),你可能想看看单声道开发者是如何实现这个的:

入口点是NumberToString(string, decimal, IFormatProvider)

有趣的部分是InitDecHexDigits(uint, ulong),它是这样调用的

InitDecHexDigits ((uint)bits [2], ((ulong)bits [1] << 32) | (uint)bits [0]);

并通过“位杂耍和移位”将三个整数转换为binary coded decimals (_val1 to _val4),然后可以(简单地)转换为字符串。

(不要因为他们称之为“十六进制表示”而感到困惑。它是二进制编码的十进制位。)

【讨论】:

  • Heinzi,谢谢 - 我没有想到这一点。我会检查一下,这可能正是我正在寻找的。就我的目的而言,BCD 几乎与直字符串一样好,而从 BCD 字符串转换是微不足道的,正如您所说。再次感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2023-04-08
  • 2015-04-20
  • 2022-10-05
  • 2023-03-24
  • 1970-01-01
  • 2020-10-11
  • 1970-01-01
  • 2011-01-21
相关资源
最近更新 更多