.NET format specifier for scientific notation with mantissa between 0 and 1
I am working with a Fortran program that expects floating point numbers to be input using Fortran's E
format specifier, which is scientific notation, except the mantissa must be between 0 and 1. So instead of:
"3147.3" --> "3.1473E3",
it needs
"3147.3" --> "0.31473E4".
开发者_如何学编程
I am unable to modify the Fortran program, as it works with a few other programs that are also particular.
It would appear that the C# E
format string would give me the former. Is there any simple way to achieve the latter in C#?
You could specify a custom format like so.
var num = 3147.3;
num.ToString("\\0.#####E0"); // "0.31473E4"
I think that you are solving a non-existent problem. It is true that the default of the Fortran E output specifier has a leading zero before the decimal point (this can be modified). But when the E specifier is used for input it is very tolerant and does not require the leading zero -- if you have a decimal point in the number and the number fits within the columns specified by the format, it will work.
Here is an example Fortran program, and an example input file.
program test_format
real :: num1, num2, num3
open (unit=16, file="numbers_3.txt", status='old', access='sequential', form='formatted', action='read' )
read (16, 1010 ) num1
read (16, 1010 ) num2
read (16, 1010 ) num3
1010 format (E9.5)
write (*, *) num1, num2, num3
stop
end program test_format
and the sample input with three different cases:
3.1473E3
0.31473E4
3147.3
I tested the program with gfortran and Intel ifort. The output was:
3147.300 3147.300 3147.300
So when performing input using Fortran's E format specifier, it is not necessary that the digit before the decimal point be zero. It is not even necessary that the input value use E-notation!
Edit / P.S. I translated the program to the fixed-form source layout of FORTRAN 77 and compiled it with g77 -- it read the three test numbers just fine. The E-format has been flexible for input for a long time -- probably since FORTRAN IV, perhaps longer.
The representaiton of floats or doubles are defined in IEEE754 / IEC 60559:1989. You should look to find libraries to extract mantissa and exponent. Then you could just divide by then to move to comma and subtract the number of steps from the exponent to form your solution.
You could take something similar to Jeff M's solution, and implement it via extension method:
public static class DoubleExtensions
{
public static string ToFortranDouble(this double value)
{
return value.ToString("\\0.#####E0");
}
}
class Program
{
static void Main(string[] args)
{
string fortranValue = 3147.3.ToFortranDouble();
System.Console.WriteLine(fortranValue);
}
}
Or for something a little more complicated (not sure how much precision Fortran floats/doubles give):
public static class DoubleExtensions
{
public static string ToFortranDouble(this double value)
{
return value.ToFortranDouble(4);
}
public static string ToFortranDouble(this double value, int precision)
{
return string.Format(value.ToString(
string.Format("\\0.{0}E0", new string('#', precision))
));
}
}
精彩评论