Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 350
  • Last Modified:

Performing math on perl variables...

I have perl code that opens a flat data file and
reads in two colmuns of numbers.  The code to do
this is as follows:

open(infile,'<my.dat');
#example of data being read in:
#                        lmbhux03:GBL_CPU_TOTAL_UTIL  lmbhux03:GBL_CPU_IDLE_UTIL

#01/01/03 09:00 Wed             88.600                       11.390
#01/02/03 09:00 Thu             44.880                       55.100

seek(infile,80,0); #mv pointer 80 bytes from 0 to start 1st true record.
$rec_count=0;
$byte_count=0;
while(<infile>){
   read(infile,$date,8);
   print "date=$date\n";

   seek(infile,23,1); #mv pointer 80 bytes from the last pointer
   read(infile,$time1,6);
$t1=$time+12.0;          #t1 is not working!!!
   print ("time1= ***$time1*** - > $time1 + 12=$t1\n");

   seek(infile,40,1); #mv pointer 80 bytes from the last pointer
}
close(infile);

As you can see in the above, the variable "t1" is not
working.  Is this because it is floating point data?

Please advise.
0
afsac
Asked:
afsac
  • 3
  • 2
  • 2
  • +1
1 Solution
 
grg99Commented:
You should be doing something like fscanf to extract your variables.  Something like:

float Time1, Time2;  char Date[10], Time[10], Day[10];

fscanf( infile, "%s %s %s %f %f", Date, Time, Day, &Time1, &Time2 );

0
 
grg99Commented:
Sorry!  Thought this was the C group!

in Perl:

$Line = <INFILE>;

if( /(.+?)\s+(.+?)\s+(.+?)\s+(.+?)\s+(.+?)\s+$/ ) {
$date = $1;  $time1 = $4; $time2 = $5;
}

0
 
jmcgOwnerCommented:
Yes, it does look like you're trying to coerce Perl into looking like C.

The other thing that I'm suspicious of is the intermingled seeks and reads with byte counts. Do you have fixed-length records that you're dealing with? No line terminations? In that case, I'd still prefer to read in an entire record from the file at a time and parse the record contents separately.

Even if everything else you're doing was correct, your attempt to add 12.0 to a string containing a time representation is not going to do what you want. The time as you have it contains a leading space and a colon separating the hours from the minutes. This will have to be interpreted before it can be used in arithmetic.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
afsacAuthor Commented:
Please notice the example of the data file i'm reading
in.  It is not time, but a number. I tried reading
the entire record, and then parcing it out, but the
math didn't work their either.

I basically want to read the numbers in, and keep
a total of each as read then devide by the number of
records read in.  

Thank you for your quick response.
0
 
jmcgOwnerCommented:
Sorry, I overlooked the seek by 23 bytes.

If you have a value in a scalar that looks like an integer or a floating point number, Perl will let you do arithmetic on it. If it doesn't look like a number, Perl will still let you do arithmetic with it, but it will treat the string as if it contained the value 0.

A leading space is sufficient to mess things up.

I'd approach this problem somewhat like this:

#! /usr/bin/env perl

open(infile,'<my.dat');

#example of data being read in:
#                        lmbhux03:GBL_CPU_TOTAL_UTIL  lmbhux03:GBL_CPU_IDLE_UTIL

#01/01/03 09:00 Wed             88.600                       11.390
#01/02/03 09:00 Thu             44.880                       55.100

$rec_count=0;

while(<infile>){
  @f = split;
  next unless @f == 5;

  $date = $f[0];
  print "date=$date\n";

  $time = $f[3];
  $t1=$time+12.0;
  print ("time1= ***$time1*** - > $time1 + 12=$t1\n");

  $accum += $t1;
  $rec_count++;
}
close(infile);

print "avg=", $accum/$rec_count;
0
 
wilcoxonCommented:
This should do what you're asking.

open(infile,'<my.dat');
#example of data being read in:
#                        lmbhux03:GBL_CPU_TOTAL_UTIL lmbhux03:GBL_CPU_IDLE_UTIL

#01/01/03 09:00 Wed             88.600                       11.390
#01/02/03 09:00 Thu             44.880                       55.100

my ($sum1, $sum2, $count) = (0,0,0);
while (<infile>) {
    chomp;
    next unless /([\d\/]+)\s+([\d:]+)\s+(\w+)\s+([\d\.]+)\s+([\d\.]+)\s*$/;
    my ($date, $time, $wday, $num1, $num2) = ($1, $2, $3, $4, $5);
    # $time will have hh:mm so will need further parsing if you want to modify it
    # but you had said it was the numbers you want tracked
    print "date=$date\ntime = "
    $sum1 += $num1;
    $sum2 += $num2;
    $count++;
}

print "avg1 = ", $sum1/$count, "\navg2 = ", $sum2/$count, "\n";
0
 
afsacAuthor Commented:
This worked the best, but I have one more quick question.
Now that I have it working i'm getting a number like
45.64, how do I use perl to round this number up to 46?

Thank you!
0
 
jmcgOwnerCommented:
$x = 45.64;
$y = sprintf "%4.0f", $x;
print $y,"\n";

0

Featured Post

Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

  • 3
  • 2
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now