Reputation: 771
Having an issue with a portion of my perl script. I am pulling floating point values and i am trying to take the average but it seems to be converting my numbers to integers.
input looks like the following
L= 78 0.000E+00 0.000E+00 0.000E+00 0.000E+00 0.000E+00 0.000E+00 0.110E-07 0.258E-03
L= 79 0.000E+00 0.000E+00 0.000E+00 0.000E+00 0.000E+00 0.000E+00 0.181E-07 0.258E-03
L= 80 0.000E+00 0.000E+00 0.000E+00 0.000E+00 0.000E+00 0.000E+00 0.494E-05 0.290E-03
L= 81 0.000E+00 0.000E+00 0.000E+00 0.000E+00 0.000E+00 0.000E+00 0.112E-04 0.499E-03
L= 82 0.000E+00 0.000E+00 0.000E+00 0.000E+00 0.000E+00 0.000E+00 0.223E-04 0.500E-03
my code snip is the following
if ($B eq 'test')
{
($A) += ($_ =~ m/^\s+L=\s+\d+(?:\s+(\d+\.\d+E[-+]?\d+)){7}/);
}
now this is in the context of a loop and the value i am getting is the following as i read in the 7th value from the listing above for example. ( using lines 79-82
value 1
value 2
value 3
value 4
if i change the += to just a = i get the correct values but i cannot manipulate them at all without destroying the contents. How do i preserve the float value when doing operations?
Thanks in advance.
Upvotes: 2
Views: 125
Reputation: 528
The problem is you're adding to $A
an array, not a single element of the array. Add [0]
to the match like this:
$A += ($text =~ m/^\s+L=\s+\d+(?:\s+(\d+\.\d+E[-+]?\d+)){7}/)[0];
Upvotes: 1
Reputation: 8866
You've run into some weird Perl quirks.
In the expression ($A) = ($_ =~ /regexp/);
the regex is used in a list context because the left-hand side of the assignment is a list (a one element list, but still a list). In list context a successful regex match returns the list of captured groups (or, if the regex doesn't capture any groups, the list (1)
).
In your case, because you have a subgroup matching a float, $A
gets assigned that number.
The expression ($A) += ($_ =~ /regexp/);
looks almost the same but here the addition forces scalar context. This means the result of the regex will be 1 (true) if there is a match or the empty string (false) if there is none.
Again, in your case, you count the successful matches.
Now for your problem, you don't need any complicated regular expressions. You can simply split on whitespace and get the numbers in an array:
$_ =~ s/^\s+//; # delete any leading spaces
my @data = split(/\s+/, $_);
Upvotes: 4