8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.75 2002/11/12 00:39:08 tgl Exp $
11
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.76 2003/01/09 01:06:57 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -175,12 +175,12 @@ AdjustTimestampForTypmod(Timestamp *time, int32 typmod)
175
175
};
176
176
177
177
static const int64 TimestampOffsets [MAX_TIMESTAMP_PRECISION + 1 ] = {
178
- INT64CONST (- 500000 ),
179
- INT64CONST (- 50000 ),
180
- INT64CONST (- 5000 ),
181
- INT64CONST (- 500 ),
182
- INT64CONST (- 50 ),
183
- INT64CONST (- 5 ),
178
+ INT64CONST (500000 ),
179
+ INT64CONST (50000 ),
180
+ INT64CONST (5000 ),
181
+ INT64CONST (500 ),
182
+ INT64CONST (50 ),
183
+ INT64CONST (5 ),
184
184
INT64CONST (0 )
185
185
};
186
186
@@ -194,16 +194,6 @@ AdjustTimestampForTypmod(Timestamp *time, int32 typmod)
194
194
100000 ,
195
195
1000000
196
196
};
197
-
198
- static const double TimestampOffsets [MAX_TIMESTAMP_PRECISION + 1 ] = {
199
- 0.5 ,
200
- 0.05 ,
201
- 0.005 ,
202
- 0.0005 ,
203
- 0.00005 ,
204
- 0.000005 ,
205
- 0.0000005
206
- };
207
197
#endif
208
198
209
199
if (!TIMESTAMP_NOT_FINITE (* time )
@@ -213,34 +203,27 @@ AdjustTimestampForTypmod(Timestamp *time, int32 typmod)
213
203
elog (ERROR , "TIMESTAMP(%d) precision must be between %d and %d" ,
214
204
typmod , 0 , MAX_TIMESTAMP_PRECISION );
215
205
206
+ /*
207
+ * Note: this round-to-nearest code is not completely consistent
208
+ * about rounding values that are exactly halfway between integral
209
+ * values. On most platforms, rint() will implement round-to-nearest,
210
+ * but the integer code always rounds up (away from zero). Is it
211
+ * worth trying to be consistent?
212
+ */
216
213
#ifdef HAVE_INT64_TIMESTAMP
217
- /* we have different truncation behavior depending on sign */
218
214
if (* time >= INT64CONST (0 ))
219
- {
220
- * time = ((* time / TimestampScales [typmod ])
221
- * TimestampScales [typmod ]);
222
- }
223
- else
224
215
{
225
216
* time = (((* time + TimestampOffsets [typmod ]) / TimestampScales [typmod ])
226
217
* TimestampScales [typmod ]);
227
218
}
228
- #else
229
- /* we have different truncation behavior depending on sign */
230
- if (* time >= 0 )
231
- {
232
- * time = (rint (((double ) * time ) * TimestampScales [typmod ])
233
- / TimestampScales [typmod ]);
234
- }
235
219
else
236
220
{
237
- /*
238
- * Scale and truncate first, then add to help the rounding
239
- * behavior
240
- */
241
- * time = (rint ((((double ) * time ) * TimestampScales [typmod ]) + TimestampOffsets [typmod ])
242
- / TimestampScales [typmod ]);
221
+ * time = - ((((- * time ) + TimestampOffsets [typmod ]) / TimestampScales [typmod ])
222
+ * TimestampScales [typmod ]);
243
223
}
224
+ #else
225
+ * time = (rint (((double ) * time ) * TimestampScales [typmod ])
226
+ / TimestampScales [typmod ]);
244
227
#endif
245
228
}
246
229
}
@@ -474,12 +457,12 @@ AdjustIntervalForTypmod(Interval *interval, int32 typmod)
474
457
};
475
458
476
459
static const int64 IntervalOffsets [MAX_INTERVAL_PRECISION + 1 ] = {
477
- INT64CONST (- 500000 ),
478
- INT64CONST (- 50000 ),
479
- INT64CONST (- 5000 ),
480
- INT64CONST (- 500 ),
481
- INT64CONST (- 50 ),
482
- INT64CONST (- 5 ),
460
+ INT64CONST (500000 ),
461
+ INT64CONST (50000 ),
462
+ INT64CONST (5000 ),
463
+ INT64CONST (500 ),
464
+ INT64CONST (50 ),
465
+ INT64CONST (5 ),
483
466
INT64CONST (0 )
484
467
};
485
468
@@ -493,16 +476,6 @@ AdjustIntervalForTypmod(Interval *interval, int32 typmod)
493
476
100000 ,
494
477
1000000
495
478
};
496
-
497
- static const double IntervalOffsets [MAX_INTERVAL_PRECISION + 1 ] = {
498
- 0.5 ,
499
- 0.05 ,
500
- 0.005 ,
501
- 0.0005 ,
502
- 0.00005 ,
503
- 0.000005 ,
504
- 0.0000005
505
- };
506
479
#endif
507
480
508
481
/*
@@ -701,30 +674,27 @@ AdjustIntervalForTypmod(Interval *interval, int32 typmod)
701
674
elog (ERROR , "INTERVAL(%d) precision must be between %d and %d" ,
702
675
precision , 0 , MAX_INTERVAL_PRECISION );
703
676
677
+ /*
678
+ * Note: this round-to-nearest code is not completely consistent
679
+ * about rounding values that are exactly halfway between integral
680
+ * values. On most platforms, rint() will implement round-to-nearest,
681
+ * but the integer code always rounds up (away from zero). Is it
682
+ * worth trying to be consistent?
683
+ */
704
684
#ifdef HAVE_INT64_TIMESTAMP
705
- /* we have different truncation behavior depending on sign */
706
685
if (interval -> time >= INT64CONST (0 ))
707
- {
708
- interval -> time = ((interval -> time / IntervalScales [precision ])
709
- * IntervalScales [precision ]);
710
- }
711
- else
712
686
{
713
687
interval -> time = (((interval -> time + IntervalOffsets [precision ]) / IntervalScales [precision ])
714
688
* IntervalScales [precision ]);
715
689
}
716
- #else
717
- /* we have different truncation behavior depending on sign */
718
- if (interval -> time >= 0 )
719
- {
720
- interval -> time = (rint (((double ) interval -> time ) * IntervalScales [precision ])
721
- / IntervalScales [precision ]);
722
- }
723
690
else
724
691
{
725
- interval -> time = ( rint (((( double ) interval -> time ) + IntervalOffsets [precision ])
726
- * IntervalScales [ precision ]) / IntervalScales [precision ]);
692
+ interval -> time = - ((( - interval -> time + IntervalOffsets [ precision ]) / IntervalScales [precision ])
693
+ * IntervalScales [precision ]);
727
694
}
695
+ #else
696
+ interval -> time = (rint (((double ) interval -> time ) * IntervalScales [precision ])
697
+ / IntervalScales [precision ]);
728
698
#endif
729
699
}
730
700
}
0 commit comments