Is there any code out there (or a built-in function) which allows outputting a floating point number in engineering notation?
For example, 1.5e-4 would
This is an old thread, but the answer might as well be correct. Issues with the existing code: it doesn't handle NaN, any of the infinities, negative numbers, or very small number (like double.Epsilon). And you can't pass in a precision.
My code is:
static string DoubleToEngineering(double value, string displayPrecision)
{
string Retval;
if (double.IsNaN(value)
|| double.IsInfinity(value)
|| double.IsNegativeInfinity(value)
|| double.IsPositiveInfinity(value)
|| value == 0.0
)
{
Retval = String.Format("{0:" + "F" + displayPrecision + "}", value);
return Retval;
}
bool isNeg = value < 0;
if (isNeg) value = -value;
int exp = (int)(Math.Floor(Math.Log10(value) / 3.0) * 3.0);
int powerToRaise = -exp;
double newValue = value;
// Problem: epsilon is something-324
// The biggest possible number is somethinge306
// You simply can't do a Math.Power (10, 324), it becomes infiniity.
if (powerToRaise > 300)
{
powerToRaise -= 300;
newValue = newValue * Math.Pow(10.0, 300);
}
newValue = newValue * Math.Pow(10.0, powerToRaise);
// I don't know when this below is triggered.
if (newValue >= 1000.0)
{
newValue = newValue / 1000.0;
exp = exp + 3;
}
var fmt = "{0:F" + displayPrecision + "}";
Retval = String.Format (fmt, newValue);
if (exp != 0) Retval += String.Format("e{0}", exp);
if (isNeg) Retval = "-" + Retval;
return Retval;
}
Test cases are below. My personal standard for test cases (sorry, this doesn't follow the latest and best NUnit guidance): the public static Test() takes no parameters and return the number of errors. It normally calls a private static TestOne(args, expected) which calculates the actual value, compared to the expected value, and returns the number of errors.
private static int TestDoubleToEngineeringOne(double value, string expected)
{
var fakePrecision = "4";
int NError = 0;
var actual = DoubleToEngineering(value, fakePrecision);
if (actual != expected)
{
System.Diagnostics.Debug.WriteLine($"ERROR: DoubleToEngineering({value}) expected {expected} actual {actual}");
NError++;
}
return NError;
}
public static int TestDoubleToEngineering()
{
int NError = 0;
NError += TestDoubleToEngineeringOne(0, "0.0000");
NError += TestDoubleToEngineeringOne(1, "1.0000");
NError += TestDoubleToEngineeringOne(2, "2.0000");
NError += TestDoubleToEngineeringOne(3, "3.0000");
NError += TestDoubleToEngineeringOne(10, "10.0000");
NError += TestDoubleToEngineeringOne(999, "999.0000");
NError += TestDoubleToEngineeringOne(1000, "1.0000e3");
NError += TestDoubleToEngineeringOne(1.234E21, "1.2340e21");
NError += TestDoubleToEngineeringOne(-1, "-1.0000");
NError += TestDoubleToEngineeringOne(-999, "-999.0000");
NError += TestDoubleToEngineeringOne(-1000, "-1.0000e3");
NError += TestDoubleToEngineeringOne(0.1, "100.0000e-3");
NError += TestDoubleToEngineeringOne(0.02, "20.0000e-3");
NError += TestDoubleToEngineeringOne(0.003, "3.0000e-3");
NError += TestDoubleToEngineeringOne(0.0004, "400.0000e-6");
NError += TestDoubleToEngineeringOne(0.00005, "50.0000e-6");
NError += TestDoubleToEngineeringOne(double.NaN, "NaN");
NError += TestDoubleToEngineeringOne(double.PositiveInfinity, "∞");
NError += TestDoubleToEngineeringOne(double.NegativeInfinity, "-∞");
NError += TestDoubleToEngineeringOne(double.Epsilon, "4.9407e-324");
NError += TestDoubleToEngineeringOne(double.MaxValue, "179.7693e306");
NError += TestDoubleToEngineeringOne(double.MinValue, "-179.7693e306");
return NError;
}