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:
  • Pokud argument není pro toFixed() definován, bude implicitně nula, což znamená, že argument má 0 desetinných míst maximální hodnota, rovno 20.
  • Pokud parametru toPrecision není zadán žádný argument, číslo zůstane nedotčeno
  • nechť randNum = 6,25; randNum.toFixed(); > "6" Math.PI.toPrecision(1); > "3" randNum = 87,335; randNum.toFixed(2); > "87,33" randNum = 87,337; randNum.toPrecision(3); > "87,3"
    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.

    Strojové epsilonové zaokrouhlování V ES6 byla zavedena alternativní metoda pro zaokrouhlování desetinných čísel. Strojové zaokrouhlení epsilon poskytuje přiměřenou míru chyb při porovnávání dvou čísel s pohyblivou řádovou čárkou. Bez zaokrouhlení mohou srovnání přinést výsledky podobné následujícím:

    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.

    Odříznutí zlomkové části Všechny výše uvedené metody lze zaokrouhlit na desetinná čísla. Chcete-li jednoduše snížit číslo na dvě desetinná místa, musíte je nejprve vynásobit 100 a poté vydělit výsledný výsledek 100:

    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.

    Zaokrouhlení dolů na nejbližší celé číslo Pokud chcete vždy zaokrouhlit dolů, použijte Math.floor:

    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.

    Zaokrouhlení nahoru na nejbližší celé číslo Na druhou stranu, pokud potřebujete vždy zaokrouhlit nahoru, použijte Math.ceil. Znovu si pamatujte nekonečný výtah: Math.ceil vždy půjde „nahoru“, bez ohledu na to, zda je číslo záporné nebo ne:

    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ů.

    Třídění Velmi často potřebujeme seřadit některé prvky, například máme řadu herních záznamů a ty musí být uspořádány v sestupném pořadí podle hráčské hodnosti. Bohužel, standardní metoda sort() má některá překvapivá omezení: funguje dobře s často používanými v anglických slovech, ale okamžitě se rozpadne, když narazíte na čísla, jedinečné znaky nebo velká slova. Seřazeno podle abecední pořadí Zdá se, že řazení pole podle abecedy by mělo být jednoduchým úkolem:

    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.

    Řazení struktury podobné JSON Konečně, pokud máme datovou strukturu podobnou JSON reprezentovanou jako pole herních záznamů:

    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.

    Práce s mocninnými funkcemi Umocňování je operace původně definovaná jako výsledek opakovaného násobení přirozené číslo sama o sobě, druhá odmocnina z a je číslo, které dává a, když na druhou. Tyto funkce bychom mohli používat neustále Každodenní život v hodinách matematiky, včetně počítání ploch, objemů nebo dokonce fyzikálního modelování.

    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.

    Příklady Samozřejmě můžeme použít neceločíselné hodnoty v jedné z těchto funkcí:

    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ší.

    1. Vytvoření šablony Před vygenerováním skupiny postav je potřeba nastavit šablonu pro jejich generování. Vlastně je to tady:

    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

    
    Horní