C#数据类型等效于VBA指数形式

时间:2016-11-14 17:09:56

标签: c# .net vba excel-vba excel

我有一个旧的VBA应用程序,它生成的值如1.123456789123456789123456789E-28。当我用Google搜索在C#中找到等效的数据类型时,我在SO Difference 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数据类型具有最大的值范围。所以现在我在十进制和双精度之间感到困惑。

然后我用下面的代码进行了一些实验

    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中的大指数值?

2 个答案:

答案 0 :(得分:4)

根据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为后缀的实数是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)的转换结果。当然,根据转换“ ......如果有必要,使用银行家的舍入...... ”四舍五入到最接近的可表示值的第三个项目符号的第二部分舍入值。< / p>

对于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

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

答案 1 :(得分:1)

floatdouble是浮点数。这意味着它们分别保持数字和指数系数,其中doublefloat的双倍大小。如果精度很重要,例如价格,建议不要使用double decimal将数字保存在&#34;十进制&#34;形式,有固定点。它更精确,特别是十进制计算 double似乎更有可能成为您正在寻找的东西。