如何将包含指数数字的字符串转换为十进制并返回到字符串

时间:2012-07-26 06:49:33

标签: c# .net decimal exponent

我在delphi和c#之间转换代码。
值作为字符串存储在delphi应用程序的文本文件中。存储值的示例是:'4.42615029219009E-5'

现在在我的c#app中我需要读取该字符串值,然后才能再次写出该值。最初我使用的代码类似于:

string stringField = "4.42615029219009E-5";
double someMoneyVar = Convert.ToDouble(stringField)

稍后如果我需要使用someMoneyVar的值重新创建文本文件,那么使用简单的:

string.Format("{0}", someMoneyVar)

会输出:

4.42615029219009E-05 // note the 0

最后,我读到最好将钱存入c#作为小数。我试图使用decimal.Parse(someMoneyVar, NumberStyles.Any)将字符串值转换为小数,但格式化将丢失。

我需要输出完全按照输入的数据。

注意,someMoneyVar的值可能并不总是包含指数部分。例如0.0428860331919443。如果someMoneyVar的值没有指数部分,那么该值将正确写入文本文件。

更新
深入研究delphi的 FloatToStr 函数和帮助文件(这是将值存储在文本文件中的文件)我带有以下内容:

  

如果是数字,结果字符串使用定点格式   小数点左侧的值小于或等于   到指定的精度,如果值大于或等于   到0.00001 (编辑:这应该是0.0001。德尔福文档中有错误)。否则结果字符串使用科学格式,   和Digits参数指定最小位数   指数(0到4之间)   ...
  如果正值部分为空,或者整个格式   string为空,使用常规浮点格式化值   格式有15位有效数字,对应一个致电   FloatToStrF具有 ffGeneral格式。一般浮点   如果值超过18位,也会使用格式   小数点左侧,格式字符串未指定   科学记数法。

因此,请记住 FloatToStr 函数调用 FloatToStrF 使用15个有效(精确)数字和0作为最小数字位数因此我们最终与

  

4.42615029219009E-5

如果数字为2则数字将显示为

  

4.42615029219009E-05

根据MSDN http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx#GFormatString
使用通用格式说明符,double的精度为15,十进制为29

  

如果是由此产生的指数,则使用定点表示法   用科学记数法表示的数字大于-5和   小于精度说明符;否则,科学记数法是   用过的。如果需要,结果包含小数点和尾随   省略小数点后的零。如果是精度说明符   存在且结果中的有效位数超过   指定的精度,超出的拖尾数字将被删除   四舍五入。

     

但是,如果数字是十进制且精度说明符是   省略,始终使用定点表示法,尾随零   保留。

     

如果使用科学记数法,则结果中的指数为前缀   如果格式说明符是“G”则带有“E”,如果是格式则带有“e”   说明符是“g”。 指数至少包含两位数。这个   不同于由科学记谱法产生的格式   指数格式说明符,至少包含三个   指数中的数字。

     

结果字符串受到格式化信息的影响   当前的NumberFormatInfo对象。下表列出了   NumberFormatInfo属性,用于控制结果的格式   字符串。

可以轻松设置精度,例如mydecimal.toString(“G15”)但是我还没有找到一种方法来设置'E'符号后面的位数,就像在delphi FloatToStrF 函数中一样容易

1 个答案:

答案 0 :(得分:6)

要将字符串转换为数字,正如您已经想到的那样,只需使用double即可。 我会尝试不同的转换:

double myNum = double.Parse("<yournumber>", NumberStyles.AllowExponent | NumberStyles.Float, CultureInfo.InvariantCulture);

AllowExponentFloat应该保留表示法,InvariantCulture负责小数点分隔符(根据语言环境可能不是一个点)。

您可以通过string.Format()输出科学记数字,如下所示:

double num = 1234.5678; // 1.2345678e+03
string.Format("{0:e}", num); // should output "1.2345678E+03"

如果您必须区分带有和不带“E + xx”部分的数字,您必须在将字符串转换为double之前搜索它,并且完整的片段(警告:未经测试!)可能看起来像:

string myString = ReadNumberFromFile(); // Just a placeholder method
double myNum = double.Parse(myString, NumberStyles.AllowExponent | NumberStyles.Float, CultureInfo.InvariantCulture);
string output = string.Empty; //this will be the "converted-back number" container
if (myString.IndexOf("e", StringComparison.OrdinalIgnoreCase) >= 0)
{
    //Number contains the exponent
    output = string.Format("{0:e}", num); // exponential notation 'xxxExx' casing of 'e' changes the casing of the 'e' in the string
}
else
{
    //TODO: Number does NOT contain the exponent
    output = string.Format("{0:f}", num); // fixed-point notation in the form 'xxxx.xxx'
}

这里的要点是,就数字而言, 没有一个指数没有任何区别,这只是一个代表问题(区分它们没有多大意义:它确实是同样的事情)。