Problems? Is your data what you think it is? PerlMonks

### Bignum breaks Time::Local?

by cunningrat (Acolyte)
 on Nov 05, 2012 at 22:45 UTC Need Help??
cunningrat has asked for the wisdom of the Perl Monks concerning the following question:

This drove me nuts for several hours today until I figured it out. Sample code below:

```#!/usr/bin/perl
use strict;
use Time::Local;
#use bignum(p => -3);

my \$key='121005';
print \$key." ==> ".convtime(\$key)."\n";

sub convtime {
my @months=qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
my @dow=qw{Sun Mon Tue Wed Thu Fri Sat};
my \$date=@_[0];
my \$year=substr \$date,0,2;
\$year += 100;
my \$month=substr \$date,2,2;
\$month -= 1;
my \$day=substr \$date,4;
my \$gmt = timegm(0,0,0,\$day,\$month,\$year);
my @gmtime = gmtime(\$gmt);
my \$convstring=\$dow[\$gmtime[6]]." ".\$months[\$gmtime[4]]." ".\$gmtime[3
+];
return \$convstring
}

If you run this, it returns "121005 ==> Fri Oct 5", as it should. If you uncomment the "use bignum" line, however, it returns "121005 ==> Mon Jan 23".

What I *think* (after some testing) is going on is that the Math::BigInt and Math::Bigfloat overload the arithmetic operators, which breaks timegm().

Is this expected behavior and/or documented anywhere?

Replies are listed 'Best First'.
Re: Bignum breaks Time::Local? (constants)
by tye (Sage) on Nov 05, 2012 at 23:34 UTC
What I *think* (after some testing) is going on is that the Math::BigInt and Math::Bigfloat overload the arithmetic operators, which breaks timegm().

No, overloading of operators is based only on the arguments given to them. But 'use bignum;' overloads numeric constants. So, for example:

```    timegm(0,0,0,\$day,\$month,\$year)

becomes

```    timegm( Math::BigInt->new(0), Math::BigInt->new(0),
Math::BigInt->new(0), \$day, \$month, \$year )

And Math::BigInt might not be careful enough to have Math::BigInt->new(0) act enough like just plain 0 for timegm()'s usage (not surprisingly).

Is this expected behavior and/or documented anywhere?

It sounds like you probably read the first sentence of the bignum documentation. Perhaps you failed to go on to read the second sentence.

This makes bignum.pm a cute demonstration that can be convenient for a one-liner. Otherwise, you should just use Math::BigInt and/or Math::BigFloat directly, so you can avoid making every single time you use a numeric constant magically turn into a complex object that infects the results of any computations that touch it.

Most of the time you only even need to call Math::BigInt->new() once, so a wrapper like bignum.pm seems of dubious benefit. bignum.pm should probably come with a big warning like "This transforms simple-looking Perl code into something very different and can easily break code".

- tye

Re: Bignum breaks Time::Local?
by tobyink (Abbot) on Nov 05, 2012 at 22:54 UTC

I see the bug you describe in Perl 5.8 and 5.10, but it seems to be fixed in 5.12, 5.14 and 5.16.

Having checked the changelogs for bignum and Time::Local and also perl5120delta I can't figure out what exactly fixed this.

perl -E'sub Monkey::do{say\$_,for@_,do{(\$monkey=[caller(0)]->[3])=~s{::}{ }and\$monkey}}"Monkey say"->Monkey::do'
That explains it, Toby. Thanks. (I'm stuck using perl 5.8, unfortunately.)

Create A New User
Node Status?
node history
Node Type: perlquestion [id://1002396]
Approved by Kenosis
help
Chatterbox?
 [stevieb]: Damn... just wasted two hours wondering why num 23 wasn't setting bit 5 in a register. I was working on the decimal, but the register holds BCD numbers. Sigh.

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (8)
As of 2018-05-22 16:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
World peace can best be achieved by:

Results (165 votes). Check out past polls.

Notices?