Velocity Reviews > Perl > Floating point

# Floating point

Sajan
Guest
Posts: n/a

 01-26-2004
Hi
I am new to perl.
I have a problem with floating point arithmetic.

I am using a a variable \$time_now which i want to increment by 0.001
everytime in a while loop until the \$tot_time is equal to \$time_now.

I am using

\$accuracy = 0.001;
\$time_now = 0.0;
\$tot_time = 10.0;

while (\$time_now <= \$tot_time)
{
#couple of calculations based on \$time_now;
\$time_now = \$time_now + \$accuracy;
}

now the problem i am facing is

\$time_now becomes 0.0019999999993, 0.0029999999993 etc
but for my calculations i expect only 0.001, 0.002 etc upto 10.0.
In short i dont expect such an accurate precision

Please let me know how to overcome this.

Sajan.

Carsten Aulbert
Guest
Posts: n/a

 01-26-2004

Sajan wrote:

> Please let me know how to overcome this.

Why not simply use an integer counter a la
\$time_count = 0;

let it rund till \$time_count < 10000 (e.g.)

and then just add this up with \$time_count++ and finally multiply by
\$accuracy to get the wanted value.

HTH
CA

Tassilo v. Parseval
Guest
Posts: n/a

 01-26-2004
Also sprach Sajan:

> I am new to perl.
> I have a problem with floating point arithmetic.
>
> I am using a a variable \$time_now which i want to increment by 0.001
> everytime in a while loop until the \$tot_time is equal to \$time_now.
>
> I am using
>
> \$accuracy = 0.001;
> \$time_now = 0.0;
> \$tot_time = 10.0;
>
> while (\$time_now <= \$tot_time)
> {
> #couple of calculations based on \$time_now;
> \$time_now = \$time_now + \$accuracy;
> }
>
> now the problem i am facing is
>
> \$time_now becomes 0.0019999999993, 0.0029999999993 etc
> but for my calculations i expect only 0.001, 0.002 etc upto 10.0.
> In short i dont expect such an accurate precision

Non-precision rather. Floating point numbers are usually just an
approximation. That means there might not be (and usually there is no)
exact representation of 0.001.

> Please let me know how to overcome this.

You can ask perl to round the number to the desired amount of decimals:

while (\$time_now <= \$tot_time) {
\$time_now += \$accuracy;
printf "%.3f\n", \$time_now;
}

With 'sprintf' you can assign the rounded number:

my \$rounded = sprintf "%.3f", \$time_now;

The implication of all that is that you should never do

if (\$num == 0.001)

because most of the time this condition wont be true. Instead, use
a delta to allow a certain tolerance:

my \$delta = 1E-8;
if ( abs(\$num - 0.001) <= \$delta )

Tassilo
--
\$_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_\$;//::niam/s~=)]3[))_\$-3(rellac(=_\$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus}) !JAPH!qq(rehtona{tsuJbus#;
\$_=reverse,s+(?<=sub).+q#q!'"qq.\t\$&."'!#+sexisexi ixesixeseg;y~\n~~dddd;eval

Jürgen Exner
Guest
Posts: n/a

 01-26-2004
Sajan wrote:
> Hi
> I am new to perl.

It appears you are new to programming, too, because your problem is in no
way specific to Perl.

> I have a problem with floating point arithmetic.
> I am using a a variable \$time_now which i want to increment by 0.001
> everytime in a while loop until the \$tot_time is equal to \$time_now.

You must have missed the first law of computer numerics
Thou shalt not use floating point for precision calculations.
In particular comparing for equality is just stupid.

> \$time_now becomes 0.0019999999993, 0.0029999999993 etc
> but for my calculations i expect only 0.001, 0.002 etc upto 10.0.
> In short i dont expect such an accurate precision
>
> Please let me know how to overcome this.

You use an epsilon interval. Further details see any book about Introduction
to Programming (if it's worth its money), about computer numerics, or just
"perldoc -q 9999".

jue

ctcgag@hotmail.com
Guest
Posts: n/a

 01-26-2004
http://www.velocityreviews.com/forums/(E-Mail Removed) (Sajan) wrote:
> Hi
> I am new to perl.
> I have a problem with floating point arithmetic.
>
> I am using a a variable \$time_now which i want to increment by 0.001
> everytime in a while loop until the \$tot_time is equal to \$time_now.
>
> I am using
>
> \$accuracy = 0.001;
> \$time_now = 0.0;
> \$tot_time = 10.0;
>
> while (\$time_now <= \$tot_time)
> {
> #couple of calculations based on \$time_now;
> \$time_now = \$time_now + \$accuracy;
> }
>
> now the problem i am facing is
>
> \$time_now becomes 0.0019999999993, 0.0029999999993 etc
> but for my calculations i expect only 0.001, 0.002 etc upto 10.0.
> In short i dont expect such an accurate precision
>
> Please let me know how to overcome this.

Change you units from seconds to milliseconds (or from milliseconds
to microseconds, or whatever). If you need to multiply/divide by 1000
after/before input/ouput, do that. But in the loop, just deal with
integers.

Xho

--
Usenet Newsgroup Service New Rate! \$9.95/Month 50GB