【问题标题】:C# data type equivalent to VBA exponential form等效于 VBA 指数形式的 C# 数据类型
【发布时间】:2016-11-14 17:09:56
【问题描述】:

我有一个旧的 VBA 应用程序,它生成的值类似于 1.123456789123456789123456789E-28。当我用谷歌搜索 C# 中的等效数据类型时,我在 SODifference between decimal, float and double in .NET? 中找到了这篇文章。根据这篇文章的建议,十进制数据类型在 C# 中具有最大的大小。所以我使用了十进制数据类型,但我发现十进制似乎在表示 VBA 以指数形式表示的大值方面受到限制。于是我再次谷歌搜索,发现这篇文章https://msdn.microsoft.com/en-us/library/ae55hdtk.aspx。如本文所述,

非整数值可以表示为 mmmEeee,其中 mmm 为 尾数(有效数字),eee 是指数(幂 10)。非整数类型的最高正值为 7.9228162514264337593543950335E+28 用于十进制,3.4028235E+38 用于单,1.79769313486231570E+308 用于双。

这意味着 Double 数据类型具有最大范围的值。所以现在我在十进制和双精度之间感到困惑。

然后我用下面的代码做了一个小实验

    double dbl = 1.123456789123456789123456789E-28;
    decimal dcl = 1.123456789123456789123456789E-28M;
    MessageBox.Show(dbl.ToString());
    MessageBox.Show(dcl.ToString());

dbl 打印的值是 1.123456789123456789123456789E-28,而 dcl 值更改为 0.0000000000000000000000000001; 有人可以解释这里发生了什么吗?在 C# 中以相同精度表示大指数值的等效数据类型(如 VBA 中)是什么?

【问题讨论】:

  • 我认为,如果您进一步阅读第一篇文章,您将了解差异以及何时使用它们。我认为您可能误解了您发布的第一个链接。

标签: c# .net vba excel


【解决方案1】:

根据 C# 语言规范:https://msdn.microsoft.com/en-us/library/aa691085%28v=vs.71%29.aspx

  • 以 F 或 f 为后缀的实数文字是浮点类型。例如,文字 1f、1.5f、1e10f 和 123.456F 都是浮点类型。
  • 以 D 或 d 为后缀的实数文字是 double 类型。例如,文字 1d、1.5d、1e10d 和 123.456D 都是 double 类型。
  • 以 M 或 m 为后缀的实数文字是十进制类型。例如,文字 1m、1.5m、1e10m 和 123.456M 都是十进制类型。 这个字面量通过精确的转换为十进制值 值,并在必要时四舍五入到最接近的可表示值 使用银行家四舍五入(第 4.1.7 节)。任何明显的规模 除非值被四舍五入或值为零,否则文字将被保留 (在后一种情况下,符号和比例将为 0)。因此, 文字 2.900m 将被解析为带符号 0 的小数, 系数 2900,尺度 3。

查看第三个要点,您可以看到短语“...此文字通过取精确值转换为十进制值...”。您获得的值 (0.0000000000000000000000000001) 是您开始使用的输入文字 (1.123456789123456789123456789E-28M) 的转换结果。当然,根据关于转换的第三个要点的第二部分四舍五入的值“...如有必要,使用银行四舍五入四舍五入到最接近的可表示值...”。

这对于decimal 是正确的,但对于floatdouble,指数符号可以由数据类型本身保留,因此不需要转换/舍入。

加法:

要进一步扩展上述内容,请参阅:https://msdn.microsoft.com/en-us/library/364x0z75.aspx

这是decimal 数据类型的定义。如上所述:decimal 的范围是(-7.9 x 1028 to 7.9 x 1028) / (100 to 28)28 to 29 significant digits。你的文字,1.123456789123456789123456789E-28M 超出了这个限制,所以当它被转换时,1 右边的所有东西都按照上面的规则四舍五入。

解决方案(?):

如果您需要比decimal 提供的精度更高的精度,您可能需要考虑实现自己的类,这绝对是可行的。考虑搜索 BigDecimal 的 C# 实现以获取想法。

我在快速谷歌上找到的一个实现:https://gist.github.com/nberardi/2667136

我不能说它的正确性,但它至少可以成为你的起点。

【讨论】:

    【解决方案2】:

    floatdouble 是浮点数。这意味着它们分别持有数字和指数系数,其中doublefloat 的两倍大小。 double 不建议在精度很重要的情况下使用,例如价格。
    decimal 以“十进制”形式保存数字,带有固定点。它更精确,尤其是小数计算。
    似乎double 更有可能是您要查找的内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-05
      • 1970-01-01
      • 2020-07-01
      • 1970-01-01
      • 2010-09-30
      • 1970-01-01
      • 2011-01-13
      相关资源
      最近更新 更多