C#Decimal.Epsilon

Rol*_*kas 32 .net c# decimal epsilon

为什么Decimal数据类型没有Epsilon字段?

从手册中,decimal值的范围是±1.0×10e-28到±7.9×10e28.

描述Double.Epsilon:

表示Double大于零的最小正值

所以看起来,Decimal也有这样一个(非平凡的)价值.但为什么不容易获得?

我明白+1.0×10e-28正是最小的正十进制值大于零:

decimal Decimal_Epsilon = new decimal(1, 0, 0, false, 28); //1e-28m;
Run Code Online (Sandbox Code Playgroud)

顺便提一下,有几个问题可以提供有关Decimal数据类型内部表示的信息:

这是一个Epsilon有用的例子.

假设我从一些采样集和所采样本的权重(或计数)之和得到加权值.现在我想计算加权平均值.但我知道权重(或计数)的总和可能仍为零.为了防止除零,我可以做if... else...并检查零.或者我可以像这样写:

T weighted_mean = weighted_sum / (weighted_count + T.Epsilon)
Run Code Online (Sandbox Code Playgroud)

这个代码在我看来更短.或者,或者我可以跳过+ T.Epsilon,而是初始化:

T weighted_count = T.Epsilon;
Run Code Online (Sandbox Code Playgroud)

当我知道实际权重的值永远不会接近时,我就能做到这一点Epsilon.

对于某些数据类型和用例,这可能更快,因为它不涉及分支.据我所知,即使分支很短,处理器也无法将两个分支用于计算.我可能知道零点以50%的速率随机出现:=)对于Decimal,速度方面可能并不重要,甚至在第一种情况下也没有用.

我的代码可能是通用的(例如,生成的),我不想为小数写单独的代码.因此,人们希望看到它Decimal具有与其他实值类型类似的接口.

Tan*_*lax 13

与该定义相反,epsilon实际上是一个概念,用于消除值的二进制和十进制表示之间转换的模糊性.例如,十进制的0.1没有简单的二进制表示,因此当您将double声明为0.1时,它实际上将该值设置为二进制的近似表示.如果您将该二进制表示编号自身添加10次(数学上),则会得到一个大约为1.0的数字,但不完全相同.epsilon会让你捏造数学,并说加到自身的0.1的近似表示可以被认为等同于0.2的近似表示.

十进制值类型不需要由表示的性质引起的这种近似,十进制值类型已经是十进制表示.这就是为什么任何时候你需要处理本身不是近似值的实际数字和数字(即货币而不是质量),使用的正确浮点类型是十进制而不是双精度.