A programozás ZH-k szerelmeseinek íme a kódrészlet, ami (állítólag) a Zune dátum paráját okozta:
BOOL ConvertDays(UINT32 days, SYSTEMTIME* lpTime)
{
int dayofweek, month, year;
UINT8 *month_tab;
//Calculate current day of the week
dayofweek = GetDayOfWeek(days);
year = ORIGINYEAR;
while (days > 365)
{
if (IsLeapYear(year))
{
if (days > 366)
{
days -= 366;
year += 1;
}
}
else
{
days -= 365;
year += 1;
}
}
// Determine whether it is a leap year
month_tab = (UINT8 *)((IsLeapYear(year))? monthtable_leap : monthtable);
for (month=0; month<12; month++)
{
if (days <= month_tab[month])
break;
days -= month_tab[month];
}
month += 1;
lpTime->wDay = days;
lpTime->wDayOfWeek = dayofweek;
lpTime->wMonth = month;
lpTime->wYear = year;
return TRUE;
}
A kérdés magától értetődik: hol a hiba?
sghctoma · http://sghctoma.extra.hu 2009.01.03. 13:53:42
bodzasfanta_ (törölt) · http://bodzasfanta.hu 2009.01.03. 18:15:15
Bit Rot 2009.01.03. 21:25:28
Mi a lósz*r ez???
Ha jól látom: input: napok (ORIGINYEAR január 1 óta)
Output: struktúra day, dayofweek, month, year-el kitöltve.
De ki volt ezt képes újra megírni (pláne így), amikor erre van millió library függvény?
Bit Rot 2009.01.03. 21:26:28
Mármint az "if (days > 366)"-nak a nem létező else ágára gondoltál, ugye? (ami a days = 366-ot kezelné.)
sghctoma · http://sghctoma.extra.hu 2009.01.03. 22:17:49
gadget 2009.01.03. 23:48:55
szádba szarok 2009.01.04. 13:59:43
while (days > (d = IsLeapYear(year) ? 366 : 365)) {
++year;
days -= d;
}
rövidebb, egyszerűbb, olvashatóbb, van jelentése a feltételnek, és mellesleg működik.
synapse · http://www.synsecblog.com 2009.01.04. 14:09:52
"Zune"-os kodban azert vicces a fuckup
1: while (days > 365)
2: if (days > 366) :))))
synapse
P1ngW1n 2009.01.04. 14:31:16
// Global Variables
//These macro define some default information of RTC
#define ORIGINYEAR 1980 // the begin year
#define MAXYEAR (ORIGINYEAR + 100) // the maxium year
#define JAN1WEEK 2 // Jan 1 1980 is a Tuesday
#define GetDayOfWeek(X) (((X-1)+JAN1WEEK)%7)
Lesz itt még baj 2080-ban is :DDD
szádba szarok 2009.01.04. 15:13:52
synapse · http://www.synsecblog.com 2009.01.04. 15:41:27
++year;
days -= d;
}
Alazol? Ajajjj :D
synapse
synapse · http://www.synsecblog.com 2009.01.04. 15:42:13
while (days > d) {
++year;
days -= d;
}
Na, igy. Kurva tacspad :D
synapse
EQ · http://rycon.hu 2009.01.04. 16:34:33
synapse · http://www.synsecblog.com 2009.01.04. 16:41:25
Amugy a multkori meglett EQ?
synapse
Udi · http://blog.udi.hu 2009.01.04. 16:54:53
A year minden egyes cikluslépésben növekszik. Befejezzem a gondolatot?
PS: 1980 szökőév.
EQ · http://rycon.hu 2009.01.04. 17:33:10
szádba szarok 2009.01.04. 17:39:06
mert ha szólok, hogy faszságot írtál (mint ahogy tényleg), akkor ahelyett hogy elgondolkodnál, hogy talán valóban fasz vagy, nagyarccal visszaszólsz, és mondod tovább a magad baromságát. na ez NAGYON gáz.
minthogy annyira ostoba vagy, hogy egy három értékadásból egy egy összehasonlításból álló kódot nem bírsz felfogni, hát megszánlak, és elmagyarázom.
a ciklus invariánsa, hogy a keresett nap a year év jan.1-étől számolva, a day-edik nap. ez minden interáció előtt és után teljesül. mivel a ciklusfeltételben a d mindig pontosan azt az értékes kapja, ahány napja a year évnek van, a ciklusfeltétel azt jelenti, hogy "a keresett nap nem a year évben van". ha ez teljesül, akkor ugrik a következő évre. ezt jelenti a "++year;" a year tehát minden kurva iterációnál változik. (gondolom még soha nem találkoztál a ++ operátorral, és ez okozta a problémát.) hogy az invariánst megtartsa, ezután a napok számát éppen annyival csökkeni, ahány nap az adott évben van. azaz d-vel. miven a days minden interációban szigorúan csökken, a ciklus garantáltan véget ér.
tehát a kódom helyes.
te meg hülye vagy.
és túl nagy az arcod.
synapse · http://www.synsecblog.com 2009.01.04. 17:43:52
Ahaha, hat ezt bizony kurvara beneztem, igazad van. :)
synapse
synapse · http://www.synsecblog.com 2009.01.04. 17:47:13
ja, beneztem, kurvaokos vagy gratulalok. Viszont a stilusod miatt kijarna neked egy alapos szajbaveres.
synapse
Udi · http://blog.udi.hu 2009.01.04. 18:13:49
A kérdéses évben (ami végtelenre viszi az eredetit), a tied hibás eredményt hoz.
Jó lenne tudni, hogy a days paraméterrel történik e valami érdekes, mielőtt megkapja a fv.
szádba szarok 2009.01.04. 18:41:12
gadget 2009.01.04. 19:04:31
a szokoevek utolso napjan szall el az eredeti kod, de ettol fuggetlenul szvsz rendben van a cilklus amit irtal...
talan ez meg olvashatobb es egyszerubb:
while (days > 365 + IsLeapYear(year)) {
days -= 365 + IsLeapYear(year);
year++;
}
gadget 2009.01.04. 19:11:21
while (days > (d = 365 + IsLeapYear(year))) {
days -= d;
year++;
}
szádba szarok 2009.01.04. 19:16:23
gadget 2009.01.04. 19:30:53
bool int-re castolva mindig 0/1
utananeztem az IsLeapYear fv. implementaciojanak (egy ujabb csodakod)...bool helyett direktbe int-et ad vissza (0/1), szal vegul is mukodhet a fenti ciklusom
bit-player.org/2009/the-zune-bug
szádba szarok 2009.01.04. 19:36:16
"bool int-re castolva mindig 0/1"
hogyne, c++-ban. meg 200 másik nyelven is. c-ben pont nem. ott nincs is beépített bool típus.
gadget 2009.01.04. 20:01:40
tenyleg, errol el is feledkeztem...de mivel int 0/1-et ad vissza, a kodomnak mukodnie kell
ha a hivatalos fixet ugyanaz a zseni koveti el aki az eredeti kodot, akkor ugyis csak else agon egy break; lesz a javitas :)
sghctoma · http://sghctoma.extra.hu 2009.01.04. 21:54:33
Udi · http://blog.udi.hu 2009.01.05. 12:37:46
Én javában teszteltem, és így inicializáltam az inputot:
private static final Calendar epoch = new GregorianCalendar(1980,1,1,0,0);
private static final GregorianCalendar d = new GregorianCalendar(2008,12,31,0,0);
aztán
days = Math.round((float)(teszt.d.getTimeInMillis()-teszt.epoch.getTimeInMillis())/1000/60/60/24);
Nem szép, tudom. Valami nem volt kerek, mert 2009.1.1 inputtal futott végtelen ciklusra. Miután kilőttem a hibát tesztelni kezdtem a többi algoritmust is. Az eredeti 0-t ad, a tied pedig nem lép be az utolsó iterációba, és 365 lesz a végeredmény.
Egyik se helyes megoldás.
Ha a days-hez hozzáadsz egyet inikor, akkor is más eredmények jönnek ki.
Fura probléma, és nincs is kedvem már többet foglalkozni vele. Annyit sejtek, hogy a probléma magja, az hogy 1980.1.1 az általuk használt epoch.
Én ezt írtam:
while (days >365){
days -= 365;
if(d.isLeapYear(year)&&days>1)days--;
year++;
}
PS: teljesség kedvéért, a te algoritmusod javában:
int day = 0;
while (days > (day = d.isLeapYear(year) ? 366 : 365)) {
year++;
days -= day;
}
Udi · http://blog.udi.hu 2009.01.05. 12:43:10
while (days > (d = 365 + (IsLeapYear(year)!=0?1:0))) {
days -= d;
year++;
}
és mindenki boldog :D
szádba szarok 2009.01.05. 14:32:28
ays = Math.round((float)(teszt.d.getTimeInMillis()-teszt.epoch.getTimeInMillis())/1000/60/60/24);
ez 0-tól sorszámozza a napookat, az eredeti meg 1-től.
2009.01.07. 01:49:56