Error: Bignum too big to convert into `long'

Hi,

I've got a bit of code that I borrowed from here http://www.ruby-forum.com/topic/77821. 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

Hi,

I've got a bit of code that I borrowed from here http://www.ruby-forum.com/topic/77821\. 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...

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

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

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:

2**30-1

=> 1073741823

_.class

=> Fixnum

2**30

=> 1073741824

_.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 Biedenharn
Rob@AgileConsultingLLC.com http://AgileConsultingLLC.com/
rab@GaslightSoftware.com http://GaslightSoftware.com/

···

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

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.

···

--
Posted via http://www.ruby-forum.com/.

Brian Candler 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.

···

--
Posted via http://www.ruby-forum.com/\.