在幕后,C#/.NET 中的十进制值类型发生了什么?

发布于 2024-09-10 20:22:55 字数 229 浏览 8 评论 0原文

decimal 类型是如何实现的?

更新

  • 这是一个 128 位值类型(16 字节)
  • 1 个符号位
  • 96 位(12 字节)用于尾数
  • 8 位用于指数
  • 剩余位(其中 23 个!)设置为 0

谢谢!我将坚持使用 64 位长和我自己的隐含比例。

How is the decimal type implemented?

Update

  • It's a 128-bit value type (16 bytes)
  • 1 sign bit
  • 96 bits (12 bytes) for the mantissa
  • 8 bits for the exponent
  • remaining bits (23 of them!) set to 0

Thanks! I'm gonna stick with using a 64-bit long with my own implied scale.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

请帮我爱他 2024-09-17 20:22:55

维基百科上的十进制浮点文章,其中包含有关System.Decimal

小数点以 128 位存储,尽管严格来说只需要 102 位。为了方便起见,可以将小数视为三个表示尾数的 32 位整数,然后一个表示符号和指数的整数。最后一个整数的最高位是符号位(以正常方式,对于负数该位设置为 (1)),第 16-23 位(高 16 位字的低位)包含指数。其他位必须全部清零 (0)。该表示形式是由decimal.GetBits(decimal) 给出的表示形式,它返回一个由4 个整数组成的数组。

Decimal Floating Point article on Wikipedia with specific link to this article about System.Decimal.

A decimal is stored in 128 bits, even though only 102 are strictly necessary. It is convenient to consider the decimal as three 32-bit integers representing the mantissa, and then one integer representing the sign and exponent. The top bit of the last integer is the sign bit (in the normal way, with the bit being set (1) for negative numbers) and bits 16-23 (the low bits of the high 16-bit word) contain the exponent. The other bits must all be clear (0). This representation is the one given by decimal.GetBits(decimal) which returns an array of 4 ints.

束缚m 2024-09-17 20:22:55

来自 C# 语言规范

decimal 类型是一种 128 位数据类型,适用于金融和货币计算。
decimal 类型可以表示范围从 1.0 × 10−28 到大约 7.9 × 1028 的值,有效数字为 28-29 位。

decimal 类型的有限值集的形式为 (–1)s × c × 10-e,其中符号 s 为 0 或 1,系数 c 由下式给出: 0 ≤ c < 296,比例 e 满足 0 ≤ e ≤ 28。
decimal 类型不支持有符号零、无穷大或 NaN。 十进制表示为按十的幂缩放的 96 位整数。对于绝对值小于 1.0m 的小数,该值精确到小数点后第 28 位,但不再保留。

对于绝对值大于或等于 1.0m 的小数,该值精确到 28 或 29 位。与 floatdouble 数据类型相反,十进制小数(例如 0.1)可以精确地用十进制表示形式表示。
floatdouble 表示中,此类数字通常是无限分数,使得这些表示更容易出现舍入错误。

如果二元运算符的操作数之一是十进制类型,则另一个操作数必须是整型或十进制类型。如果存在整型操作数,则在执行操作之前将其转换为十进制

对十进制类型值进行运算的结果是计算精确结果(保留为每个运算符定义的比例)然后舍入以适合表示形式的结果。结果将四舍五入到最接近的可表示值,并且当结果同样接近两个可表示值时,四舍五入到最低有效数字位置具有偶数的值(这称为“银行家四舍五入”)。零结果的符号始终为 0,小数位数为 0。

如果十进制算术运算产生的值的绝对值小于或等于 5 × 10-29,则运算结果为零。如果十进制算术运算产生的结果对于 decimal 格式来说太大,则会引发 System.OverflowException

decimal 类型比浮点类型具有更高的精度,但范围更小。因此,从浮点类型到十进制的转换可能会产生溢出异常,而从十进制到浮点类型的转换可能会导致精度损失。由于这些原因,浮点类型和十进制之间不存在隐式转换,并且如果没有显式转换,则不可能在浮点类型和十进制操作数中混合使用相同的表达方式。

From the C# Language Specifications:

The decimal type is a 128-bit data type suitable for financial and monetary calculations.
The decimal type can represent values ranging from 1.0 × 10−28 to approximately 7.9 × 1028 with 28-29 significant digits.

The finite set of values of type decimal are of the form (–1)s × c × 10-e, where the sign s is 0 or 1, the coefficient c is given by 0 ≤ c < 296, and the scale e is such that 0 ≤ e ≤ 28.
The decimal type does not support signed zeros, infinities, or NaN's. A decimal is represented as a 96-bit integer scaled by a power of ten. For decimals with an absolute value less than 1.0m, the value is exact to the 28th decimal place, but no further.

For decimals with an absolute value greater than or equal to 1.0m, the value is exact to 28 or 29 digits. Contrary to the float and double data types, decimal fractional numbers such as 0.1 can be represented exactly in the decimal representation.
In the float and double representations, such numbers are often infinite fractions, making those representations more prone to round-off errors.

If one of the operands of a binary operator is of type decimal, then the other operand must be of an integral type or of type decimal. If an integral type operand is present, it is converted to decimal before the operation is performed.

The result of an operation on values of type decimal is that which would result from calculating an exact result (preserving scale, as defined for each operator) and then rounding to fit the representation. Results are rounded to the nearest representable value, and, when a result is equally close to two representable values, to the value that has an even number in the least significant digit position (this is known as “banker’s rounding”). A zero result always has a sign of 0 and a scale of 0.

If a decimal arithmetic operation produces a value less than or equal to 5 × 10-29 in absolute value, the result of the operation becomes zero. If a decimal arithmetic operation produces a result that is too large for the decimal format, a System.OverflowException is thrown.

The decimal type has greater precision but smaller range than the floating-point types. Thus, conversions from the floating-point types to decimal might produce overflow exceptions, and conversions from decimal to the floating-point types might cause loss of precision. For these reasons, no implicit conversions exist between the floating-point types and decimal, and without explicit casts, it is not possible to mix floating-point and decimal operands in the same expression.

も让我眼熟你 2024-09-17 20:22:55

如 MSDN 的十进制结构页面所述 http:// /msdn.microsoft.com/en-us/library/system.decimal(VS.80).aspx

十进制的二进制表示
值由 1 位符号、
96 位整数和缩放
用于划分 96 位的因子
整数并指定它的哪一部分
是小数。缩放比例
因子隐式是数字 10,
提升至 0 范围内的指数
到 28。因此,二进制
Decimal 值的表示形式是
形式为 ((-296 到 296) / 10(0 到
28)),其中 -296-1 等于
MinValue,且 296-1 等于
最大值。

缩放因子还保留了任何
十进制数中的尾随零。
尾随零不影响
十进制数的值
算术或比较运算。
然而,尾随零可以是
由 ToString 方法显示,如果
应用适当的格式字符串。

As described on MSDN's Decimal Structure page at http://msdn.microsoft.com/en-us/library/system.decimal(VS.80).aspx:

The binary representation of a Decimal
value consists of a 1-bit sign, a
96-bit integer number, and a scaling
factor used to divide the 96-bit
integer and specify what portion of it
is a decimal fraction. The scaling
factor is implicitly the number 10,
raised to an exponent ranging from 0
to 28. Therefore, the binary
representation of a Decimal value is
of the form, ((-296 to 296) / 10(0 to
28)), where -296-1 is equal to
MinValue, and 296-1 is equal to
MaxValue.

The scaling factor also preserves any
trailing zeroes in a Decimal number.
Trailing zeroes do not affect the
value of a Decimal number in
arithmetic or comparison operations.
However, trailing zeroes can be
revealed by the ToString method if an
appropriate format string is applied.

淤浪 2024-09-17 20:22:55

来自 J.Richter 的“CLR via C#”第三版:

128位高精度
浮点值通常用于
财务计算,其中
不能容忍舍入错误。的
128位,1位代表
值的符号,96位代表
值本身,8位代表
10 的幂除以 96 位
值(可以是从 0 到
28)。其余位未使用。

From "CLR via C#" 3rd Edition by J.Richter:

A 128-bit high-precision
floating-point value commonly used for
financial calculations in which
rounding errors can’t be tolerated. Of
the 128 bits, 1 bit represents the
sign of the value, 96 bits represent
the value itself, and 8 bits represent
the power of 10 to divide the 96-bit
value by (can be anywhere from 0 to
28). The remaining bits are unused.

七堇年 2024-09-17 20:22:55

decimal 关键字表示 128 位数据类型。

来源

Decimal 值的二进制表示形式由 1 位符号、96 位整数和用于除以 96 位整数并指定其中哪一部分为小数的比例因子组成。缩放因子隐式为数字 10,提升为 0 到 28 范围内的指数。因此,Decimal 值的二进制表示形式为 ((-296 到 296) / 10(0 到 28)),其中-296-1 等于 MinValue,296-1 等于 MaxValue。

来源

The decimal keyword denotes a 128-bit data type.

Source

The binary representation of a Decimal value consists of a 1-bit sign, a 96-bit integer number, and a scaling factor used to divide the 96-bit integer and specify what portion of it is a decimal fraction. The scaling factor is implicitly the number 10, raised to an exponent ranging from 0 to 28. Therefore, the binary representation of a Decimal value is of the form, ((-296 to 296) / 10(0 to 28)), where -296-1 is equal to MinValue, and 296-1 is equal to MaxValue.

Source

默嘫て 2024-09-17 20:22:55

十进制类型只是另一种形式
浮点数 - 但与
float 和 double,使用的基数是 10。

一个简单的解释在这里 http://csharpindepth.com /Articles/General/Decimal.aspx

The decimal type is just another form
of floating point number - but unlike
float and double, the base used is 10.

A simple explanation is here http://csharpindepth.com/Articles/General/Decimal.aspx

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文