Re: hires DateTime-from_epoch( epoch = ... ) values

2005-08-09 Thread Joshua Hoblitt
On Mon, Aug 08, 2005 at 10:45:19AM -0500, Dave Rolsky wrote:
 On Mon, 8 Aug 2005, John Siracusa wrote:
 
 On 8/8/05, Dave Rolsky [EMAIL PROTECTED] wrote:
 Does anyone object to adding Math::BigFloat as a
 prereq?
 
 What are the performance/memory implications?  I don't object to the 
 prereq,
 but I would like to know if we're in for any new speed/bloat issues.  (I
 only really care about per-object overhead, not the cost of loading
 Math::BigFloat itself.)
 
 If I read the patch directly, we never store the bigfloat object, we just 
 use it to make sure that nanoseconds has the right value.

That's correct.  A single Math::BigFloat object is used as an
intermediate value, to hold the hires epoch 'string', which is then
immediately discarded after seperating the integer and fractional
values.

It shouldn't have much impact on memory unless Math::BigFloat has leaks.
;)

Cheers,

-J

--


pgpEitMgczkpC.pgp
Description: PGP signature


Re: hires DateTime-from_epoch( epoch = ... ) values

2005-08-09 Thread Joshua Hoblitt
On Mon, Aug 08, 2005 at 09:02:06AM -1000, Joshua Hoblitt wrote:
 On Mon, Aug 08, 2005 at 10:45:19AM -0500, Dave Rolsky wrote:
  On Mon, 8 Aug 2005, John Siracusa wrote:
  
  On 8/8/05, Dave Rolsky [EMAIL PROTECTED] wrote:
  Does anyone object to adding Math::BigFloat as a
  prereq?
  
  What are the performance/memory implications?  I don't object to the 
  prereq,
  but I would like to know if we're in for any new speed/bloat issues.  (I
  only really care about per-object overhead, not the cost of loading
  Math::BigFloat itself.)
  
  If I read the patch directly, we never store the bigfloat object, we just 
  use it to make sure that nanoseconds has the right value.
 
 That's correct.  A single Math::BigFloat object is used as an
 intermediate value, to hold the hires epoch 'string', which is then
 immediately discarded after seperating the integer and fractional
 values.
 
 It shouldn't have much impact on memory unless Math::BigFloat has leaks.
 ;)

On second thought, would we be better off simplifying
DateTime::from_epoch to only handle integer values and move all the
floating point complexity into DateTime::HiRes?  That would be
optimizing the common case.

Cheers,

-J

--


pgpivzyAm7UOQ.pgp
Description: PGP signature


Re: hires DateTime-from_epoch( epoch = ... ) values

2005-08-08 Thread Joshua Hoblitt
Since nobody has commented on this patch does that mean everybody agrees
that it's a good idea? :)

-J

--
On Mon, Jul 25, 2005 at 04:10:53PM -1000, Joshua Hoblitt wrote:
 Hi Folks,
 
 I stumbled across a limited precision issue while working on
 DateTime::Format::DateParse.
 
 One of 'epoch' test values used in Date::Parse is 1045469647.198189,
 which is just beyond the precision of an IEEE 754 64bit value (a C
 double).  So internally (on all IEEE 754 compliant platforms, YMMV) this
 gets represent as 1045469647.198189020... .  Since
 DateTime-from_epoch() treats the epoch parameter as numeric, it
 currently creates an object from that number set to 198_189_020
 nanoseconds.  I believe that this is surprising behavior for most users;
 in general people don't think about using an epsilon when comparing
 integer values.
 
 Possible solutions:
 
 a) do nothing... nobody else seems to have noticed
 b) document the limited precision issue
 c) change the API to some awful Fortranish a part + b part to preserve
 precision
 d) turn the epoch parameter into a Math::BigFloat so a high resolution
 'string' can be passed in and document the behavior.
 
 It's not clear to me what the right solution is although a patch to
 implement option d sans the required documentation changes is attached.
 
 Cheers,
 
 -J
 
 --

 ? .swp
 ? DateTime-0.2901-from_epoch_precision-fix.patch
 ? DateTime.bs
 ? DateTime.c
 ? Makefile
 ? blib
 ? leap_seconds.h
 ? pm_to_blib
 ? tmp.pl
 ? t/zz_00load.t
 ? t/zz_01sanity.t
 ? t/zz_02last_day.t
 ? t/zz_03components.t
 ? t/zz_04epoch.t
 ? t/zz_05set.t
 ? t/zz_06add.t
 ? t/zz_07compare.t
 ? t/zz_09greg.t
 ? t/zz_10subtract.t
 ? t/zz_11duration.t
 ? t/zz_12week.t
 ? t/zz_13strftime.t
 ? t/zz_14locale.t
 ? t/zz_15jd.t
 ? t/zz_16truncate.t
 ? t/zz_17set_return.t
 ? t/zz_18today.t
 ? t/zz_19leap_second.t
 ? t/zz_20infinite.t
 ? t/zz_21bad_params.t
 ? t/zz_22from_doy.t
 ? t/zz_23storable.t
 ? t/zz_24from_object.t
 ? t/zz_25add_subtract.t
 ? t/zz_27delta.t
 ? t/zz_28dow.t
 ? t/zz_29overload.t
 ? t/zz_30future_tz.t
 ? t/zz_31formatter.t
 ? t/zz_32leap_second2.t
 ? t/zz_33seconds_offset.t
 ? t/zz_34set_tz.t
 ? t/zz_35rd_values.t
 ? t/zz_36invalid_local.t
 Index: Makefile.PL
 ===
 RCS file: /cvsroot/perl-date-time/modules/DateTime.pm/Makefile.PL,v
 retrieving revision 1.47
 diff -u -r1.47 Makefile.PL
 --- Makefile.PL   27 Feb 2005 03:27:25 -  1.47
 +++ Makefile.PL   26 Jul 2005 01:41:35 -
 @@ -83,6 +83,7 @@
  
 PREREQ_PM= { 'DateTime::Locale' = 0.21,
   'DateTime::TimeZone' = 0.26,
 + 'Math::BigFloat' = 0,
   'Params::Validate' = 0.76,
   'Pod::Man'= 1.14,
   'Test::More'  = 0.34,
 Index: lib/DateTime.pm
 ===
 RCS file: /cvsroot/perl-date-time/modules/DateTime.pm/lib/DateTime.pm,v
 retrieving revision 1.304
 diff -u -r1.304 DateTime.pm
 --- lib/DateTime.pm   7 Jul 2005 23:18:21 -   1.304
 +++ lib/DateTime.pm   26 Jul 2005 01:41:38 -
 @@ -48,6 +48,7 @@
  use DateTime::TimeZone;
  use Params::Validate qw( validate validate_pos SCALAR BOOLEAN HASHREF OBJECT 
 );
  use Time::Local ();
 +use Math::BigFloat;
  
  # for some reason, overloading doesn't work unless fallback is listed
  # early.
 @@ -435,8 +436,8 @@
  my %args;
  
  # Because epoch may come from Time::HiRes
 -my $fraction = $p{epoch} - int( $p{epoch} );
 -$args{nanosecond} = int( $fraction * MAX_NANOSECONDS )
 +my $fraction = Math::BigFloat-new( $p{epoch} ) - int( $p{epoch} );
 +$args{nanosecond} = int ( $fraction * MAX_NANOSECONDS )-as_int-bstr
  if $fraction;
  
  # Note, for very large negative values this may give a blatantly
 Index: t/04epoch.t
 ===
 RCS file: /cvsroot/perl-date-time/modules/DateTime.pm/t/04epoch.t,v
 retrieving revision 1.18
 diff -u -r1.18 04epoch.t
 --- t/04epoch.t   13 Nov 2004 21:22:36 -  1.18
 +++ t/04epoch.t   26 Jul 2005 01:41:38 -
 @@ -2,7 +2,7 @@
  
  use strict;
  
 -use Test::More tests = 32;
 +use Test::More tests = 34;
  
  use DateTime;
  
 @@ -126,3 +126,13 @@
  my $dt = DateTime-from_epoch( epoch = 0.1234567891 );
  is( $dt-nanosecond, 123_456_789, 'nanosecond should be an integer ' );
  }
 +
 +{
 +my $dt = DateTime-from_epoch( epoch = 123456789.1234567891 );
 +is( $dt-nanosecond, 123_456_789, 'nanosecond should be an integer ' );
 +}
 +
 +{
 +my $dt = DateTime-from_epoch( epoch = 1045469647.198189 );
 +is( $dt-nanosecond, 198_189_000, 'nanosecond should be an integer ' );
 +}





pgphQzDt5zeaD.pgp
Description: PGP signature


Re: hires DateTime-from_epoch( epoch = ... ) values

2005-08-08 Thread Dave Rolsky

On Mon, 25 Jul 2005, Joshua Hoblitt wrote:


a) do nothing... nobody else seems to have noticed
b) document the limited precision issue
c) change the API to some awful Fortranish a part + b part to preserve
precision
d) turn the epoch parameter into a Math::BigFloat so a high resolution
'string' can be passed in and document the behavior.

It's not clear to me what the right solution is although a patch to
implement option d sans the required documentation changes is attached.


That seems right to me.  Does anyone object to adding Math::BigFloat as a 
prereq?



-dave

/*===
VegGuide.Orgwww.BookIRead.com
Your guide to all that's veg.   My book blog
===*/


Re: hires DateTime-from_epoch( epoch = ... ) values

2005-08-08 Thread John Siracusa
On 8/8/05, Dave Rolsky [EMAIL PROTECTED] wrote:
 Does anyone object to adding Math::BigFloat as a
 prereq?

What are the performance/memory implications?  I don't object to the prereq,
but I would like to know if we're in for any new speed/bloat issues.  (I
only really care about per-object overhead, not the cost of loading
Math::BigFloat itself.)

-John




Re: hires DateTime-from_epoch( epoch = ... ) values

2005-08-08 Thread Dave Rolsky

On Mon, 8 Aug 2005, John Siracusa wrote:


On 8/8/05, Dave Rolsky [EMAIL PROTECTED] wrote:

Does anyone object to adding Math::BigFloat as a
prereq?


What are the performance/memory implications?  I don't object to the prereq,
but I would like to know if we're in for any new speed/bloat issues.  (I
only really care about per-object overhead, not the cost of loading
Math::BigFloat itself.)


If I read the patch directly, we never store the bigfloat object, we just 
use it to make sure that nanoseconds has the right value.



-dave

/*===
VegGuide.Orgwww.BookIRead.com
Your guide to all that's veg.   My book blog
===*/


RE: hires DateTime-from_epoch( epoch = ... ) values

2005-08-08 Thread Hill, Ronald


On Mon, 25 Jul 2005, Joshua Hoblitt wrote:

 a) do nothing... nobody else seems to have noticed
 b) document the limited precision issue
 c) change the API to some awful Fortranish a part + b part to preserve
 precision
 d) turn the epoch parameter into a Math::BigFloat so a high resolution
 'string' can be passed in and document the behavior.

 It's not clear to me what the right solution is although a patch to
 implement option d sans the required documentation changes is
attached.

That seems right to me.  Does anyone object to adding Math::BigFloat as
a 
prereq?

No objections here :-) I just installed on WNT without issues
(Clean install on this OS)

Ron


Re: hires DateTime-from_epoch( epoch = ... ) values

2005-08-08 Thread Yitzchak Scott-Thoennes
On Mon, Aug 08, 2005 at 09:31:10AM -0500, Dave Rolsky wrote:
 On Mon, 25 Jul 2005, Joshua Hoblitt wrote:
 
 a) do nothing... nobody else seems to have noticed
 b) document the limited precision issue
 c) change the API to some awful Fortranish a part + b part to preserve
 precision
 d) turn the epoch parameter into a Math::BigFloat so a high resolution
 'string' can be passed in and document the behavior.
 
 It's not clear to me what the right solution is although a patch to
 implement option d sans the required documentation changes is attached.
 
 That seems right to me.  Does anyone object to adding Math::BigFloat as a 
 prereq?

You may want to require a recent version; Tels has done a great job
maintaining the Math::Big* modules, but AIUI they started off (and
were shipped in older perls) with quite a few bugs.


Re: hires DateTime-from_epoch( epoch = ... ) values

2005-07-26 Thread Joshua Hoblitt
Here's a quick demonstration of the issue...

--
#!/usr/bin/perl

use Math::BigFloat;
use Math::BigInt;

myfunc(1045469647.198189);
myfunc('1045469647.198189');

sub myfunc {
my $n = shift;

my $fraction = Math::BigFloat-new( $n ) - int( $n );

printf %s\n, int ( $fraction * 1e9 )-as_int-bstr;
}
--

-J

--
On Mon, Jul 25, 2005 at 04:10:53PM -1000, Joshua Hoblitt wrote:
 Hi Folks,
 
 I stumbled across a limited precision issue while working on
 DateTime::Format::DateParse.
 
 One of 'epoch' test values used in Date::Parse is 1045469647.198189,
 which is just beyond the precision of an IEEE 754 64bit value (a C
 double).  So internally (on all IEEE 754 compliant platforms, YMMV) this
 gets represent as 1045469647.198189020... .  Since
 DateTime-from_epoch() treats the epoch parameter as numeric, it
 currently creates an object from that number set to 198_189_020
 nanoseconds.  I believe that this is surprising behavior for most users;
 in general people don't think about using an epsilon when comparing
 integer values.
 
 Possible solutions:
 
 a) do nothing... nobody else seems to have noticed
 b) document the limited precision issue
 c) change the API to some awful Fortranish a part + b part to preserve
 precision
 d) turn the epoch parameter into a Math::BigFloat so a high resolution
 'string' can be passed in and document the behavior.
 
 It's not clear to me what the right solution is although a patch to
 implement option d sans the required documentation changes is attached.
 
 Cheers,
 
 -J
 
 --

 ? .swp
 ? DateTime-0.2901-from_epoch_precision-fix.patch
 ? DateTime.bs
 ? DateTime.c
 ? Makefile
 ? blib
 ? leap_seconds.h
 ? pm_to_blib
 ? tmp.pl
 ? t/zz_00load.t
 ? t/zz_01sanity.t
 ? t/zz_02last_day.t
 ? t/zz_03components.t
 ? t/zz_04epoch.t
 ? t/zz_05set.t
 ? t/zz_06add.t
 ? t/zz_07compare.t
 ? t/zz_09greg.t
 ? t/zz_10subtract.t
 ? t/zz_11duration.t
 ? t/zz_12week.t
 ? t/zz_13strftime.t
 ? t/zz_14locale.t
 ? t/zz_15jd.t
 ? t/zz_16truncate.t
 ? t/zz_17set_return.t
 ? t/zz_18today.t
 ? t/zz_19leap_second.t
 ? t/zz_20infinite.t
 ? t/zz_21bad_params.t
 ? t/zz_22from_doy.t
 ? t/zz_23storable.t
 ? t/zz_24from_object.t
 ? t/zz_25add_subtract.t
 ? t/zz_27delta.t
 ? t/zz_28dow.t
 ? t/zz_29overload.t
 ? t/zz_30future_tz.t
 ? t/zz_31formatter.t
 ? t/zz_32leap_second2.t
 ? t/zz_33seconds_offset.t
 ? t/zz_34set_tz.t
 ? t/zz_35rd_values.t
 ? t/zz_36invalid_local.t
 Index: Makefile.PL
 ===
 RCS file: /cvsroot/perl-date-time/modules/DateTime.pm/Makefile.PL,v
 retrieving revision 1.47
 diff -u -r1.47 Makefile.PL
 --- Makefile.PL   27 Feb 2005 03:27:25 -  1.47
 +++ Makefile.PL   26 Jul 2005 01:41:35 -
 @@ -83,6 +83,7 @@
  
 PREREQ_PM= { 'DateTime::Locale' = 0.21,
   'DateTime::TimeZone' = 0.26,
 + 'Math::BigFloat' = 0,
   'Params::Validate' = 0.76,
   'Pod::Man'= 1.14,
   'Test::More'  = 0.34,
 Index: lib/DateTime.pm
 ===
 RCS file: /cvsroot/perl-date-time/modules/DateTime.pm/lib/DateTime.pm,v
 retrieving revision 1.304
 diff -u -r1.304 DateTime.pm
 --- lib/DateTime.pm   7 Jul 2005 23:18:21 -   1.304
 +++ lib/DateTime.pm   26 Jul 2005 01:41:38 -
 @@ -48,6 +48,7 @@
  use DateTime::TimeZone;
  use Params::Validate qw( validate validate_pos SCALAR BOOLEAN HASHREF OBJECT 
 );
  use Time::Local ();
 +use Math::BigFloat;
  
  # for some reason, overloading doesn't work unless fallback is listed
  # early.
 @@ -435,8 +436,8 @@
  my %args;
  
  # Because epoch may come from Time::HiRes
 -my $fraction = $p{epoch} - int( $p{epoch} );
 -$args{nanosecond} = int( $fraction * MAX_NANOSECONDS )
 +my $fraction = Math::BigFloat-new( $p{epoch} ) - int( $p{epoch} );
 +$args{nanosecond} = int ( $fraction * MAX_NANOSECONDS )-as_int-bstr
  if $fraction;
  
  # Note, for very large negative values this may give a blatantly
 Index: t/04epoch.t
 ===
 RCS file: /cvsroot/perl-date-time/modules/DateTime.pm/t/04epoch.t,v
 retrieving revision 1.18
 diff -u -r1.18 04epoch.t
 --- t/04epoch.t   13 Nov 2004 21:22:36 -  1.18
 +++ t/04epoch.t   26 Jul 2005 01:41:38 -
 @@ -2,7 +2,7 @@
  
  use strict;
  
 -use Test::More tests = 32;
 +use Test::More tests = 34;
  
  use DateTime;
  
 @@ -126,3 +126,13 @@
  my $dt = DateTime-from_epoch( epoch = 0.1234567891 );
  is( $dt-nanosecond, 123_456_789, 'nanosecond should be an integer ' );
  }
 +
 +{
 +my $dt = DateTime-from_epoch( epoch = 123456789.1234567891 );
 +is( $dt-nanosecond, 123_456_789, 'nanosecond should be an integer ' );
 +}
 +
 +{
 +my $dt = DateTime-from_epoch( epoch = 1045469647.198189 

hires DateTime-from_epoch( epoch = ... ) values

2005-07-26 Thread Joshua Hoblitt
Hi Folks,

I stumbled across a limited precision issue while working on
DateTime::Format::DateParse.

One of 'epoch' test values used in Date::Parse is 1045469647.198189,
which is just beyond the precision of an IEEE 754 64bit value (a C
double).  So internally (on all IEEE 754 compliant platforms, YMMV) this
gets represent as 1045469647.198189020... .  Since
DateTime-from_epoch() treats the epoch parameter as numeric, it
currently creates an object from that number set to 198_189_020
nanoseconds.  I believe that this is surprising behavior for most users;
in general people don't think about using an epsilon when comparing
integer values.

Possible solutions:

a) do nothing... nobody else seems to have noticed
b) document the limited precision issue
c) change the API to some awful Fortranish a part + b part to preserve
precision
d) turn the epoch parameter into a Math::BigFloat so a high resolution
'string' can be passed in and document the behavior.

It's not clear to me what the right solution is although a patch to
implement option d sans the required documentation changes is attached.

Cheers,

-J

--
? .swp
? DateTime-0.2901-from_epoch_precision-fix.patch
? DateTime.bs
? DateTime.c
? Makefile
? blib
? leap_seconds.h
? pm_to_blib
? tmp.pl
? t/zz_00load.t
? t/zz_01sanity.t
? t/zz_02last_day.t
? t/zz_03components.t
? t/zz_04epoch.t
? t/zz_05set.t
? t/zz_06add.t
? t/zz_07compare.t
? t/zz_09greg.t
? t/zz_10subtract.t
? t/zz_11duration.t
? t/zz_12week.t
? t/zz_13strftime.t
? t/zz_14locale.t
? t/zz_15jd.t
? t/zz_16truncate.t
? t/zz_17set_return.t
? t/zz_18today.t
? t/zz_19leap_second.t
? t/zz_20infinite.t
? t/zz_21bad_params.t
? t/zz_22from_doy.t
? t/zz_23storable.t
? t/zz_24from_object.t
? t/zz_25add_subtract.t
? t/zz_27delta.t
? t/zz_28dow.t
? t/zz_29overload.t
? t/zz_30future_tz.t
? t/zz_31formatter.t
? t/zz_32leap_second2.t
? t/zz_33seconds_offset.t
? t/zz_34set_tz.t
? t/zz_35rd_values.t
? t/zz_36invalid_local.t
Index: Makefile.PL
===
RCS file: /cvsroot/perl-date-time/modules/DateTime.pm/Makefile.PL,v
retrieving revision 1.47
diff -u -r1.47 Makefile.PL
--- Makefile.PL 27 Feb 2005 03:27:25 -  1.47
+++ Makefile.PL 26 Jul 2005 01:41:35 -
@@ -83,6 +83,7 @@
 
PREREQ_PM= { 'DateTime::Locale' = 0.21,
  'DateTime::TimeZone' = 0.26,
+ 'Math::BigFloat' = 0,
  'Params::Validate' = 0.76,
  'Pod::Man'= 1.14,
  'Test::More'  = 0.34,
Index: lib/DateTime.pm
===
RCS file: /cvsroot/perl-date-time/modules/DateTime.pm/lib/DateTime.pm,v
retrieving revision 1.304
diff -u -r1.304 DateTime.pm
--- lib/DateTime.pm 7 Jul 2005 23:18:21 -   1.304
+++ lib/DateTime.pm 26 Jul 2005 01:41:38 -
@@ -48,6 +48,7 @@
 use DateTime::TimeZone;
 use Params::Validate qw( validate validate_pos SCALAR BOOLEAN HASHREF OBJECT );
 use Time::Local ();
+use Math::BigFloat;
 
 # for some reason, overloading doesn't work unless fallback is listed
 # early.
@@ -435,8 +436,8 @@
 my %args;
 
 # Because epoch may come from Time::HiRes
-my $fraction = $p{epoch} - int( $p{epoch} );
-$args{nanosecond} = int( $fraction * MAX_NANOSECONDS )
+my $fraction = Math::BigFloat-new( $p{epoch} ) - int( $p{epoch} );
+$args{nanosecond} = int ( $fraction * MAX_NANOSECONDS )-as_int-bstr
 if $fraction;
 
 # Note, for very large negative values this may give a blatantly
Index: t/04epoch.t
===
RCS file: /cvsroot/perl-date-time/modules/DateTime.pm/t/04epoch.t,v
retrieving revision 1.18
diff -u -r1.18 04epoch.t
--- t/04epoch.t 13 Nov 2004 21:22:36 -  1.18
+++ t/04epoch.t 26 Jul 2005 01:41:38 -
@@ -2,7 +2,7 @@
 
 use strict;
 
-use Test::More tests = 32;
+use Test::More tests = 34;
 
 use DateTime;
 
@@ -126,3 +126,13 @@
 my $dt = DateTime-from_epoch( epoch = 0.1234567891 );
 is( $dt-nanosecond, 123_456_789, 'nanosecond should be an integer ' );
 }
+
+{
+my $dt = DateTime-from_epoch( epoch = 123456789.1234567891 );
+is( $dt-nanosecond, 123_456_789, 'nanosecond should be an integer ' );
+}
+
+{
+my $dt = DateTime-from_epoch( epoch = 1045469647.198189 );
+is( $dt-nanosecond, 198_189_000, 'nanosecond should be an integer ' );
+}


pgp0UXq4Jq4m6.pgp
Description: PGP signature