ameyer has asked for the wisdom of the Perl Monks concerning the following question:

I am attempting to Perlize a simple arithmetic expression that returns the pressure of CO2 gas in PSI needed to carbonate beer with a given number of gas volumes at a given temperature.

Volumes and Temperature are both known. So we have an expressions akin to:

X = 1 + 2^3 + 4*5 - 6*7^8

The full expression is:

Pressures=-16.6999-(0.0101059*Temperature)+(0.00116512*(Temperature^2) +)+(0.1733554*(Temperature)*(Volumes))+(4.24267*(Volumes))-(0.0684226* +(Volumes^2))

This works in Excel yielding a pressure of 12.27462975 for a temperature of 40 and 2.5 volumes of CO2. This does not work in Perl..

$temp = 40; $vol = 2.5; $pressure=(-16.6999)-(0.0101059*$temp)+(0.00116512*($temp^2))+(0.17335 +4*$temp*$vol)+(4.24267*$vol)-(0.0684226*($vol^2));

Here I get a pressure of 10.88687404 which is definitely wrong. (I am matching values on a known table for testing).

Is this an issue with floating point precision? I couldn't find a floating point module... Please help.

Janitored by Arunbear - added code tags, and changed title from 'Problems with floating point arithmetic. Please Help!'

Replies are listed 'Best First'.
Re: Convert arithmetic expression from Excel to Perl syntax
by kvale (Monsignor) on Nov 04, 2004 at 18:02 UTC
    Floating point in perl is fine, but the exponentiation operator in perl is **, not ^.
    $temp = 40; $vol = 2.5; $pressure=(-16.6999)-(0.0101059*$temp)+(0.00116512*($temp**2))+ (0.173354*$temp*$vol)+(4.24267*$vol)-(0.0684226*($vol**2));

    -Mark

Re: Convert arithmetic expression from Excel to Perl syntax
by ikegami (Patriarch) on Nov 04, 2004 at 18:00 UTC
    ^ doesn't mean "to the power of" in Perl, it means "exclusively ored with". Change $temp^2 to $temp*$temp and $vol^2 to $vol*$vol.

    Update: As other pointed out, Perl does have a power operator: ** (although it's not quite as fast, as you can see in Benchmarks I posted below).

      You can also di $temp**2 or $vol**2. Exactly the same, but faster.
        You're right that ** works too, but you're wrong about it being faster (at least on my system).
        # srand(0) is used to make sure both # subs are using the same input set. sub m1 { unless ($i1) { srand(0); $i1=1; } $n = rand; $p = $n ** 2; } sub m2 { unless ($i2) { srand(0); $i2=1; } $n = rand; $p = $n * $n; } use Benchmark; Benchmark::cmpthese(0, { '$n**2' => \&m1, '$n*$n' => \&m2, }); __END__ Rate $n**2 $n*$n $n**2 722292/s -- -29% $n*$n 1013884/s 40% --
Re: Convert arithmetic expression from Excel to Perl syntax
by ameyer (Initiate) on Nov 04, 2004 at 18:08 UTC
    Thanks! That did it.