Subject: | interger overflow on 32-bit architectures |
Date: | Mon, 13 Aug 2018 13:19:37 +0200 |
To: | bug-Date-Manip [...] rt.cpan.org |
From: | pgajdos <pgajdos [...] suse.cz> |
Hello,
thanks for Date-Manip.
I stumbled over several failing tests for me running the testsuite on
i586. I think at least one issue, if not only, lies in
days_since_1BC(), as demonstrated below.
$ cat test.pl
#!/bin/perl
require 5.010000;
use strict;
use warnings;
use integer;
sub days_since_1BC {
my($arg) = @_;
if (ref($arg)) {
my($y,$m,$d) = @$arg;
$m = ($m + 9) % 12;
$y = $y - $m/10;
return 365*$y + $y/4 - $y/100 + $y/400 + ($m*306 + 5)/10 + ($d - 1) - 305;
} else {
my $g = $arg + 305;
print "g = $g\n";
my $y = (10000*$g + 14780)/3652425;
my $res = 10000*$g;
print "10000*$g = $res\n";
print "y = $y\n";
my $ddd = $g - (365*$y + $y/4 - $y/100 + $y/400);
if ($ddd < 0) {
$y = $y - 1;
$ddd = $g - (365*$y + $y/4 - $y/100 + $y/400);
}
my $mi = (100*$ddd + 52)/3060;
my $mm = ($mi + 2) % 12 + 1;
$y = $y + ($mi + 2)/12;
my $dd = $ddd - ($mi*306 + 5)/10 + 1;
return [$y, $mm, $dd];
}
}
my $y = 2009;
my $m = 8;
my $d = 15;
print "YMD: $y $m $d\n";
my $d1bc = days_since_1BC([$y,$m,$d]);
print "D1BC: $d1bc\n";
my $ymd = days_since_1BC($d1bc);
print "YMD: @$ymd\n";
$
x86_64
$ perl test.pl
YMD: 2009 8 15
D1BC: 733634
g = 733939
10000*733939 = 7339390000
y = 2009
YMD: 2009 8 15
$
i586
$ perl test.pl
YMD: 2009 8 15
D1BC: 733634
g = 733939
10000*733939 = -1250544592
y = -342
YMD: 1997 2 2
$