<docere>http://www.docere.ro/ |

—download jsFact.zip— (click pe imagine) |
Calculul factorialului necesită numeroase operaţii de împărţire la BAZA de lucru, iar operaţia de împărţire consumă de cel puţin 20 de ori mai mult timp decât majoritatea celorlalte operaţii. Să observăm însă că dacă avem de împărţit la 10k, noi — care folosim în mod nativ baza 10 — nu facem efectiv împărţirea, ci doar deplasăm cifrele spre dreapta cu k poziţii. Pentru calculator, baza nativă de operare este 2k, k = 8/16/32; modelând operaţiile de exemplu în baza 216, putem evita împărţirile la BAZA (= 65536) - înlocuindu-le cu operaţii "pe biţi" (AND, deplasări de biţi), incomparabil mai rapide decât împărţirea efectivă.
function factorial_hex( n ) { var cf = new Array(); // tabloul binar al cifrelor factorialului cf[0] = 1; for( var f = 2; f <= n; f++) { var t = 0; for(var i = 0, s = cf.length; i < s; i++) { var p = t + cf[i] * f; cf[i] = p & 0xFFFF; // = p % 65536; t = p >> 16; // = Math.floor(p / 65536); } while(t) { cf[s++] = t & 0xFFFF; t >>= 16; } } // Fiecărei cifre de 16 biţi din cf[] îi corespund 4 cifre hexazecimale, // exceptând eventual, cifra de 16 biţi cea mai semnificativă din cf[] var hfac = cf[cf.length - 1].toString(16); // fără "zero padding" pe cifra "high" for(var i = cf.length - 2; i >= 0; i--) { var w = cf[i].toString(16); while(w.length < 4) w = '0' + w; // prefixează cu '0' ("zero padding") hfac += w; // alipeşte cele 4 cifre, şirului cifrelor hexazecimale } return hfac.toUpperCase(); }
Această funcţie este folosită în aplicaţia care urmează şi se va putea constata că viteza este mult mai mare decât în cazul bazei 106 (în pofida faptului că se operează cu cifre cam de 15 ori mai mici - având în vedere că 106 - 1 = 0xF423F, iar 65535 = 0xFFFF); 10000! a fost furnizat de programul în baza 10^6 în 220 secunde (şi mai multe click-uri 'Continue'), iar în baza 2^16 în numai 20 secunde (şi un singur 'Continue'). E drept că în primul caz am obţinut cifrele zecimale (35660 cifre), iar în al doilea doar forma hexazecimală formatată (29615 cifre hexazecimale) - ceea ce înseamnă că ar trebui să corectăm comparaţia, eliminând şi în primul program conversia la baza 10 (reducând metoda bignum_str() la bignum_str() { return this.T.reverse().join(' '); }, de exemplu); dar corecţia va fi mică, având în vedere că e vorba de conversie de la baza 10^6 la baza 10 (care nu implică operaţii de împărţire).
ORAR orarul şcolii
SitSco situaţie şcolară
ŞAH prin corespondenţă
doChess a Javascript chess engine
doPGN a Javascript PGN-browser
Cal++ ambiţiile Calului
aşaAzis momente lingvistice
Comentarii
—cum ar trebui calculată Media şcolară?
completely rethink the browser:
Google chrome