# Convert value from scientific notation to decimal in shell?

How to convert value from scientific notation to decimal in shell? (preferred C shell)

Also I'd want to convert it from e-12 to e-9 and then shell

42.53e-12 to 0.04253. I have to do this for a list.

• `42.53e-12` can not be presented as `0.04253`. Also, this "to do this for a list" requires detailed description/sample – RomanPerekhrest Feb 11 '18 at 21:32

`printf` will do this for you, from shell.

`````` \$ FOO=42.53e-12
\$ BAR=\$(printf "%.14f" \$FOO)
\$ echo \$BAR
0.00000000004253
\$
``````

In ancient+arcane C-shell, this would be.

``````\$ set FOO=42.53e-12
\$ set BAR=`printf "%.14f" \$FOO`
\$ echo \$BAR
0.00000000004253
\$
``````

# shell

Many shells (specially ancient+arcane csh) don't understand floating point arithmetic.

In most shells there is a builtin `printf` which understands "scientific format".

``````\$ printf '%5.0f\n' '1e3'
1000
``````

But all printf could not do math:

``````\$ printf '%5.0f\n' '1e3+1e3'
printf: ‘1e3+1e3’: value not completely converted
``````

There is a workaround in two steps for csh. - First
Convert the number to a decimal of less than 18 digits (for a 53 bit significant of a 64 bit float)[a]:

``````    % printf "%.18f\n" "42.53e-12"
0.000000000042530000
``````
• Second
Multiply by `1e3` (as you requested) and print again:

``````% printf '%.15f\n' "`printf "%.18f" "42.53e-12"`e3"
0.000000042530000
``````

Of course, `printf` in `csh` is an external utility with its own float size (64 bit?) and may be different for a different OS.

# Math tools.

To do math (other than the shell) it is natural to think of `bc`, but bc has its own limitations (doesn't understand the `e` as exponent, it has to be converted to `10^`). Read this.

But awk could do it:

``````% echo 42.53e-12 | awk '{printf("%.15f\n", \$1*1e3)}'
0.000000042530000
``````

Don't expect more than 15 correct digits as awk use a 53 bit significant. To have more, you need the GNU version of awk with the arbitrary precision module compiled in.

``````% echo 42.53e-12 | awk -M -v PREC=134 '{printf("%.40g\n", \$1*1e3)}'
4.253e-08
``````

That is 134 binary bits for (up to) 40 decimal digits. As a decimal:

``````% echo 42.53e-12 | awk -M -v PREC=134 '{printf("%.40f\n", \$1*1e3)}'
0.0000000425300000000000000000000000000000
``````

# list

I have to do this for a list.

But give no details of what kind of list it is. If the list is inside a file (not as a shell variable) you need nothing from `csh` (or any other shell) except to execute this:

``````% awk '{printf("%.15f\n", \$1*1e3)}' <file
``````

The same precision limitations as above still apply.

[a] Actually, to be technically exact, you should limit the number of digits with the `%g` printf format first, so the pedantically correct solution is a three level transformation.

In any reasonable shell (ksh,bash,zsh) this will work:

``````\$ bash -c 'printf "%.15f\n" "\$(printf "%.18f" "\$( printf "%.18g" "42.53e-12")" )e3"'
0.000000042530000
``````

But quoting a double `` `` is really awkward in csh, and csh use `set` to assign to vars. In short, this will work for `csh`:

``````\$ csh -c 'set a=`printf "%.18g" "42.53e-12"`; set a=`printf "%.18f" "\$a"`; printf "%.18f\n" "\${a}e3"'
0.000000042530000000
``````

But, I really, really! think that you should avoid csh.

Might not be the best solution but I managed to do it with a little hack. You can do something like this -

``````scientific='42.53e-12'
base=\$(echo \$scientific | cut -d 'e' -f1)
exp=\$((\$(echo \$scientific | cut -d 'e' -f2)*1))
converted=\$(bc -l <<< "\$base*(10^\$exp)")
>> .00000000004253000000
``````