Commit e9c648f5 authored by Morten Welinder's avatar Morten Welinder Committed by Morten Welinder

Improve rounding precision and avoid overflow. Also, round before doing

2000-01-10  Morten Welinder  <terra@diku.dk>

	* src/format.c (split_time): Improve rounding precision and avoid
 	overflow.  Also, round before doing date part.

	* src/functions/fn-date.c (gnumeric_hour, gnumeric_minute,
 	gnumeric_second): Don't do the 0.5 second rounding here.
	(get_serial_date, get_serial_time): Do it here.
parent 340eebca
2000-01-10 Morten Welinder <terra@diku.dk>
* src/format.c (split_time): Improve rounding precision and avoid
overflow. Also, round before doing date part.
* src/functions/fn-date.c (gnumeric_hour, gnumeric_minute,
gnumeric_second): Don't do the 0.5 second rounding here.
(get_serial_date, get_serial_time): Do it here.
2000-01-10 Jody Goldberg <jgoldberg@home.com> 2000-01-10 Jody Goldberg <jgoldberg@home.com>
* src/application.c (application_clipboard_cut) : Typo. * src/application.c (application_clipboard_cut) : Typo.
......
2000-01-10 Morten Welinder <terra@diku.dk>
* src/format.c (split_time): Improve rounding precision and avoid
overflow. Also, round before doing date part.
* src/functions/fn-date.c (gnumeric_hour, gnumeric_minute,
gnumeric_second): Don't do the 0.5 second rounding here.
(get_serial_date, get_serial_time): Do it here.
2000-01-10 Jody Goldberg <jgoldberg@home.com> 2000-01-10 Jody Goldberg <jgoldberg@home.com>
* src/application.c (application_clipboard_cut) : Typo. * src/application.c (application_clipboard_cut) : Typo.
......
...@@ -30,6 +30,10 @@ get_serial_date (const Value *v) ...@@ -30,6 +30,10 @@ get_serial_date (const Value *v)
} else } else
serial = 0; serial = 0;
} }
/* Add half a second. Yes, Excel rounds up the date too. */
serial += 0.5 / DAY_SECONDS;
return floor (serial); return floor (serial);
} }
...@@ -59,6 +63,10 @@ get_serial_time (Value *v) ...@@ -59,6 +63,10 @@ get_serial_time (Value *v)
serial = 0; serial = 0;
g_free (str); g_free (str);
} }
/* Add half a second. Yes, Excel rounds up the date too. */
serial += 0.5 / DAY_SECONDS;
return serial - floor (serial); return serial - floor (serial);
} }
...@@ -328,7 +336,7 @@ gnumeric_hour (FunctionEvalInfo *ei, Value **argv) ...@@ -328,7 +336,7 @@ gnumeric_hour (FunctionEvalInfo *ei, Value **argv)
{ {
int secs; int secs;
secs = (int)(get_serial_time (argv[0]) * DAY_SECONDS + 0.5); secs = (int)(get_serial_time (argv[0]) * DAY_SECONDS);
return value_new_int (secs / 3600); return value_new_int (secs / 3600);
} }
...@@ -356,7 +364,7 @@ gnumeric_minute (FunctionEvalInfo *ei, Value **argv) ...@@ -356,7 +364,7 @@ gnumeric_minute (FunctionEvalInfo *ei, Value **argv)
{ {
int secs; int secs;
secs = (int)(get_serial_time (argv[0]) * DAY_SECONDS + 0.5); secs = (int)(get_serial_time (argv[0]) * DAY_SECONDS);
return value_new_int ((secs / 60) % 60); return value_new_int ((secs / 60) % 60);
} }
...@@ -384,7 +392,7 @@ gnumeric_second (FunctionEvalInfo *ei, Value **argv) ...@@ -384,7 +392,7 @@ gnumeric_second (FunctionEvalInfo *ei, Value **argv)
{ {
int secs; int secs;
secs = (int)(get_serial_time (argv[0]) * DAY_SECONDS + 0.5); secs = (int)(get_serial_time (argv[0]) * DAY_SECONDS);
return value_new_int (secs % 60); return value_new_int (secs % 60);
} }
......
...@@ -688,19 +688,24 @@ split_time (gdouble number) ...@@ -688,19 +688,24 @@ split_time (gdouble number)
{ {
static struct tm tm; static struct tm tm;
guint secs; guint secs;
GDate* date;
GDate* date = g_date_new_serial (number); /* Excel compatible rounding, I think. -- MW. */
number += 0.5 / 86400;
date = g_date_new_serial (number);
g_date_to_struct_tm (date, &tm); g_date_to_struct_tm (date, &tm);
/* /*
* WARNING : Be very careful about rounding here * This code used to be
* 86400 is not a great number to multiply by and one can easily * secs = ((number * 86400. + .5)) - (((int)number) * 86400);
* loose a second, and hence an entire minute. * but that does not work on Sparc's. (I don't think it really works
* We first round the seconds, then do integer calculations * anywhere else, but that is just a guess. Think overflow.
* for the rest. *
* (And that was before the += 0.5 above).
*/ */
secs = ((number * 86400. + .5)) - (((int)number) * 86400);
secs = (int)((number - (int)number) * 86400);
tm.tm_hour = secs / 3600; tm.tm_hour = secs / 3600;
secs -= tm.tm_hour * 3600; secs -= tm.tm_hour * 3600;
......
...@@ -30,6 +30,10 @@ get_serial_date (const Value *v) ...@@ -30,6 +30,10 @@ get_serial_date (const Value *v)
} else } else
serial = 0; serial = 0;
} }
/* Add half a second. Yes, Excel rounds up the date too. */
serial += 0.5 / DAY_SECONDS;
return floor (serial); return floor (serial);
} }
...@@ -59,6 +63,10 @@ get_serial_time (Value *v) ...@@ -59,6 +63,10 @@ get_serial_time (Value *v)
serial = 0; serial = 0;
g_free (str); g_free (str);
} }
/* Add half a second. Yes, Excel rounds up the date too. */
serial += 0.5 / DAY_SECONDS;
return serial - floor (serial); return serial - floor (serial);
} }
...@@ -328,7 +336,7 @@ gnumeric_hour (FunctionEvalInfo *ei, Value **argv) ...@@ -328,7 +336,7 @@ gnumeric_hour (FunctionEvalInfo *ei, Value **argv)
{ {
int secs; int secs;
secs = (int)(get_serial_time (argv[0]) * DAY_SECONDS + 0.5); secs = (int)(get_serial_time (argv[0]) * DAY_SECONDS);
return value_new_int (secs / 3600); return value_new_int (secs / 3600);
} }
...@@ -356,7 +364,7 @@ gnumeric_minute (FunctionEvalInfo *ei, Value **argv) ...@@ -356,7 +364,7 @@ gnumeric_minute (FunctionEvalInfo *ei, Value **argv)
{ {
int secs; int secs;
secs = (int)(get_serial_time (argv[0]) * DAY_SECONDS + 0.5); secs = (int)(get_serial_time (argv[0]) * DAY_SECONDS);
return value_new_int ((secs / 60) % 60); return value_new_int ((secs / 60) % 60);
} }
...@@ -384,7 +392,7 @@ gnumeric_second (FunctionEvalInfo *ei, Value **argv) ...@@ -384,7 +392,7 @@ gnumeric_second (FunctionEvalInfo *ei, Value **argv)
{ {
int secs; int secs;
secs = (int)(get_serial_time (argv[0]) * DAY_SECONDS + 0.5); secs = (int)(get_serial_time (argv[0]) * DAY_SECONDS);
return value_new_int (secs % 60); return value_new_int (secs % 60);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment