c#数据类型相当于VBA的指数形式

本文关键字:指数 VBA 数据类型 相当于 | 更新日期: 2023-09-27 18:17:56

我有一个旧的VBA应用程序,它产生的值像1.123456789123456789123456789E-28。当我在谷歌上搜索c#中等效的数据类型时,我在。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.00000000000000000000000000000001;有人能解释一下这里发生了什么吗?c#中的等效数据类型是什么来表示像VBA一样具有相同精度的大指数值?

c#数据类型相当于VBA的指数形式

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

  • 以F或F为后缀的真正字面量,类型为float。例如,文字1f、1.5f、1e10f和123.456F都是float类型。
  • 以D或D为后缀的真正字面量是双精度类型。例如,字面值1d、1.5d、1e10d和123.456D都是double类型。
  • 以M或M为后缀的实字面值为十进制类型。例如,文字1m、1.5m、1e10m和12345.6都是十进制类型。将该文字转换为十进制值值,并在必要时舍入到最接近的可表示值使用银行舍入(第4.1.7节)。任何比例明显在除非值被舍入或值为零,否则将保留文字(在后一种情况下,符号和比例将为0)字面量2900 m将被解析成带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

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

floatdouble为浮点数。这意味着它们分别保存数字和指数系数,其中doublefloat的两倍大小。不建议在精度要求很高的情况下使用double,例如价格。
decimal以定点的"十进制"形式保存数字。它更精确,特别是在十进制计算中。
看来double更有可能是你正在寻找的。