Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
28 + ((0x2eeeecc >> (2*month)) & 3). Ваш вариант выиграет на x86-64, мой — на x86 просто, хотя разница там копеечная.days = 28 + ((0x3bbeecc >> (month * 2)) & 3);И таки идеальный вариант!Я пытался понять это самостоятельно и нашёл несколько упоминаний подобного метода на других сайтах, но к своему невежеству так и не выяснил: откуда взялось число 0x3bbeecc?
К 28 надо прибавить 0, 2 или 3 — это занимает два бита. Отсюда получается 2 в множителе и 3 в маске.
А дальше просто упаковать все добавки в одно целое:
12 11 10 09 08 07 06 05 04 03 02 01 00 - номер месяца
11 10 11 10 11 11 10 11 10 11 00 11 00 - перечисляем количество дней для добавкиИ получаем 0x3bbeecc
function getDays(m){
return m === 2 ? 28 : 30 + (m > 7 ? m+1 : m) % 2;
}
sage: PolynomialRing(QQ, 'x').lagrange_polynomial(zip(range(1, 13), (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)))
-11/907200*x^11 + 163/181440*x^10 - 37/1260*x^9 + 13481/24192*x^8 - 2055371/302400*x^7 + 240683/4320*x^6 - 28268521/90720*x^5 + 85774775/72576*x^4 - 446998571/151200*x^3 + 46351537/10080*x^2 - 221017/56*x + 1416
sage: PolynomialRing(GF(37), 'x').lagrange_polynomial(zip(range(1, 13), (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)), algorithm="neville")[-1]
16*x^11 + 12*x^10 + 4*x^8 + 21*x^7 + 29*x^6 + 10*x^5 + 12*x^4 + 34*x^3 + 26*x^2 + 5*x + 10
30 ^ m & 1 ^ m / 8 ^ 4 / m & 2;
28 + (m + m / 8) % 2 + 2 % m + 1 / m * 2;
а у вас только 7. Интересно, можно ли компактнее?
31
-
(3) * (m == 2)
+
(1) * (m == 2) * ((y % 4 == 0) - (y % 100 == 0) + (y % 400 == 0))
-
(1) * (m == 4 || m == 6 || m == 9 || m == 11)


f(2,2100)===29 //true
(1 - (y % 4 + 2) % (y % 4 + 1)) * ((y % 100 + 2) % (y % 100 + 1)) + (1 - (y % 400 + 2) % (y % 400 + 1))
neg ecx
sbb eax,eax
inc eax
xor eax,eax
test ecx,ecx
sete al
Date.prototype.isLeapYear = function () {
var y = this.getFullYear();
return !(y % 4) && !!(y % 100) || !(y % 400)
};
Date.prototype.getDaysInMonth = function () {
// adapted from ZX-Spectrum BIOS :-)
return 28 + ((this.isLeapYear() << 2 | 15662003) >> (this.getMonth() << 1) & 3)
};
Формула подсчёта количества дней в месяце