Error: Bignum too big to convert into `long'

Hi,

I’ve got a bit of code that I borrowed from here
Re: Microsoft Timestamp (Active Directory) - Ruby - Ruby-Forum. I use it to convert MS
timestamps into a ruby Time object.
It works fine on Mac/Linux, but not on a Solaris SPARC system. The
error is “bignum too big to convert into `long’” and it occurs on the
line that begins…
Time.at(…)

I’m wondering if it’s because SPARC is Big-Endian that I get the error?

def self.ad2time(timestamp)
ad_epoch = 116_444_736_000_000_000
ad_multiplier = 10_000_000

# DEBUG
ap ad_epoch.class
puts "TIMESTAMP:  #{timestamp}"
ap timestamp.class

Time.at((timestamp.to_i - ad_epoch) / ad_multiplier)

end

On my Mac (Snow Leopard x86_64) the DEBUG output looks like this…
Fixnum < Integer
TIMESTAMP: 9223372036854775807
Net::BER::BerIdentifiedString < String

On Solaris SPARC it’s this…
Bignum < Integer
TIMESTAMP: 9223372036854775807
String < Object

Looks like on Solaris it forces the ‘ad_epoch’ to a Bignum instead of a
Fixnum? Should I try to cast it to a Fixnum on Solaris maybe?

Matt

On Aug 9, 2010, at 6:09 PM, Matt M. wrote:

error?

Time.at((timestamp.to_i - ad_epoch) / ad_multiplier)
end

On my Mac (Snow Leopard x86_64) the DEBUG output looks like this…

Ah, note the x86_64 part? That’s a 64-bit system so Fixnum holds up to
(2^62)-1

Looks like on Solaris it forces the ‘ad_epoch’ to a Bignum instead
of a Fixnum? Should I try to cast it to a Fixnum on Solaris maybe?

Matt

I suspect your SPARC system is only 32-bit where 2^30 and beyond
becomes Bignum.

If your timestamp is a Net::BER::BerIdentifiedString, perhaps it has
other properties that would help convert it into an Integer. (Notice
that both Fixnum and Bignum are subclasses of Integer)

On a 32-bit system, the divide between Fixnum and Bignum is:

irb> 230-1
=> 1073741823
irb> _.class
=> Fixnum
irb> 2
30
=> 1073741824
irb> _.class
=> Bignum

So 910692730085 is far too big for a Fixnum and Time.at is likely
wanting a number of seconds since 1970. Maybe you can see a pattern
if you compare Time.now.to_i on your platform with your expected
timestamp value.

-Rob

Rob B.
[email protected] http://AgileConsultingLLC.com/
[email protected] http://GaslightSoftware.com/

Brian C. wrote:

Time.at expects number of seconds since Jan 1, 1970.

The value you have given it is some time in the year 30,828 :slight_smile:

I suspect either your epoch or your multiplier is wrong.

Actually, I think you’re just reading a dummy value. Note the following:

irb(main):001:0> 9223372036854775807.to_s(16)
=> “7fffffffffffffff”

(i.e. the largest possible signed 64-bit value)

A quick Google suggests the Microsoft epoch is Jan 1, 1601, and Windows
uses 100-nanosecond ticks.

Using a 64-bit machine:

irb(main):002:0> require ‘time’
=> true
irb(main):003:0> Time.parse(“Jan 1 1601”)
=> Mon Jan 01 00:00:00 -0001 1601
irb(main):004:0> Time.parse(“Jan 1 1601”).to_i
=> -11644473525
irb(main):005:0> 11644473525 * 10_000_000
=> 116444735250000000

This value agrees with your epoch, within 75 leap seconds anyway.

If I use ldapsearch against an AD server, and look at attributes like
lastLogon, they give plausible answers when parsed using your function
(and succeed on a 32-bit machine)

Regards,

Brian.

Try your example values in irb:

irb(main):003:0> (9223372036854775807 - 116_444_736_000_000_000) /
10_000_000
=> 910692730085
irb(main):004:0> Time.at(910692730085)
RangeError: bignum too big to convert into long' from (irb):4:inat’
from (irb):4

Time.at expects number of seconds since Jan 1, 1970.

The value you have given it is some time in the year 30,828 :slight_smile:

I suspect either your epoch or your multiplier is wrong.

B.

Ah…

9223372036854775807 is the timestamp value assigned to the
“accountExpires” attribute in Active Directory when any account is set
to “Never Expire”.

It works fine on Linux/Mac but not on Solaris. I guess I’ll just
convert that timestamp to something like 12/31/2099 23:59:59 before I
run the Time.at.

Matt

----- Original Message -----
From: “Brian C.” [email protected]
To: “ruby-talk ML” [email protected]
Sent: Tuesday, August 10, 2010 7:53:24 AM
Subject: Re: Error: Bignum too big to convert into `long’

Try your example values in irb:

irb(main):003:0> (9223372036854775807 - 116_444_736_000_000_000) /
10_000_000
=> 910692730085
irb(main):004:0> Time.at(910692730085)
RangeError: bignum too big to convert into long' from (irb):4:in at’
from (irb):4

Time.at expects number of seconds since Jan 1, 1970.

The value you have given it is some time in the year 30,828 :slight_smile:

I suspect either your epoch or your multiplier is wrong.

B.

Matt M. wrote:

Ah…

9223372036854775807 is the timestamp value assigned to the
“accountExpires” attribute in Active Directory when any account is set
to “Never Expire”.

It works fine on Linux/Mac but not on Solaris. I guess I’ll just
convert that timestamp to something like 12/31/2099 23:59:59 before I
run the Time.at.

The largest Time you can have in a 32-bit value is:

irb(main):001:0> Time.at(0x7fffffff)
=> Tue Jan 19 03:14:07 +0000 2038
irb(main):002:0> Time.at(0x7fffffff+1)
RangeError: bignum too big to convert into long' from (irb):2:inat’
from (irb):2
from :0

Being Ruby, you are not constrained to using a numeric value. You could
use nil, or a symbol like :never, or a custom object which has
sufficient Time-like behaviours:

Never = Object.new
def Never.to_s; “Never”; end

Nope…that doesn’t work either.

def self.ad2time(timestamp)
# CONVERT NEVER EXPIRES ‘accountExpires’ NUMBER TO 12/31/2099 TO GET
AROUND BIGNUM PROBLEM ON SOLARIS
if timestamp == “9223372036854775807”
timestamp = “157468536000000000”
end
ad_epoch = 116_444_736_000_000_000
ad_multiplier = 10_000_000
Time.at((timestamp.to_i - ad_epoch) / ad_multiplier)
end

I ran through the calculation in irb and get this…

irb(main):003:0> 157468536000000000 - 116_444_736_000_000_000
=> 41023800000000000
irb(main):004:0> 41023800000000000/10_000_000
=> 4102380000
irb(main):005:0> Time.at(4102380000)
RangeError: bignum too big to convert into long' from (irb):5:in at’
from (irb):5

So Solaris can’t even work with a date in this century? That’s bad…

I ran the exact same numbers through irb on my Mac and it works just
fine…

157468536000000000 - 116_444_736_000_000_000
=> 41023800000000000
41023800000000000/10_000_000
=> 4102380000
Time.at(4102380000)
=> Thu Dec 31 00:00:00 -0600 2099

Another reason for me to dislike Solaris SPARC.

Matt

----- Original Message -----
From: “Matt M.” [email protected]
To: “ruby-talk ML” [email protected]
Sent: Tuesday, August 10, 2010 8:40:54 AM
Subject: Re: Error: Bignum too big to convert into `long’

Ah…

9223372036854775807 is the timestamp value assigned to the
“accountExpires” attribute in Active Directory when any account is set
to “Never Expire”.

It works fine on Linux/Mac but not on Solaris. I guess I’ll just
convert that timestamp to something like 12/31/2099 23:59:59 before I
run the Time.at.

Matt

----- Original Message -----
From: “Brian C.” [email protected]
To: “ruby-talk ML” [email protected]
Sent: Tuesday, August 10, 2010 7:53:24 AM
Subject: Re: Error: Bignum too big to convert into `long’

Try your example values in irb:

irb(main):003:0> (9223372036854775807 - 116_444_736_000_000_000) /
10_000_000
=> 910692730085
irb(main):004:0> Time.at(910692730085)
RangeError: bignum too big to convert into long' from (irb):4:in at’
from (irb):4

Time.at expects number of seconds since Jan 1, 1970.

The value you have given it is some time in the year 30,828 :slight_smile:

I suspect either your epoch or your multiplier is wrong.

B.

On Tue, Aug 10, 2010 at 10:51 PM, Matt M. [email protected] wrote:

Another reason for me to dislike Solaris SPARC.

you may let ruby do the work for you :slight_smile:
try ruby 1.9

eg,

$ ruby -ve ‘puts(“#{(-1.size==4?32:64)}bit”, Time.at(4102380000))’
ruby 1.9.2dev (2010-07-11 revision 28618) [i686-linux]
32bit
2099-12-31 14:00:00 +0800

best regards -botp

Matt M. wrote:

Another reason for me to dislike Solaris SPARC.

You can get 64-bit Solaris SPARC can’t you?

The example I posted (showing the limit for 32-bit Time) was on a 32-bit
Ubuntu machine.

Linux xxx 2.6.24-28-386 #1 Sat Jul 31 15:36:51 UTC 2010 i686 GNU/Linux

ruby 1.8.6 (2007-09-24 patchlevel 111) [i486-linux]

I’m sure an older Mac would be the same.

Solaris 10 SPARC is 64bit. It may be the ruby version I have installed
was compiled for 32bit? It’s an older version of 1.8.7 off of
sunfreeware.com. I noticed that sunfreeware has a newer 1.9.1 version
available there now so I think I’ll upgrade ruby to 1.9.1 and see what
happens.

Thanks,
Matt

----- Original Message -----
From: “botp” [email protected]
To: “ruby-talk ML” [email protected]
Sent: Tuesday, August 10, 2010 9:18:30 PM
Subject: Re: Error: Bignum too big to convert into `long’

On Tue, Aug 10, 2010 at 10:51 PM, Matt M. [email protected] wrote:

Another reason for me to dislike Solaris SPARC.

you may let ruby do the work for you :slight_smile:
try ruby 1.9

eg,

$ ruby -ve ‘puts(“#{(-1.size==4?32:64)}bit”, Time.at(4102380000))’
ruby 1.9.2dev (2010-07-11 revision 28618) [i686-linux]
32bit
2099-12-31 14:00:00 +0800

best regards -botp

On Aug 10, 2010, at 10:51 AM, Matt M. wrote:

Time.at((timestamp.to_i - ad_epoch) / ad_multiplier)
from (irb):5:in `at’

157468536000000000 - 116_444_736_000_000_000
=> 41023800000000000
41023800000000000/10_000_000
=> 4102380000
Time.at(4102380000)
=> Thu Dec 31 00:00:00 -0600 2099

Another reason for me to dislike Solaris SPARC.

Matt

32 bits of counting seconds since 1970 only gets you as far as 2038.
You apparently dislike 32-bit systems and not just Solaris SPARC.

-Rob

“accountExpires” attribute in Active Directory when any account is
To: “ruby-talk ML” [email protected]
from (irb):4:in `at’
Posted via http://www.ruby-forum.com/.

Rob B.
[email protected] http://AgileConsultingLLC.com/
[email protected] http://GaslightSoftware.com/

Matt M. wrote:

Solaris 10 SPARC is 64bit. It may be the ruby version I have installed
was compiled for 32bit? It’s an older version of 1.8.7 off of
sunfreeware.com. I noticed that sunfreeware has a newer 1.9.1 version
available there now so I think I’ll upgrade ruby to 1.9.1 and see what
happens.

Remember that ruby 1.9 is a significantly different language to ruby
1.8. Unless you are lucky, or fancy modifying your app to work with 1.9
(and maybe its dependent libs too), I think you’d be better off finding
a 64-bit build of ruby 1.8.7.