@@ -61,43 +61,51 @@ _PyLong_FromTime_t(time_t t)
6161}
6262
6363static int
64- _PyTime_ObjectToDenominator ( PyObject * obj , time_t * sec , long * numerator ,
64+ _PyTime_DoubleToDenominator ( double d , time_t * sec , long * numerator ,
6565 double denominator , _PyTime_round_t round )
6666{
67- assert (denominator <= LONG_MAX );
68- if (PyFloat_Check (obj )) {
69- double d , intpart , err ;
70- /* volatile avoids unsafe optimization on float enabled by gcc -O3 */
71- volatile double floatpart ;
67+ double intpart , err ;
68+ /* volatile avoids unsafe optimization on float enabled by gcc -O3 */
69+ volatile double floatpart ;
70+
71+ floatpart = modf (d , & intpart );
72+ if (floatpart < 0 ) {
73+ floatpart = 1.0 + floatpart ;
74+ intpart -= 1.0 ;
75+ }
7276
73- d = PyFloat_AsDouble (obj );
74- floatpart = modf (d , & intpart );
75- if (floatpart < 0 ) {
76- floatpart = 1.0 + floatpart ;
77- intpart -= 1.0 ;
77+ floatpart *= denominator ;
78+ if (round == _PyTime_ROUND_CEILING ) {
79+ floatpart = ceil (floatpart );
80+ if (floatpart >= denominator ) {
81+ floatpart = 0.0 ;
82+ intpart += 1.0 ;
7883 }
84+ }
85+ else {
86+ floatpart = floor (floatpart );
87+ }
7988
80- floatpart *= denominator ;
81- if (round == _PyTime_ROUND_CEILING ) {
82- floatpart = ceil (floatpart );
83- if (floatpart >= denominator ) {
84- floatpart = 0.0 ;
85- intpart += 1.0 ;
86- }
87- }
88- else {
89- floatpart = floor (floatpart );
90- }
89+ * sec = (time_t )intpart ;
90+ err = intpart - (double )* sec ;
91+ if (err <= -1.0 || err >= 1.0 ) {
92+ error_time_t_overflow ();
93+ return -1 ;
94+ }
9195
92- * sec = (time_t )intpart ;
93- err = intpart - (double )* sec ;
94- if (err <= -1.0 || err >= 1.0 ) {
95- error_time_t_overflow ();
96- return -1 ;
97- }
96+ * numerator = (long )floatpart ;
97+ return 0 ;
98+ }
9899
99- * numerator = (long )floatpart ;
100- return 0 ;
100+ static int
101+ _PyTime_ObjectToDenominator (PyObject * obj , time_t * sec , long * numerator ,
102+ double denominator , _PyTime_round_t round )
103+ {
104+ assert (denominator <= LONG_MAX );
105+ if (PyFloat_Check (obj )) {
106+ double d = PyFloat_AsDouble (obj );
107+ return _PyTime_DoubleToDenominator (d , sec , numerator ,
108+ denominator , round );
101109 }
102110 else {
103111 * sec = _PyLong_AsTime_t (obj );
@@ -220,30 +228,39 @@ _PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv, int raise)
220228}
221229#endif
222230
231+ static int
232+ _PyTime_FromFloatObject (_PyTime_t * t , double value , _PyTime_round_t round ,
233+ long to_nanoseconds )
234+ {
235+ /* volatile avoids unsafe optimization on float enabled by gcc -O3 */
236+ volatile double d , err ;
237+
238+ /* convert to a number of nanoseconds */
239+ d = value ;
240+ d *= to_nanoseconds ;
241+
242+ if (round == _PyTime_ROUND_CEILING )
243+ d = ceil (d );
244+ else
245+ d = floor (d );
246+
247+ * t = (_PyTime_t )d ;
248+ err = d - (double )* t ;
249+ if (fabs (err ) >= 1.0 ) {
250+ _PyTime_overflow ();
251+ return -1 ;
252+ }
253+ return 0 ;
254+ }
255+
223256static int
224257_PyTime_FromObject (_PyTime_t * t , PyObject * obj , _PyTime_round_t round ,
225258 long to_nanoseconds )
226259{
227260 if (PyFloat_Check (obj )) {
228- /* volatile avoids unsafe optimization on float enabled by gcc -O3 */
229- volatile double d , err ;
230-
231- /* convert to a number of nanoseconds */
261+ double d ;
232262 d = PyFloat_AsDouble (obj );
233- d *= to_nanoseconds ;
234-
235- if (round == _PyTime_ROUND_CEILING )
236- d = ceil (d );
237- else
238- d = floor (d );
239-
240- * t = (_PyTime_t )d ;
241- err = d - (double )* t ;
242- if (fabs (err ) >= 1.0 ) {
243- _PyTime_overflow ();
244- return -1 ;
245- }
246- return 0 ;
263+ return _PyTime_FromFloatObject (t , d , round , to_nanoseconds );
247264 }
248265 else {
249266#ifdef HAVE_LONG_LONG
0 commit comments