Funkce generátoru náhodných čísel v javascriptu. Náhodná čísla. Oříznutí zlomkové části
Výpočty v JavaScriptu velmi často nedávají přesně takové výsledky, jaké bychom chtěli. S čísly si samozřejmě můžeme dělat, co chceme – zaokrouhlovat nahoru nebo dolů, nastavovat rozsahy, ořezávat nepotřebná čísla určité množství desetinná místa, vše závisí na tom, co chcete s tímto číslem dále dělat. Proč je nutné zaokrouhlování? Jedním ze zajímavých aspektů JavaScriptu je, že ve skutečnosti neukládá celá čísla, pracujeme rovnou s čísly s plovoucí desetinnou čárkou. To v kombinaci se skutečností, že mnoho zlomkových hodnot nelze vyjádřit v konečném počtu desetinných míst, můžeme v JavaScriptu získat výsledky takto:0.1 * 0.2;
> 0.020000000000000004
0.3 - 0.1
> 0.19999999999999998
Pro praktické účely tato nepřesnost nevadí, v našem případě se bavíme o chybě v kvintilionu dílů, nicméně to může někoho zklamat. Poněkud podivné výsledky můžeme získat také při práci s čísly, která představují měny, procenta nebo velikosti souborů. Abychom tyto nepřesnosti opravili, potřebujeme umět výsledky zaokrouhlit a stačí nastavit desetinnou přesnost.
Zaokrouhlování čísel má praktické využití, můžeme manipulovat s číslem v určitém rozsahu, například chceme zaokrouhlit hodnotu na nejbližší celé číslo a ne pracovat pouze s desetinná část.
Zaokrouhlování desetinných čísel K odříznutí desetinné číslo, použijte metodu toFixed nebo toPrecision. Oba berou jeden argument, který určuje, respektive kolik významné postavy(tj. celkový počet číslic použitých v čísle) nebo desetinná místa (číslo za desetinnou čárkou) musí obsahovat výsledek:Metody toFixed() i toPrecision() vracejí řetězcovou reprezentaci výsledku, nikoli číslo. To znamená, že při sečtení zaokrouhlené hodnoty s randNum vznikne zřetězení řetězců spíše než součet čísel:
Nechť randNum = 6,25; let rounded = randNum.toFixed(); // "6" console.log(randNum + rounded); > "6,256"
Pokud chcete, aby byl výsledek číselný typ data, pak budete muset použít parseFloat:
Nechť randNum = 6,25; let rounded = parseFloat(randNum.toFixed(1)); console.log(zaoblene); > 6.3
Vezměte prosím na vědomí, že hodnoty 5 jsou zaokrouhleny kromě vzácných případů.
Metody toFixed() a toPrecision() jsou užitečné, protože mohou nejen ořezávat zlomková část, ale také přidat desetinná místa, což je výhodné při práci s měnou:
Nechť celéNum = 1 nechť dolaryCenty = celéNum.toFixed(2); console.log(dollarsCents); > "1,00"
Všimněte si, že toPrecision vytvoří výsledek ve vědeckém zápisu, pokud je počet celých čísel větší než samotná přesnost:
Nechť num = 123,435 num.toPrecision(2); > "1,2e+2"
Jak se vyhnout chybám při zaokrouhlování s desetinnými místy V některých případech toFixed a toPrecision zaokrouhlí hodnotu 5 dolů a nahoru:Nechť numTest = 1,005; numTest.toFixed(2); > "1,00"
Výsledek výše uvedeného výpočtu by měl být 1,01, nikoli 1. Pokud se chcete vyhnout podobná chyba, můžeme použít řešení navržené Jackem L Moorem, které používá k výpočtu exponenciální čísla:
Funkce round(hodnota, desetinná místa) ( return Number(Math.round(hodnota+"e"+desetinná)+"e-"+desetinná); )
Nyní:
kolo(1,005,2); > 1,01
Pokud chcete robustnější řešení než to uvedené výše, můžete přejít na MDN.
0,1 + 0,2 === 0,3 > nepravda
V naší funkci používáme Math.EPSILON, abychom získali platné srovnání:
Funkce epsEqu(x, y) ( return Math.abs(x - y)< Number.EPSILON * Math.max(Math.abs(x), Math.abs(y));
}
Funkce má dva argumenty: první je aktuální výpočet, druhý je očekávaný výsledek. Vrátí srovnání těchto dvou:
EpsEqu(0,1 + 0,2, 0,3) > pravda
Všechny moderní prohlížeče již ES6 podporují matematické funkce ale pokud chcete podporu v prohlížečích jako IE 11, použijte polyfills.
Funkce truncated(num) ( return Math.trunc(num * 100) / 100; ) truncated(3.1416) > 3.14
Pokud chcete metodu přizpůsobit libovolnému počtu desetinných míst, můžete použít bitovou dvojitou negaci:
Funkce zkrácena (num, desetinná místa) ( nechť numPowerConverter = Math.pow(10, desetinná místa); return ~~(num * numPowerConverter)/numPowerConverter; )
Nyní:
Nechť randInt = 35,874993; truncated(randInt,3); > 35,874
Zaokrouhlení na nejbližší číslo Chcete-li zaokrouhlit desetinné číslo na nejbližší číslo nahoru nebo dolů, podle toho, k čemu jsme nejblíže, použijte Math.round():Mat.kolo(4.3) > 4 Mat.kolo(4.5) > 5
Všimněte si, že "poloviční hodnota", 0,5 je zaokrouhleno na velká strana podle pravidel matematiky.
Math.floor(42,23); > 42 Mate.podla(36,93); > 36
Upozorňujeme, že zaokrouhlení dolů funguje pro všechna čísla, včetně záporných čísel. Představte si mrakodrap s nekonečným počtem pater, včetně pater na spodní úrovni (představující záporná čísla). Pokud jste ve výtahu nižší úroveň mezi 2 a 3 (což představuje hodnotu -2,5), Math.floor vás přenese na -3:
Math.floor(-2,5); > -3
Pokud se ale této situaci chcete vyhnout, použijte Math.trunc , který je podporován ve všech moderní prohlížeče(kromě IE/Edge):
Math.trunc(-41,43); > -41
Na MDN najdete polyfill, který bude poskytovat podporu pro Math.trunc v prohlížečích a IE/Edge.
Math.ceil(42,23); > 43 Math.ceil(36,93); > 37 Math.ceil(-36,93); > -36
Zaokrouhlení nahoru/dolů na potřebné číslo Pokud chceme zaokrouhlit na nejbližší násobek 5, nejjednodušším způsobem je vytvořit funkci, která číslo vydělí 5, zaokrouhlí a poté vynásobí stejnou hodnotou:Funkce roundTo5(num) ( return Math.round(num/5)*5; )
Nyní:
RoundTo5(11); > 10
Pokud chcete zaokrouhlit na násobky vaší hodnoty, použijeme více obecná funkce, předáním počáteční hodnoty a násobku do ní:
Funkce roundToMultiple(počet, násobek) ( return Math.round(num/násobek)*násobek; )
Nyní:
Nechť initialNumber = 11; nechť násobek = 10; roundToMultiple(počátečníNumber, násobek); > 10;
Stanovení čísla v rozsahu Existuje mnoho případů, kdy chceme získat hodnotu x, která leží v rozsahu. Například bychom mohli potřebovat hodnotu mezi 1 a 100, ale skončili jsme s hodnotou 123. Abychom to napravili, můžeme použít min (vrátí nejmenší ze sady čísel) a max (vrátí největší ze sady čísel čísel). V našem příkladu je rozsah od 1 do 100:Nechť lowBound = 1; nech highBound = 100; nechť numInput = 123; nechat upnut = Math.max(dolni hranice, Math.min(numInput, highBound)); console.log(upnutý); > 100;
Opět můžeme operaci znovu použít a celou věc zabalit do funkce pomocí řešení navrženého Danielem X. Mooreem:
Number.prototype.clamp = function(min, max) ( return Math.min(Math.max(this, min), max); );
Nyní:
NumInput.clamp(lowBound, highBound); > 100;
Gaussovské zaokrouhlování Gaussovské zaokrouhlování, známé také jako bankéřské zaokrouhlování, zahrnuje zaokrouhlování na nejbližší sudé číslo. Tato metoda zaokrouhlování funguje bez statistické chyby. Nejlepší rozhodnutí navrhl Tim Down:Funkce gaussRound(číslo, desetinná místa) ( nechť d = desetinná místa || 0, m = Math.pow(10, d), n = +(d ? num * m: num).toFixed(8), i = Math.floor (n), f = n - i, e = 1e-8, r = (f > 0,5 - e && f< 0.5 + e) ?
((i % 2 == 0) ? i: i + 1) : Math.round(n);
return d ? r / m: r;
}
Nyní:
GaussRound(2.5) > 2 gaussRound(3.5) > 4 gaussRound(2.57,1) > 2.6
Desetinné v CSS:
Vzhledem k tomu, že JavaScript se často používá k vytváření pozičních mapování pro prvky HTML, možná vás zajímá, co by se stalo, kdybychom pro naše prvky vygenerovali desetinné hodnoty:
#box ( šířka: 63,667731993px; )
Dobrou zprávou je, že moderní prohlížeče budou respektovat desetinné hodnoty v blokový model, včetně jednotek procent nebo pixelů.
Nechte ovoce = ["butternut squash", "meruňka", "cantaloupe"]; ovoce.sort(); > "meruňka", "máslová dýně", "cantaloupe"]
Jakmile je však jeden z prvků velkými písmeny, narazíme na problém:
Nechte ovoce = ["butternut squash", "meruňka", "Cantalope"]; ovoce.sort(); > "Cantaloupe", "meruňka", "máslová dýně"]
Je to proto, že ve výchozím nastavení třídič porovnává první znak reprezentovaný v Unicode. Unicode je unikátní kód pro jakýkoli symbol, bez ohledu na platformu, bez ohledu na program, bez ohledu na jazyk. Pokud se například podíváte na tabulku kódů, znak „a“ má hodnotu U+0061 (in hexadecimální soustava 0x61), zatímco znak "C" má kód U+0043 (0x43), který je v tabulce Unicode dříve než znak "a".
Abychom seřadili pole, které může obsahovat smíšená první písmena velkých a malých písmen, musíme buď dočasně převést všechny prvky na malá písmena nebo definujte své vlastní pořadí řazení pomocí metody localeCompare() s některými argumenty. Zpravidla je pro takový případ lepší okamžitě vytvořit funkci pro opakované použití:
Funkce alphaSort(arr) ( arr.sort(funkce (a, b) ( return a.localeCompare(b, "en", ("citlivost": "základ")); )); ) nechť ovoce = ["máslová dýně ", "meruňka", "cantaloupe"]; alphaSort(ovoce) >
Pokud chcete pole seřadit v obráceném abecedním pořadí, jednoduše prohoďte pozice a a b ve funkci:
Funkce alphaSort(arr) ( arr.sort(funkce (a, b) ( return b.localeCompare(a, "en", ("citlivost": "základ")); )); ) nechť ovoce = ["máslová dýně ", "meruňka", "cantaloupe"]; alphaSort(ovoce) > ["Cantaloupe", "máslová dýně", "meruňka"]
Zde stojí za zmínku, že localeCompare se používá s argumenty, musíme také pamatovat na to, že je podporováno IE11+, pro starší verze IE jej můžeme použít bez argumentů a malými písmeny:
Funkce caseSort(arr) ( arr.sort(funkce (a, b) ( return a.toLowerCase().localeCompare(b.toLowerCase()); )); ) nechť ovoce = ["máslová dýně", "meruňka", "Ananasový meloun"]; caseSort(ovoce) > ["meruňka", "máslová dýně", "Cantaloupe"]
Numerické řazení To vše neplatí pro příklad, o kterém jsme hovořili výše o poli herních záznamů. S nějakým číselná poleřazení funguje perfektně, ale v určitém okamžiku může být výsledek nepředvídatelný:Nechat highScores = ; highScores.sort(); >
Faktem je, že způsob řazení() provádí lexikografické srovnání: což znamená, že čísla budou převedena na řetězec a porovnání budou opět provedena porovnáním prvního znaku tohoto řetězce v pořadí znaků tabulky Unicode. Proto musíme znovu definovat naše pořadí řazení:
Nechat highScores = ; highScores.sort(funkce(a,b) ( return a - b; )); >
Opět platí, že chcete-li seřadit čísla v opačném pořadí, prohoďte pozice aab ve funkci.
Let score = [ ( "name": "Daniel", "score": 21768 ), ( "name": "Michael", "score": 33579 ), ( "name": "Alison", "score": 38395 )];
V ES6+ můžete používat funkce šipek:
Scores.sort((a, b) => b.score - a.score));
Pro starší prohlížeče, které tuto podporu nemají:
Scores.sort(function(a, b) ( return a.score - b.score ));
Jak vidíte, řazení v JavaScriptu je poměrně obskurní záležitost, doufám, že tyto příklady nějak usnadní život.
V JavaScriptu výkonová funkce představený jako Math.pow(), byl zaveden v novém standardu ES7 nového operátora umocnění - " * * ".
Zvýšení na mocninu Chcete-li zvýšit číslo na n-tou mocninu, použijte funkci Math.pow(), kde první argument je číslo, které bude umocněno, druhý argument je exponent:Math.pow(3,2) > 9
Tato forma zápisu znamená 3 na druhou, neboli 3 × 3, což vede k výsledku 9. Lze samozřejmě uvést jiný příklad:
Math.pow(5,3); > 125
To znamená, že 5 krychlových nebo 5 × 5 × 5 se rovná 125.
ECMAScript 7 je další verze JavaScript, v zásadě můžeme použít nový navrhovaný operátor umocňování - * *, tato forma zápisu může být popisnější:
3 ** 2
> 9
Na tento moment Podpora tohoto operátora je značně omezená, proto se jeho použití nedoporučuje.
Funkce napájení může být užitečná ve většině různé situace. Jednoduchý příklad výpočtu počtu sekund za hodinu: Math.pow (60,2).
Druhá mocnina a krychle Math.sqrt() a Math.cbrt() jsou opakem Math.pow(). Jak si pamatujeme, druhá odmocnina z a je číslo, které dává a, když je na druhou.Math.sqrt(9) > 3
Zároveň je třetí odmocninou a číslo, které dává a, když je zvýšeno na krychli.
Math.cbrt(125) > 5
Math.cbrt() byl do specifikace JavaScriptu zaveden teprve nedávno, a je tedy podporován pouze v moderních prohlížečích: Chrome 38+, Firefox a Opera 25+ a Safari 7.1+. Toho si všimnete internet Explorer není na tomto seznamu, ale na MDN najdete polyfill.
Math.pow(1,25; 2); > 1,5625 Math.cbrt(56,57) > 3,8387991760286138
Vezměte prosím na vědomí, že to při použití funguje docela dobře záporné hodnoty argumenty:
Math.pow(-5,2) > 25 Math.pow(10,-2) > 0,01
To však nebude fungovat pro druhou odmocninu:
Math.sqrt(-9) > NaN
Z matematická analýza víme, že imaginárním číslem rozumíme odmocniny z záporná čísla. A to nás může přivést k další technice práce komplexní čísla, Ale to je jiný příběh.
K nalezení čtverce a můžete použít zlomkové hodnoty v Math.pow(). krychlové kořenyčísla. Odmocnina používá exponent 0,5:
Math.pow(5, 0,5); // = Math.sqrt(5) = 5 ** (1/2) > 2,23606797749979
Kvůli rozmarům s pohyblivou řádovou čárkou však nemůžete přesně odhadnout správný výsledek:
Math.pow(2,23606797749979,2) > 5,00000000000001
V takových situacích se budete muset uchýlit k odříznutí znamének od čísla nebo zaokrouhlení na nějakou hodnotu.
Někteří lidé si z neznámých důvodů v JavaScriptu pletou funkci Math.pow() s Math.exp() , což je exponenciální funkce pro čísla obecně. Poznámka: v anglický jazyk„exponent“ se překládá jako „exponent“, takže to platí spíše pro anglicky mluvící, i když existují alternativní názvy pro exponent, jako je index, mocnina.
Matematické konstanty Práci s matematikou v JavaScriptu usnadňuje řada vestavěných konstant. Tyto konstanty jsou vlastnostmi objektu Math. Stojí za zmínku, že konstanty jsou psány velkými písmeny, nikoli zápisem CamelCase.Průzkumu se mohou zúčastnit pouze registrovaní uživatelé. , Prosím.
Štítky: Přidat štítky 2. června 2013 ve 22:56 Řízené náhodně v JavaScriptu- JavaScript
„Algoritmus“ pro náhodný výběr hodnot z pole bez jejich opakování. Přesněji řečeno, v rámci svého JS tréninku jsem jej použil ke generování klasické RPG skupiny postav (barbar, mág, zloděj, rytíř, kněz), bez opakování tříd a jmen.
Princip je extrémně jednoduchý, ale může být užitečný pro JS začátečníky, jako jsem já. Spojení s RPG je čistě symbolické – nyní se aktivně snažím změnit svůj profil z marketingu na IT (uvědomil jsem si, že má duše leží) a cvičit herní forma mnohem zajímavější.
Funkce GamePlayer(n, r, l, p) ( this.nick = n; this.role = r; this.level = l; this.portrait = p; )
Ve skutečnosti tato funkce vytvoří znaky z proměnných, přes které bude volána. Například:
Var player1 = nový GamePlayer("Power Ranger","barbarian","64","img/barbarian.jpg")
Nyní proměnná player1 ukládá barbara Power Rangera úrovně 64 se specifickým portrétem; v těle stránky můžeme zobrazit libovolný jeho parametr pomocí player1.nick, player1.level atp.
Hodnoty (n, r, l, p) z GamePlayeru jsou zodpovědné za příjem a pořadí, ve kterém jsou data přijímána do funkce. Pokud v příkladu prohodíme n a r, pak mocný ranger Barbarian zůstane v player1, což úplně neodpovídá zadání.
2. Definujte pole Abychom si znaky nevytvářeli sami, ale téměř náhodně je generovali (jak je slíbeno v názvu), potřebujeme pole, ze kterých budeme brát parametry těchto stejných znaků. Jak již bylo popsáno výše, máme pouze 4 parametry: jméno postavy, třída, úroveň a portrét.Pole pro jméno:
Var player Names = ["Králík bezmocný", "Teplé obávané hříbě", "Desire Kit", "Angel Dusty", "Sweety Frozen", "Silver Heavy Wombat", "Lost Puma", "Vital Panda", "Rolling Sun" , "Steel Runny", "Young Fox", "Needless Ruthless Volunteer", "Chipmunk Cult", "Indigo Puppy"];
Bylo by možné jít dále a generovat jména ze 2-3 komponent, ale algoritmus pro takové vylepšení neobsahuje nic nového (stejná náhodnost), a pak by to prostě zkomplikovalo proces učení.
Pole pro třídu:
Var hráčRole = ["barbar", "mág", "rogue", "rytíř", "kněz"];
Všechno je stejně zřejmé. Několik řetězců, ze kterých pak vybereme hodnoty, které se mají zobrazit na stránce.
Pole pro úroveň:
V konkrétní příklad, Chtěl jsem, aby všichni členové party byli mezi úrovní 60 a 70. Ale protože se podmínky mohou změnit, bylo nutné vytvořit pole od úrovní 0 do 80, ze kterého pak vybrat požadované hodnoty. Vytvořeno ve smyčce:
Var hráčÚrovně = ; pro (i = 0; i