Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to simplify expression with "int", modulus, and division?

The below script calculates the time difference in decimal number, but I get a rounding error, so I guess it is because of my very bad conversion at the end.

Question

Something tells me, that the expression can be simplified, but what are the math rules in this particular situation, when I have int, modulus and division?

#!/usr/bin/perl

print f("9:00", "16:45");

sub f {
    my $t1 = shift @_;
    my $t2 = shift @_;

    my $m1 = $1*60+$2 if $t1 =~ m/(\d\d?):(\d\d?)/;
    my $m2 = $1*60+$2 if $t2 =~ m/(\d\d?):(\d\d?)/;

    my $h = int(($m2-$m1)/60);

    return $h + ($h*60+$m2-$m1)%60/60;
}
like image 894
Jasmine Lognnes Avatar asked Jan 26 '26 17:01

Jasmine Lognnes


2 Answers

You have already correctly calculated $m1 and $m2 as minutes elapsed since midnight. So why not return the time difference in fractional hours as simply:

return ($m2 - $m1) / 60.0;

As far as the "math rules," maybe it will help to look at your return versus mine and see why they are equivalent (ignoring rounding):

$h + ($h * 60 + $m2 - $m1) % 60 / 60

Notice that ($h * 60) % 60 is zero, so this term essentially drops out, leaving:

$h + ($m2 - $m1) % 60 / 60

Now think about how $h was calculated: it is the quotient of ($m2 - $m1) divided by 60, dropping the remainder (because of int()). On the other hand, ($m2 - $m1) % 60 is exactly the remainder of this division. So the expression above is essentially just adding the remainder fraction, which you dropped from $h, back in. Therefore it has the same result as

($m2 - $m1) / 60
like image 172
TypeIA Avatar answered Jan 29 '26 09:01

TypeIA


You can use Time::Piece to do simple date/time calculations:

#!/usr/bin/perl

use strict;
use warnings;

use Time::Piece;

my $pattern = '%H:%M';

my $start = Time::Piece->strptime('09:00', $pattern);
my $end   = Time::Piece->strptime('16:45', $pattern);

my $diff  = $end - $start;
print $diff->hours;

Output:

7.75

Note that $diff is actually a Time::Seconds object.

like image 39
ThisSuitIsBlackNot Avatar answered Jan 29 '26 09:01

ThisSuitIsBlackNot