Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to format numbers in scientific notation with powers in superscript

I need to write values like:

9.6 x 10²
9.6 x 10¹²

I need to know if there is a way to format numbers as above in a string.

like image 861
Renan Barbosa Avatar asked Jan 02 '18 12:01

Renan Barbosa


People also ask

How do you do scientific notation with powers?

To increase an exponent in scientific notation, move the decimal point in the mantissa to the left the same number of times that you would like to increase the exponent. (For example, to increase the exponent by 2, add 2 to the exponent and move the decimal point in the mantissa to the left two times).

What is a superscript in scientific notation?

Scientific notation is expressed as a power (also called an exponent) to the base 10. The superscript (called the exponent) represents essentially how many zeros there are in an measurable amount.

Do you add the powers in scientific notation?

When adding or subtracting numbers in scientific notation, the exponents must be the same. The exponents are the same, so add the coefficients. When adding or subtracting numbers in scientific notation, the exponents must be the same.


2 Answers

You have to find the appropriate character from the code page you are using, for example UTF-8:

string superScript2 = "²";

There is no such thing as formatting in a string, it is just all data.

like image 58
Patrick Hofman Avatar answered Oct 26 '22 21:10

Patrick Hofman


Try this:

    public static string Eng(this double x, string format="g")
    {
        const string sup_signs = "⁺⁻⁼⁽⁾ⁿ";
        const string sup_digits = "⁰¹²³⁴⁵⁶⁷⁸⁹";

        if(double.IsNaN(x) || double.IsInfinity(x))
        {
            return x.ToString();
        }

        int num_sign = Math.Sign(x);
        x = Math.Abs(x);
        // group exponents in multiples of 3 (thousands)
        int exp = (int)Math.Floor(Math.Log(x, 10)/3)*3;
        // otherwise use:
        // int exp = (int)Math.Floor(Math.Log(x, 10));
        // and handle the exp==1 case separetly to avoid 10¹
        x*= Math.Pow(10, -exp);
        int exp_sign = Math.Sign(exp);
        exp = Math.Abs(exp);
        // Build the exponent string 'dig' from right to left
        string dig = string.Empty;
        while(exp>0)
        {
            int n = exp%10;
            dig = sup_digits[n] + dig;
            exp = exp/10;
        }
        // if has exponent and its negative prepend the superscript minus sign
        if(dig.Length>0 && exp_sign<0)
        {
            dig = sup_signs[1] + dig;
        }
        // prepend answer with minus if number is negative
        string sig = num_sign<0 ? "-" : "";            
        if(dig.Length>0)
        {
            // has exponent
            return $"{sig}{x.ToString(format)}×10{dig}";
        }
        else
        {
            // no exponent
            return $"{sig}{x.ToString(format)}";
        }
    }

As a test case run

static void Main(string[] args)
{
    // Type code here.
    double x = Math.PI/50e5;
    for(int i = 0; i < 20; i++)
    {
        // Format output to 12 wide column, right aligned
        Debug.WriteLine($"{ Eng(x, "g4"),12}");
        x*=50;
    }
}

with the output:

  628.3×10⁻⁹
  31.42×10⁻⁶
  1.571×10⁻³
  78.54×10⁻³
       3.927
       196.3
   9.817×10³
   490.9×10³
   24.54×10⁶
   1.227×10⁹
   61.36×10⁹
  3.068×10¹²
  153.4×10¹²
   7.67×10¹⁵
  383.5×10¹⁵
  19.17×10¹⁸
  958.7×10¹⁸
  47.94×10²¹
  2.397×10²⁴
  119.8×10²⁴

By no means optimized, but it does the job. The exponents are in engineering form (multiples of 3 only, in order to avoid things like 10¹). As a bonus, the number can be formatted to a specific number of significant digits by supplying a format code like g4 or g5 for 4 or 5 digits respectively.

  • It can handle negative or positive numbers
  • It can handle negative or positive exponents of 10
  • In can format the mantissa
  • It can handle NAN or Inf.
  • It's in extension form for re-usability
like image 40
John Alexiou Avatar answered Oct 26 '22 22:10

John Alexiou