bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: print float number


From: Greg Wooledge
Subject: Re: print float number
Date: Wed, 8 Jan 2014 08:11:48 -0500
User-agent: Mutt/1.4.2.3i

On Tue, Jan 07, 2014 at 10:36:54PM -0700, Bob Proulx wrote:
> lina wrote:
> > How can I print the 0.05, 0.10 ... 1.0 out, with the step of 0.05

Floating point does weird things.  A first approach might look like
this:

  awk 'BEGIN {for (i=0.05; i<=1.0; i+=0.05) printf ("%.2f\n", i)}'

But when I test this, it doesn't print 1.0.  Why?  Because floating
point arithmetic is not precise.  Adding 0.05 a bunch of times must
have given a value slightly over 1.0, which caused the loop to
terminate prematurely.  Results may vary on different machines,
depending on how the floating point numbers are stored internally.

If you want to get the expected number of steps, it's better to do
your counting with integers, and then present an altered view of
the data as output only:

  awk 'BEGIN {for (i=1; i<=20; i++) printf ("%.2f\n", i/20.0)}'

This one gives the expected result.

> Questions should go to the help-bash@gnu.org mailing list.

I've Cc'ed that.

> As to your question there are many ways to solve the problem.  I would
> be inclined to use the GNU seq command.
> 
>   $ seq 0.05 0.05 1.0

Note that seq(1) is nonstandard and won't be present on most machines.
Some BSD systems have jot(1) instead, which has a very different syntax.

(This in addition to suffering from the inherent imprecision of floating
point calculations, as Bob pointed out.)

> A related question about for loops in bash is discussed in this FAQ
> entry.  It isn't exactly your case but you might be interested in
> reading about the examples it provides.
> 
>   http://mywiki.wooledge.org/BashFAQ/018

There's also this page:

http://mywiki.wooledge.org/BashFAQ/022 -- How can I calculate with
floating point numbers instead of just integers?

The important point here is that Bash cannot add, subtract, multiply or
divide -- or even compare -- floating point numbers.  Any solution to
your question is going to require an external command that CAN do these
things (such as awk or seq).  I'd suggest awk as the go-to for this,
because it is a standard tool.

Of course, another answer to your question would be:

  printf %s\\n 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45 0.50 0.55 \
    0.60 0.65 0.70 0.75 0.80 0.85 0.90 0.95 1.00

But I'm guessing you don't want to do that.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]