如何用"int",模数和除法简化表达式?

Jas*_*nes 3 algorithm math perl

下面的脚本计算十进制数的时差,但是我得到一个舍入误差,所以我想这是因为我最后的转换很糟糕.

有些东西告诉我,表达式可以简化,但是在这个特殊情况下,当我有int,模数和除法时,数学规则是什么?

#!/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;
}
Run Code Online (Sandbox Code Playgroud)

Typ*_*eIA 6

您已经正确计算$m1并且$m2自午夜起已经过了几分钟.那么为什么不简单地以小时为单位返回时差:

return ($m2 - $m1) / 60.0;
Run Code Online (Sandbox Code Playgroud)

就"数学规则"而言,也许有助于看看你return和我的,看看为什么它们是等价的(忽略舍入):

$h + ($h * 60 + $m2 - $m1) % 60 / 60
Run Code Online (Sandbox Code Playgroud)

请注意,该($h * 60) % 60值为零,因此该术语基本上消失了,留下:

$h + ($m2 - $m1) % 60 / 60
Run Code Online (Sandbox Code Playgroud)

现在想想如何$h计算:它是($m2 - $m1)除以60 的商,除去余数(因为int()).在另一方面,($m2 - $m1) % 60 就是完全该除法的余数.所以上面的表达式基本上只是添加了你从中丢弃的余数部分$h.因此它具有与之相同的结果

($m2 - $m1) / 60
Run Code Online (Sandbox Code Playgroud)


Thi*_*Not 6

您可以使用Time :: Piece进行简单的日期/时间计算:

#!/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;
Run Code Online (Sandbox Code Playgroud)

输出:

7.75
Run Code Online (Sandbox Code Playgroud)

注意,$diff它实际上是一个Time :: Seconds对象.

  • 我认为OP正在做这种运动,但如果没有,这个答案绝对是生产使用的更好解决方案.避免在任何可能的情况下重新发明轮子,*特别是*在日期/时间计算方面,这是众所周知的粘性主题. (2认同)