user2808302
user2808302

Reputation:

Problems with digits in perl

I have an array (@BondLength) of integers with about 14 digits each:

1.4913648111713
1.49444103262725
1.49324445420032
1.49781641064584
1.49375901670919
1.48388476641551
1.49205194279556
1.48573550809019
1.48486531375745
1.48899462725693
1.48455818343371
1.49451162591664
1.49687975468973
1.48919777061343
1.48460466118088

I put them as the "data" field, plus their "average" (which I was also successfully able to get to 10-digits) into a subroutine:

sub stdev{
    my($data) = @_;
    my $average = $_;
    if(@$data == 1){
            return 0;
    }
    my $sqtotal = 0;
    foreach(@$data) {
            $sqtotal += ($average-$_) ** 2;
    }
    my $std = ($sqtotal / (@$data-1)) ** 0.5;
    return $std;
}

But when I call this subroutine with the necessary parameters:

 my $stdev = &stdev(@BondLength, $average);
printf("\nThe standard deviation NCABondLength: $stdev");

I get simply "0" outputted. I know it has values larger than zero up to the tenth-decimal place because I inputted it into Excel. What am I doing wrong in this script? (I have tinkered with it too much now by reading things off the web, but still keep getting "0").

Thanks.

Upvotes: 1

Views: 89

Answers (1)

edi_allen
edi_allen

Reputation: 1872

There is a problem in the second line of your code. You only assign one value from the list of parameters when you say my($data) = @_

This is the reason why your subroutine is returning with a zero value. you can try this instead.

#!/usr/bin/perl
use strict;
use warnings;

sub average {
    my $data = shift;
    my $count = @$data;
    my $sum;
    foreach my $element (@$data){
            $sum += $element;
    }
    return $sum / $count;
}


sub stdev {
    my ($average, $data) = @_;
    my $count = @$data;
    my $sum;
    my $variance;
    $sum += (($_ - $average) ** 2) foreach @$data;
    $variance = $sum / $count;
    return $variance ** 0.5;

}

}
my @array = qw/
1.4913648111713
1.49444103262725
1.49324445420032
1.49781641064584
1.49375901670919
1.48388476641551
1.49205194279556
1.48573550809019
1.48486531375745
1.48899462725693
1.48455818343371
1.49451162591664
1.49687975468973
1.48919777061343
1.48460466118088
/;

my $average = average(\@array);

my $deviation = stdev($average, \@array);

printf "Standard deviation is %.5f\n", $deviation; #print number to five decimal places.
#output 0.00461

Upvotes: 3

Related Questions