0

How to format a [double] floating point number in Engineering Notation?

PS> Engr(10e-8)
100 nano

PS> Engr(10e-7)
1 micro
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
Bimo
  • 5,987
  • 2
  • 39
  • 61

1 Answers1

2
function Engr([double] $d) {
    [double] $exponent = [Math]::Log10([Math]::Abs($d))
    if ([Math]::Abs($d) -ge 1) {
        switch([int][Math]::Floor($exponent)) {
            0  {return $d.ToString()}
            1  {return $d.ToString()}
            2  {return $d.ToString()}
            3  {return ($d / 1e3).ToString()  + "k"}
            4  {return ($d / 1e3).ToString()  + "k"}
            5  {return ($d / 1e3).ToString()  + "k"}
            6  {return ($d / 1e6).ToString()  + "M"}
            7  {return ($d / 1e6).ToString()  + "M"}
            8  {return ($d / 1e6).ToString()  + "M"}
            9  {return ($d / 1e9).ToString()  + "G"}
            10 {return ($d / 1e9).ToString()  + "G"}
            11 {return ($d / 1e9).ToString()  + "G"}
            12 {return ($d / 1e12).ToString() + "T"}
            13 {return ($d / 1e12).ToString() + "T"}
            14 {return ($d / 1e12).ToString() + "T"}
            15 {return ($d / 1e15).ToString() + "P"}
            16 {return ($d / 1e15).ToString() + "P"}
            17 {return ($d / 1e15).ToString() + "P"}
            18 {return ($d / 1e18).ToString() + "E"}
            19 {return ($d / 1e18).ToString() + "E"}
            20 {return ($d / 1e18).ToString() + "E"}
            21 {return ($d / 1e21).ToString() + "Z"}
            22 {return ($d / 1e21).ToString() + "Z"}
            23 {return ($d / 1e21).ToString() + "Z"}
            default {return ($d / 1e24).ToString() + "Y"}     
        }
    }
    elseif ([Math]::Abs($d) -gt 0) {

        switch ([int][Math]::Floor($exponent)) {
            -1  {return ($d * 1e3).ToString()  + "m"}
            -2  {return ($d * 1e3).ToString()  + "m"}
            -3  {return ($d * 1e3).ToString()  + "m"}
            -4  {return ($d * 1e6).ToString()  + "µ"}
            -5  {return ($d * 1e6).ToString()  + "µ"}
            -6  {return ($d * 1e6).ToString()  + "µ"}
            -7  {return ($d * 1e9).ToString()  + "n"}
            -8  {return ($d * 1e9).ToString()  + "n"}
            -9  {return ($d * 1e9).ToString()  + "n"}
            -10 {return ($d * 1e12).ToString() + "p"}
            -11 {return ($d * 1e12).ToString() + "p"}
            -12 {return ($d * 1e12).ToString() + "p"}              
            -13 {return ($d * 1e15).ToString() + "f"}
            -14 {return ($d * 1e15).ToString() + "f"}
            -15 {return ($d * 1e15).ToString() + "f"}
            -16 {return ($d * 1e15).ToString() + "a"}
            -17 {return ($d * 1e15).ToString() + "a"}
            -18 {return ($d * 1e15).ToString() + "a"}
            -19 {return ($d * 1e15).ToString() + "z"}
            -20 {return ($d * 1e15).ToString() + "z"}
            -21 {return ($d * 1e15).ToString() + "z"}
            default {return ($d * 1e15).ToString() + "y"}
        }
    }
    else
    {
        return "0";
    }
}
Bimo
  • 5,987
  • 2
  • 39
  • 61
  • 2
    Just a matter of improvement, you can use ranges for your switches: `-19..-21 { <#stuff#> }` – Maximilian Burszley Nov 28 '17 at 15:57
  • I suspect code will have edge case problems with values just below a power-of-1000. With `$d.ToString()` is not the default precision 6 digits? So printing 999.999999999 will print `"1000.000000"` rather than `"1.000000k"`. – chux - Reinstate Monica Nov 28 '17 at 16:34
  • BTW: Perhaps simplify the `switch` with `([int][Math]::Floor($exponent))/3`? – chux - Reinstate Monica Nov 28 '17 at 16:38
  • The precision should be the same as c# double since $d is cast to [double] type. Good suggestion on using range for case statement... – Bimo Nov 28 '17 at 16:41
  • if anybody knows a better way to implement this, by all means post it below... I was just hoping that somebody would tell me its a built in .NET function so that I don't need to include special code from the command line. The ENGR button is built into my scientific calculator, why not .NET? – Bimo Nov 28 '17 at 16:43
  • Incidentally, for those that don't know, the powershell prompt is a great replacement for the annoying Metro calculator application. – Bimo Nov 28 '17 at 16:54
  • Two previous question/answers with code for C# - here https://stackoverflow.com/a/808295/478656 and here https://stackoverflow.com/a/7011600/478656 - which might be ported to PS – TessellatingHeckler Nov 28 '17 at 17:26