我在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 函数中一样容易
答案 0 :(得分:6)
要将字符串转换为数字,正如您已经想到的那样,只需使用double
即可。
我会尝试不同的转换:
double myNum = double.Parse("<yournumber>", NumberStyles.AllowExponent | NumberStyles.Float, CultureInfo.InvariantCulture);
AllowExponent
和Float
应该保留表示法,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'
}
这里的要点是,就数字而言, 或没有一个指数没有任何区别,这只是一个代表问题(区分它们没有多大意义:它确实是同样的事情)。