[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

In the year 2525

Jim V. Tess

10/7/2006 2:51:00 AM

Is there a reason why Time.local can't handle dates beyond 2038? I know
that's when the number of second since 1970 exceeds 2^32, but can't a
big, strong language like Ruby handle it?

irb(main):004:0> Time.local(2038)
=> Fri Jan 01 00:00:00 Pacific Standard Time 2038


irb(main):005:0> Time.local(2039)
ArgumentError: time out of range
from (irb):5:in `local'
from (irb):5

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

20 Answers

David Vallner

10/7/2006 3:06:00 AM

0

Jim v. Tess wrote:
> Is there a reason why Time.local can't handle dates beyond 2038? I know
> that's when the number of second since 1970 exceeds 2^32, but can't a
> big, strong language like Ruby handle it?
>

Because it uses the underlying platform's time manipulation functions?
(Disclaimer: That's a wild guess.) No point reinventing the wheel in
Ruby. The numbercrunching to process Unix timestamps would probably be
rather sluggish done in Ruby if done in large quantities - and dates /
times are a rather common datatype you need to handle.

Mebbe hack around the issue by providing Ruby replacements for large
timestamps? Then again, maybe that's what the Date / DateTime classes
do. Buggered if I know, I could never remember which one did what.

David Vallner

khaines

10/7/2006 3:22:00 AM

0

Bill Kelly

10/7/2006 4:19:00 AM

0

From: <khaines@enigo.com>
>
> On Sat, 7 Oct 2006, David Vallner wrote:
>
>> Jim v. Tess wrote:
>>> Is there a reason why Time.local can't handle dates beyond 2038? I know
>>> that's when the number of second since 1970 exceeds 2^32, but can't a
>>> big, strong language like Ruby handle it?
>>>
>>
>> Because it uses the underlying platform's time manipulation functions?
>
> Yes.
>
>> Mebbe hack around the issue by providing Ruby replacements for large
>> timestamps? Then again, maybe that's what the Date / DateTime classes
>> do. Buggered if I know, I could never remember which one did what.
>
> Yes. DateTime uses Rational to represent time. 1 represents a day, not a
> second. It can be used with arbitrary dates well outside the range of
> Time, but it is MUCH slower. Use Time everywhere one can.

DateTime sounds nice. As cool as ruby's automatic Fixnum -> Bignum
auto-conversions are, one imagines a date where even someone learning
ruby might be able to specify "puts 2**256" (can already), or
Date.years_ago( -13_700_000_000 ).to_s
=> "Big Bang"


Is it not theoretically possible to make a "fixnum->bignum-like Date",
where it would be fast until its precision was exceeded? Then morph
into a badass DateTime that could handle dinosaurs, and big bangs,
etc.?


With Respect,

Bill



Suraj Kurapati

10/7/2006 7:03:00 AM

0

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Bill Kelly wrote:
> From: <khaines@enigo.com>
>>
>> On Sat, 7 Oct 2006, David Vallner wrote:
>>
>>> Jim v. Tess wrote:
>>>> Is there a reason why Time.local can't handle dates beyond 2038? I
>>>> know
>>>> that's when the number of second since 1970 exceeds 2^32, but can't a
>>>> big, strong language like Ruby handle it?
>>>>
>>>
>>> Because it uses the underlying platform's time manipulation functions?
>>
>> Yes.
>>
>>> Mebbe hack around the issue by providing Ruby replacements for large
>>> timestamps? Then again, maybe that's what the Date / DateTime classes
>>> do. Buggered if I know, I could never remember which one did what.
>>
>> Yes. DateTime uses Rational to represent time. 1 represents a day,
>> not a second. It can be used with arbitrary dates well outside the
>> range of Time, but it is MUCH slower. Use Time everywhere one can.
>
> DateTime sounds nice. As cool as ruby's automatic Fixnum -> Bignum
> auto-conversions are, one imagines a date where even someone learning
> ruby might be able to specify "puts 2**256" (can already), or
> Date.years_ago( -13_700_000_000 ).to_s
> => "Big Bang"
>
>
> Is it not theoretically possible to make a "fixnum->bignum-like Date",
> where it would be fast until its precision was exceeded? Then morph
> into a badass DateTime that could handle dinosaurs, and big bangs, etc.?

Furthermore, what about automatic Float -> BigDecimal conversion?
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)

iD8DBQFFJ1FymV9O7RYnKMcRAkU/AKCRnJbfT6yq2kl/TXa2PD77kVEoxgCfVkZH
uZBiltQMjjiPdB2wgNFwDPU=
=mXTx
-----END PGP SIGNATURE-----

jh+ruby-lang

10/7/2006 9:28:00 AM

0

David Vallner wrote:
> Jim v. Tess wrote:
>> Is there a reason why Time.local can't handle dates beyond 2038? I know
>> that's when the number of second since 1970 exceeds 2^32, but can't a
>> big, strong language like Ruby handle it?
>>
>
> Because it uses the underlying platform's time manipulation functions?

And brings interesting portability issues (not only for ruby).

$ irb
>> RUBY_PLATFORM
=> "x86_64-linux"
>> Time.local(2525)
=> Mon Jan 01 00:00:00 GMT 2525

Kalman Noel

10/7/2006 9:52:00 AM

0

Jim v. Tess:
> irb(main):004:0> Time.local(2038)
> => Fri Jan 01 00:00:00 Pacific Standard Time 2038
>
>
> irb(main):005:0> Time.local(2039)
> ArgumentError: time out of range
> from (irb):5:in `local'
> from (irb):5

Never rely on future times...

irb> RUBY_PLATFORM
=> "x86_64-linux"

irb> Time.local(2**31-1)
=> Tue Jan 01 00:00:00 CET 2147483647
irb> Time.local(2**31)
=> Wed Jan 01 00:00:00 CET -2147483648

irb> n = 2147485547
=> 2147485547
irb> Time.local(n)
=> Wed Jan 01 00:00:00 CET -2147481749
irb> Time.local(n+1)
ArgumentError: argument out of range
from (irb):70:in `local'
from (irb):70
from :0

Kalman

David Vallner

10/7/2006 10:11:00 AM

0

Suraj N. Kurapati wrote:
> Furthermore, what about automatic Float -> BigDecimal conversion?

Wouldn't that only be possible if the processor reports if an IEEE
floating-point conversion / operation was inprecise / innacurate (can't
for the heck of it remember which term applies here.)

Even if that was the case, that means that say a floating point division
would take would take one attempt, report that, convert the floating
point numbers to BigDecimals, and then perform the division in Ruby.
This isn't something I'd like happening in code even casually working
with floating point numbers for performance reasons. Though it's a valid
Shiny Thing to put as an optional mode of operation.

David Vallner

Vincent Fourmond

10/7/2006 11:27:00 AM

0

David Vallner wrote:
> Suraj N. Kurapati wrote:
>> Furthermore, what about automatic Float -> BigDecimal conversion?
>
> Wouldn't that only be possible if the processor reports if an IEEE
> floating-point conversion / operation was inprecise / innacurate (can't
> for the heck of it remember which term applies here.)
>
> Even if that was the case, that means that say a floating point division
> would take would take one attempt, report that, convert the floating
> point numbers to BigDecimals, and then perform the division in Ruby.

I think that basically every operation on a number which doesn't have
a natural writing in base 2 would trigger the conversion. That is,
unless you do 2 * 0.5, you'll switch automatically to BigDecimal. Bad
idea. Why don't you use BigDecimal systematically, if you're really
worried about precision ?

Cheers !

Vince

Suraj Kurapati

10/7/2006 3:22:00 PM

0

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Vincent Fourmond wrote:
> David Vallner wrote:
>> Suraj N. Kurapati wrote:
>>> Furthermore, what about automatic Float -> BigDecimal conversion?
>> Wouldn't that only be possible if the processor reports if an IEEE
>> floating-point conversion / operation was inprecise / innacurate (can't
>> for the heck of it remember which term applies here.)
>>
>> Even if that was the case, that means that say a floating point division
>> would take would take one attempt, report that, convert the floating
>> point numbers to BigDecimals, and then perform the division in Ruby.
>
> I think that basically every operation on a number which doesn't have
> a natural writing in base 2 would trigger the conversion. That is,
> unless you do 2 * 0.5, you'll switch automatically to BigDecimal. Bad
> idea. Why don't you use BigDecimal systematically, if you're really
> worried about precision ?

Well, manually applying BigDecimal wherever necessary for
performance reasons feels like programming in C (remember floats and
doubles? /me vomits).

When I was learning Ruby, I absolutely *loved* the fact that Fixnum
automatically spills into Bignum and vice versa... good riddance to
short, int, long, and long long! Just think of how beneficial this
conceptual abstraction (I don't care how many bits it occupies, I
just want to use this integer!) has been to your code and mode of
thinking. If Ruby didn't have this, we would be manually checking
sizes, upcasting, and downcasting Fixnums and Bignums everywhere. :-(

I don't care so much about performance; rather, I want to write code
quickly and elegantly using conceptual abstractions. If I really
need performance, I will profile the code and re-write the slow
parts in C.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)

iD8DBQFFJ8ZvmV9O7RYnKMcRAi5NAJ47Kby2Bo6OaZU2LWBeEJ8iJ9Sh+wCcDzqz
eAlA7MMIlci1VyaBmojAcL8=
=A4po
-----END PGP SIGNATURE-----

David Vallner

10/7/2006 4:20:00 PM

0

Suraj N. Kurapati wrote:
> Well, manually applying BigDecimal wherever necessary for
> performance reasons feels like programming in C (remember floats and
> doubles? /me vomits).
>

Yes, but there's performance losses, and performance losses. For the
fixnum -> bignum conversion, there's a whole of two cutover numbers
where you have to convert from one to the other. For a Float ->
BigDecimal conversion, there's probably an infinity of them.

Also:

---

require 'bigdecimal'
require 'benchmark'

N = 1000000

Benchmark.bmbm { |test|
test.report("Float") {
for i in 1..N
Math::PI / Math::E
end
}

test.report("BigDecimal") {
for i in 1..N
BigDecimal.new(String(Math::PI)) /
BigDecimal(String(Math::E))
end
}
}

---

Rehearsal ----------------------------------------------
Float 0.937000 0.000000 0.937000 ( 0.969000)
BigDecimal 30.594000 0.093000 30.687000 ( 30.922000)
------------------------------------ total: 31.624000sec

user system total real
Float 1.031000 0.000000 1.031000 ( 1.015000)
BigDecimal 30.453000 0.078000 30.531000 ( 30.766000)

---

That's a slowdown by a factor of 30. Which means simple decimal maths in
Ruby could be slower by at least a factor of 20 on average by my wild
guess. That's without the overhead of verifying if the result of a maths
operation can be represented in IEEE floats. Besides, even BigDecimals
lose precision eventually, and they don't have nearly as many use cases
as either arbitrary-size integers (that help prevent counter overflows),
or fast floating-point maths.

For a more "interesting" benchmark, let's see less trivial number crunching.

---

require 'bigdecimal'
require 'bigdecimal/math'
require 'benchmark'

N = 100000

include BigMath

Benchmark.bmbm { |test|
test.report("Float") {
for i in 1..N
Math.log(Math::PI) / Math.log(Math::E)
end
}

test.report("BigDecimal") {
for i in 1..N
log(BigDecimal(String(Math::PI)), 20) /
log(BigDecimal(String(Math::E)), 20)
end
}
}

---

Rehearsal ----------------------------------------------
Float 0.172000 0.000000 0.172000 ( 0.203000)
BigDecimal 278.641000 0.656000 279.297000 (279.422000)
----------------------------------- total: 279.469000sec

user system total real
Float 0.218000 0.000000 0.218000 ( 0.203000)
BigDecimal 276.266000 0.625000 276.891000 (286.234000)

---

That's a slowdown by a factor of roughly 1267... I don't need profiling
to see this would kill even casual use of nontrivial amounts of
numbercrunching.

> I don't care so much about performance; rather, I want to write code
> quickly and elegantly using conceptual abstractions. If I really
> need performance, I will profile the code and re-write the slow
> parts in C.

Which turns your proposal into "Let's make Ruby behave not like C,
crippling speed, so that everyone ends up rewriting maths code in C". I
fail to see the gain. As I said, the automagical conversion is somewhere
on my list of Potential Shiny Things. I doubt it's an essential feature
for, well, anyone. And it would be actively harmful to make it default
behaviour, or ever alter the behaviour to this in a library released
into the wild.

David Vallner