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

标签 c# .net decimal exponent

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

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

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 函数和帮助文件(将值存储在文本文件中)我得到了以下内容:

The resulting string uses fixed point format if the number of digits to the left of the decimal point in the value is less than or equal to the specified precision, and if the value is greater than or equal to 0.00001 (Edit: this should be 0.0001. There is an error in the delphi documentation). Otherwise the resulting string uses scientific format, and the Digits parameter specifies the minimum number of digits in the exponent (between 0 and 4).
...
If the section for positive values is empty, or if the entire format string is empty, the value is formatted using general floating-point formatting with 15 significant digits, corresponding to a call to FloatToStrF with the ffGeneral format. General floating-point formatting is also used if the value has more than 18 digits to the left of the decimal point and the format string does not specify scientific notation.

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

4.42615029219009E-5

如果数字是 2 那么数字将显示为

4.42615029219009E-05

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

Fixed-point notation is used if the exponent that would result from expressing the number in scientific notation is greater than -5 and less than the precision specifier; otherwise, scientific notation is used. The result contains a decimal point if required, and trailing zeros after the decimal point are omitted. If the precision specifier is present and the number of significant digits in the result exceeds the specified precision, the excess trailing digits are removed by rounding.

However, if the number is a Decimal and the precision specifier is omitted, fixed-point notation is always used and trailing zeros are preserved.

If scientific notation is used, the exponent in the result is prefixed with "E" if the format specifier is "G", or "e" if the format specifier is "g". The exponent contains a minimum of two digits. This differs from the format for scientific notation that is produced by the exponential format specifier, which includes a minimum of three digits in the exponent.

The result string is affected by the formatting information of the current NumberFormatInfo object. The following table lists the NumberFormatInfo properties that control the formatting of the result string.

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

最佳答案

如您所知,要将字符串转换为数字,只需使用 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'
}

这里的要点是,就数字而言,没有指数没有任何区别,这只是表示的问题(区分它们毫无意义:它们确实是同一件事)。

关于c# - 如何将包含指数数的字符串转换为十进制数并返回字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11663910/

相关文章:

c# - 'context' 在 C# async/await 代码中到底意味着什么?

c# - 为什么结构实例不存在于堆或堆栈中

c# - 从 List 中取出一组 5 个字符串

java - 为什么这个 BigInteger 在输入 FFFFFFFF (8 F) 时显示不正确的结果

c# Reflection - 查找集合的通用类型

c# - 保护从第三方网站返回的查询字符串

c# - 静态变量在 ASP.NET 页面中的什么地方起作用?

.NET Web 客户端 400 错误

javascript - Angular 2 - 如何摆脱 Angular 绑定(bind)中的额外小数?

javascript - 我的 for 循环中的这些小数来自哪里?