Я столкнулся с исходным кодом для функции Minix gmtime.Меня интересовал бит, который вычислял число года по дням с эпохи.Вот кишки этого бита:
http://www.raspberryginger.com/jbailey/minix/html/gmtime_8c-source.html
http://www.raspberryginger.com/jbailey/minix/html/loc__time_8h-source.html
#define EPOCH_YR 1970
#define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) % 400)))
#define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365)
int year = EPOCH_YR;
while (dayno >= YEARSIZE(year)) {
dayno -= YEARSIZE(year);
year++;
}
Похоже, что алгоритм - это O (n), где n - эторасстояние от эпохи.Кроме того, кажется, что LEAPYEAR должен рассчитываться отдельно для каждого года - десятки раз для текущих дат и еще много для дат в далеком будущем.У меня был следующий алгоритм для того же действия (в данном случае из эпохи ISO-9601 (год 0 = 1 г. до н.э.), а не эпохи UNIX):
#define CYCLE_1 365
#define CYCLE_4 (CYCLE_1 * 4 + 1)
#define CYCLE_100 (CYCLE_4 * 25 - 1)
#define CYCLE_400 (CYCLE_100 * 4 + 1)
year += 400 * (dayno / CYCLE_400)
dayno = dayno % CYCLE_400
year += 100 * (dayno / CYCLE_100)
dayno = dayno % CYCLE_100
year += 4 * (dayno / CYCLE_4)
dayno = dayno % CYCLE_4
year += 1 * (dayno / CYCLE_1)
dayno = dayno % CYCLE_1
Это выполняется в O (1) длялюбое свидание, и похоже, что оно должно быть быстрее даже для дат, достаточно близких к 1970 году.
Итак, предполагая, что разработчики Minix - это умные люди, которые сделали это по-своему, и, вероятно, знают немного большеС чем я занимаюсь, почему?