Convert value from scientific notation to decimal in shell? - Unix & Linux Stack Exchange most recent 30 from unix.stackexchange.com 2019-09-21T21:42:38Z https://unix.stackexchange.com/feeds/question/423453 https://creativecommons.org/licenses/by-sa/4.0/rdf https://unix.stackexchange.com/q/423453 2 Convert value from scientific notation to decimal in shell? cHiRaG https://unix.stackexchange.com/users/275476 2018-02-11T21:03:48Z 2018-10-20T21:07:28Z <p>How to convert value from scientific notation to decimal in shell? (preferred C shell)</p> <p>Also I'd want to convert it from e-12 to e-9 and then shell</p> <p>42.53e-12 to 0.04253. I have to do this for a list.</p> https://unix.stackexchange.com/questions/423453/-/423457#423457 5 Answer by steve for Convert value from scientific notation to decimal in shell? steve https://unix.stackexchange.com/users/104877 2018-02-11T21:27:20Z 2018-02-11T21:56:04Z <p><code>printf</code> will do this for you, from shell.</p> <pre><code> \$ FOO=42.53e-12 \$ BAR=\$(printf "%.14f" \$FOO) \$ echo \$BAR 0.00000000004253 \$ </code></pre> <p>In ancient+arcane C-shell, this would be.</p> <pre><code>\$ set FOO=42.53e-12 \$ set BAR=`printf "%.14f" \$FOO` \$ echo \$BAR 0.00000000004253 \$ </code></pre> https://unix.stackexchange.com/questions/423453/-/476760#476760 0 Answer by markroxor for Convert value from scientific notation to decimal in shell? markroxor https://unix.stackexchange.com/users/204519 2018-10-20T16:41:10Z 2018-10-20T16:41:10Z <p>Might not be the best solution but I managed to do it with a little hack. You can do something like this - </p> <pre><code>scientific='42.53e-12' base=\$(echo \$scientific | cut -d 'e' -f1) exp=\$((\$(echo \$scientific | cut -d 'e' -f2)*1)) converted=\$(bc -l &lt;&lt;&lt; "\$base*(10^\$exp)") &gt;&gt; .00000000004253000000 </code></pre> https://unix.stackexchange.com/questions/423453/-/476796#476796 1 Answer by Isaac for Convert value from scientific notation to decimal in shell? Isaac https://unix.stackexchange.com/users/265604 2018-10-20T21:07:28Z 2018-10-20T21:07:28Z <h1>shell</h1> <p>Many shells (specially ancient+arcane csh) don't understand floating point arithmetic.</p> <p>In most shells there is a builtin <code>printf</code> which understands "scientific format".</p> <pre><code>\$ printf '%5.0f\n' '1e3' 1000 </code></pre> <p>But all printf could <strong>not</strong> do math:</p> <pre><code>\$ printf '%5.0f\n' '1e3+1e3' printf: ‘1e3+1e3’: value not completely converted </code></pre> <p>There is a workaround in two steps for csh. - First<br> Convert the number to a decimal of less than 18 digits (for a 53 bit significant of a 64 bit float)<sup>[a]</sup>:</p> <pre><code> % printf "%.18f\n" "42.53e-12" 0.000000000042530000 </code></pre> <ul> <li><p>Second<br> Multiply by <code>1e3</code> (as you requested) and print again:</p> <pre><code>% printf '%.15f\n' "`printf "%.18f" "42.53e-12"`e3" 0.000000042530000 </code></pre></li> </ul> <p>Of course, <code>printf</code> in <code>csh</code> is an external utility with its own float size (64 bit?) and may be different for a different OS.</p> <h1>Math tools.</h1> <p>To do math (other than the shell) it is natural to think of <code>bc</code>, but bc has its own limitations (doesn't understand the <code>e</code> as exponent, it has to be converted to <code>10^</code>). <a href="https://stackoverflow.com/a/12882612/9110606">Read this</a>.</p> <p>But awk could do it:</p> <pre><code>% echo 42.53e-12 | awk '{printf("%.15f\n", \$1*1e3)}' 0.000000042530000 </code></pre> <p>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.</p> <pre><code>% echo 42.53e-12 | awk -M -v PREC=134 '{printf("%.40g\n", \$1*1e3)}' 4.253e-08 </code></pre> <p>That is 134 binary bits for (up to) 40 decimal digits. As a decimal:</p> <pre><code>% echo 42.53e-12 | awk -M -v PREC=134 '{printf("%.40f\n", \$1*1e3)}' 0.0000000425300000000000000000000000000000 </code></pre> <h1>list</h1> <p>In your question, you state:</p> <blockquote> <p>I have to do this for a list.</p> </blockquote> <p>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 <code>csh</code> (or any other shell) except to execute this:</p> <pre><code>% awk '{printf("%.15f\n", \$1*1e3)}' &lt;file </code></pre> <p>The same precision limitations as above still apply.</p> <hr> <p><sup><strong>[a]</strong></sup> Actually, to be technically exact, you should limit the number of digits with the <code>%g</code> printf format first, so the pedantically correct solution is a three level transformation.</p> <p>In any reasonable shell (ksh,bash,zsh) this will work:</p> <pre><code>\$ bash -c 'printf "%.15f\n" "\$(printf "%.18f" "\$( printf "%.18g" "42.53e-12")" )e3"' 0.000000042530000 </code></pre> <p>But quoting a double <code>` `</code> is really awkward in csh, and csh use <code>set</code> to assign to vars. In short, this will work for <code>csh</code>:</p> <pre><code>\$ csh -c 'set a=`printf "%.18g" "42.53e-12"`; set a=`printf "%.18f" "\$a"`; printf "%.18f\n" "\${a}e3"' 0.000000042530000000 </code></pre> <p>But, I really, really! think that you should avoid csh.</p>