Hur man genererar ett slumptal i javascript. Genererar du slumpmässiga heltal i JavaScript inom ett specifikt intervall? Avrundning till närmaste tal


Tekniskt sett är termen "slumptalsgenerator" absurd, eftersom siffrorna i sig inte är slumpmässiga. Till exempel, är 100 ett slumptal? Och 25? Vad denna term egentligen betyder är att den skapar en sekvens av tal som visas slumpmässigt. Detta väcker en mer komplex fråga: Vad är en sekvens av slumptal? Det enda rätta svaret: en sekvens av slumptal är en sekvens där alla element inte är relaterade. Denna definition leder till en sådan paradox att vilken sekvens som helst kan vara både slumpmässig och icke-slumpmässig, beroende på hur denna sekvens erhålls. Till exempel följande rad med siffror
1 2 3 4 5 6 7 8 9 0
erhölls genom att skriva den översta raden på tangentbordet i ordning, så sekvensen kan inte betraktas som slumpmässigt genererad. Men tänk om du får samma konsistens genom att ta ut de numrerade tennisbollarna ur fatet. I det här fallet är det redan en slumpmässigt genererad sekvens. Detta exempel visar att en sekvenss slumpmässighet beror på hur den erhölls och inte på sig själv.

Kom ihåg att talföljden som genereras av datorn är deterministisk: varje nummer utom det första beror på de föregående talen. Rent tekniskt innebär detta att endast en kvasi-slumpmässig talföljd kan genereras av en dator, d.v.s. i själva verket är de inte riktigt slumpmässiga. Detta är dock tillräckligt för de flesta uppgifter och sådana sekvenser kommer att kallas slumpmässiga för enkelhetens skull. En mycket intressant metod utvecklades av John von Neumann; det kallas ofta för rotmedelkvadrat. I den här metoden kvadreras det föregående slumptalet, och sedan extraheras de mellersta siffrorna från resultatet. Om du till exempel skapar siffror med tre siffror och det föregående talet var 121, så ger kvadrering 14641. Att välja de tre mittersta siffrorna ger nästa slumpmässiga nummer 464. Nackdelen med denna metod är att den har en mycket kort upprepningsperiod, kallad en slinga... Av denna anledning används inte denna metod idag. Moderna metoder för att generera slumpmässiga tal är mycket mer komplicerade.

Slumptal i PHP

PHP har två grupper av slumptalsfunktioner. Utåt kan de särskiljas med prefixet mt_ för alla funktioner i en av grupperna.

Utfasade funktioner
Randen. Returnerar ett heltal från noll till RAND_MAX (vilket är 32767). Den kan ha två valfria heltalsparametrar - om de är specificerade genereras ett slumptal från den första parametern till den andra.

Echo rand (); eko rand (1 100); // Ge ut ett slumpmässigt tal från 1 till 100

Srand. Anger sekvensen av slumptal som produceras av rand-funktionen. Har en heltalsparameter - för olika värden av denna parameter kommer rand att producera olika nummersekvenser. srand-funktionen behöver bara anropas en gång innan alla anrop till rand-funktionen. Användningsexempel:

Srand (1288); // Initiera slumptalsgeneratorn för ($ i = 0; $ i<5;$i++){ echo rand(); echo "
"; }

Uppmärksamhet! Sedan PHP 4.2.0 behöver du inte anropa srand () - PHP gör detta automatiskt.
Getrandmax () funktion. Returnerar värdet för det maximala slumptalet (32767).

Funktioner i den andra gruppen (med prefixet mt_)
Deras namn och åtgärder liknar funktionerna i den första gruppen - mt_rand, mt_srand och mt_getrandmax. Den största skillnaden är att slumptal tas från ett större område: från 0 till 21937 - 1. Dessutom fungerar dessa funktioner mycket snabbare än sina gamla motsvarigheter, eftersom de använder Mersenne Twisters slumptalsgenerator, utvecklad 1997 av japanska forskare. Därav prefixet mt_ (Mersenne Twister).
Användningsexempel:

// Skapa ett slumptal från 1000 till 2000 echo mt_rand (1000, 2000);

Slumptal i JavaScript

Slumptal i JavaScript kan genereras med Math.random (). Det kommer dock att vara ett bråktal mellan 0 och 1 (exklusive 0 och 1). För att generera ett slumpmässigt heltal i det önskade intervallet måste du skriva din egen funktion

Mycket ofta ger JavaScript-beräkningar inte exakt de resultat vi vill ha. Naturligtvis kan vi göra vad som helst med siffror – avrunda uppåt eller nedåt, sätta intervall, skära bort onödiga siffror till ett visst antal decimaler, allt beror på vad du vill göra med detta nummer i framtiden.

Varför är avrundning nödvändig?

En av de märkliga aspekterna av JavaScript är att det faktiskt inte lagrar heltal, vi arbetar omedelbart med flyttal. Detta, i kombination med det faktum att många bråkvärden inte kan uttryckas i ändligt antal decimaler, i JavaScript kan vi få resultat så här:

0.1 * 0.2; > 0.020000000000000004 0.3 - 0.1 > 0.19999999999999998
För praktiska ändamål spelar denna felaktighet ingen roll alls, i vårt fall talar vi om ett fel i quintillion delar, men detta kan göra någon besviken. Vi kan få ett lite konstigt resultat när vi arbetar med siffror som representerar värden på valutor, procentsatser eller filstorlekar. För att korrigera dessa felaktigheter behöver vi bara kunna runda resultaten, samtidigt som det räcker med att ställa in decimalprecisionen.

Avrundning av tal har en praktisk tillämpning, vi kan manipulera ett tal i ett visst område, till exempel vill vi avrunda värdet till närmaste heltal, och inte bara arbeta med decimaldelen.

Avrundning av decimaltal

För att ta bort ett decimaltal, använd toFixed eller toPrecision-metoden. De tar båda ett enda argument, som bestämmer hur många signifikanta siffror (dvs det totala antalet siffror som används i numret) eller decimaler (talet efter decimalkomma) resultatet ska innehålla:
  1. Om argumentet inte är definierat för toFixed (), kommer det som standard till noll, vilket betyder 0 decimaler, argumentet har ett maximalt värde på 20.
  2. Om inget argument ges för toPrecision, lämnas numret orört
låt 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"
Både toFixed () och toPrecision () returnerar en strängrepresentation av resultatet, inte ett tal. Detta betyder att när det avrundade värdet summeras med randNum, kommer strängarna att sammanfogas, inte summan av talen:

Låt randNum = 6,25; let rounded = randNum.toFixed (); // "6" console.log (randNum + avrundad); > "6.256"
Om du vill att resultatet ska ha en numerisk datatyp, måste du använda parseFloat:

Låt randNum = 6,25; let rounded = parseFloat (randNum.toFixed (1)); console.log (avrundad); > 6.3
Observera att 5 värden är avrundade utom i sällsynta fall.

Metoderna toFixed () och toPrecision () är användbara eftersom de inte bara kan ta bort bråkdelen, utan också komplettera decimalerna, vilket är praktiskt när du arbetar med valuta:

Låt wholeNum = 1 let dollarsCents = wholeNum.toFixed (2); console.log (dollarscent); > "1.00"
Observera att toPrecision ger resultatet i exponentiell notation om antalet heltal är större än själva precisionen:

Låt num = 123.435 num.to Precision (2); > "1.2e + 2"

Hur man undviker avrundningsfel med decimaltal

I vissa fall rundar toFixed och toPrecision 5 ned och upp:

Låt numTest = 1,005; numTest.toFixed (2); > "1.00"
Ovanstående beräkningsresultat borde ha varit 1,01, inte 1. Om du vill undvika detta fel kan vi använda lösningen som föreslås av Jack L Moore, som använder exponentialtal för att beräkna:

Funktionsrunda (värde, decimaler) (returnummer (Math.round (värde + "e" + decimaler) + "e -" + decimaler);)
Nu:

Rund (1.005.2); > 1,01
Om du vill ha en mer robust lösning än den som visas ovan kan du gå över till MDN.

Maskin epsilon avrundning

En alternativ metod för avrundning av decimaltal introducerades i ES6. Maskin epsilon-avrundning ger en rimlig felmarginal när man jämför två flyttal. Utan avrundning kan jämförelser ge resultat som liknar följande:

0,1 + 0,2 === 0,3> falskt
Vi använder Math.EPSILON i vår funktion för att få rätt jämförelse:

Funktion epsEqu (x, y) (retur Math.abs (x - y)< Number.EPSILON * Math.max(Math.abs(x), Math.abs(y)); }
Funktionen tar två argument: det första är den aktuella beräkningen, det andra är det förväntade resultatet. Det ger en jämförelse av de två:

EpsEqu (0,1 + 0,2, 0,3)> sant
Alla moderna webbläsare stöder redan ES6 matematiska funktioner, men om du vill ha stöd i webbläsare som IE 11 använd polyfills.

Bråkklippning

Alla metoder som presenteras ovan vet hur man avrundar till decimaltal. För att helt enkelt skära av talet med två decimaler måste du först multiplicera det med 100 och sedan dividera resultatet med 100:

Funktion trunkerad (num) (retur Math.trunc (num * 100) / 100;) trunkerad (3.1416)> 3.14
Om du vill anpassa metoden till valfritt antal decimaler kan du använda dubbel bitvis negation:

Funktion trunkerad (num, decimalPlaces) (låt numPowerConverter = Math.pow (10, decimalPlaces); returnera ~~ (num * numPowerConverter) / numPowerConverter;)
Nu:

Låt randInt = 35,874993; trunkerad (randInt, 3); > 35,874

Avrundning till närmaste tal

För att avrunda ett decimaltal uppåt eller nedåt, beroende på vilket som kommer närmast, använd Math.round ():

Math.round (4.3)> 4 Math.round (4.5)> 5
Observera att "halva värdet", 0,5, avrundas uppåt enligt matematikens regler.

Avrunda nedåt till närmaste heltal

Om du alltid vill avrunda nedåt, använd Math.floor:

Math.floor (42.23); > 42 Math.floor (36.93); > 36
Observera att avrundning nedåt fungerar för alla tal, inklusive negativa. Föreställ dig en skyskrapa med ett oändligt antal våningar, inklusive de på den lägre nivån (representerar negativa tal). Om du är i hissen på den lägre nivån mellan 2 och 3 (vilket är ett värde på -2,5), tar Math.floor dig ner till -3:

Math.floor (-2,5); > -3
Men om du vill undvika denna situation, använd Math.trunc, som stöds i alla moderna webbläsare (förutom IE / Edge):

Math.trunc (-41,43); > -41
På MDN hittar du en polyfill som kommer att ge stöd för Math.trunc i webbläsare och IE / Edge.

Runda uppåt till närmaste heltal

Å andra sidan, om du alltid behöver avrunda uppåt, använd Math.ceil. Återigen, kom ihåg det oändliga lyftet: Math.ceil kommer alltid att gå upp, oavsett om siffran är negativ eller inte:

Math.ceil (42,23); > 43 Math.ceil (36.93); > 37 Math.ceil (-36,93); > -36

Avrundning upp/ner efter behov

Om vi ​​vill avrunda till närmaste multipel av 5 är det enklaste sättet att skapa en funktion som dividerar ett tal med 5, avrundar det och sedan multiplicerar det med samma belopp:

Funktion roundTo5 (num) (retur Math.round (num / 5) * 5;)
Nu:

RoundTo5 (11); > 10
Om du vill avrunda till multiplar av ditt värde använder vi en mer allmän funktion, som skickar in ett initialvärde och en multipel:

Funktion roundToMultiple (tal, multipel) (retur Math.round (tal / multipel) * multipel;)
Nu:

Låt initialNumber = 11; låt multipla = 10; roundToMultiple (initialNumber, multipel); > 10;

Fixa ett nummer i ett intervall

Det finns många fall där vi vill få x inom ett intervall. Till exempel kanske vi vill ha ett värde mellan 1 och 100, men vi fick värdet 123. För att fixa detta kan vi använda min (returnerar den minsta av en uppsättning siffror) och max (returerar den största av alla uppsättningar av tal) ). I vårt exempel är intervallet från 1 till 100:

Låt låggräns = 1; låt höggräns = 100; låt numInput = 123; let clamped = Math.max (lowBound, Math.min (numInput, highBound)); console.log (klämd); > 100;
Återigen, vi kan återanvända operationen och slå in det hela i en funktion, låt oss använda lösningen som föreslagits av Daniel X. Moore:

Number.prototype.clamp = funktion (min, max) (retur Math.min (Math.max (detta, min), max);
Nu:

NumInput.clamp (lowBound, highBound); > 100;

Gaussisk avrundning

Gaussisk avrundning, även känd som bankavrundning, är där avrundningen sker till närmaste jämnhet. Denna avrundningsmetod fungerar utan statistiska fel. Den bästa lösningen föreslogs av Tim Down:

Funktion gaussRound (num, decimalPlatser) (låt d = decimalPlatser || 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; }
Nu:

GaussRound (2.5)> 2 gaussRound (3.5)> 4 gaussRound (2.57,1)> 2.6
Decimalkomma i CSS:

Eftersom JavaScript ofta används för att generera positionella transformationer på HTML-element, kanske du undrar vad som händer om vi genererar decimalvärden för våra element:

#box (bredd: 63,667731993px;)
Den goda nyheten är att moderna webbläsare kommer att överväga decimalvärden i boxmodellen, inklusive procent eller pixelenheter.

Sortering

Mycket ofta måste vi sortera vissa element, till exempel har vi en rad spelrekord, och de måste organiseras i fallande ordning efter spelarnas rangordning. Tyvärr har standardmetoden sortering () några överraskande begränsningar: den fungerar bra med vanliga engelska ord, men bryter omedelbart när den står inför siffror, unika tecken eller versaler.

Sortera alfabetiskt

Det verkar som att sortering av en array alfabetiskt borde vara den enklaste uppgiften:

Låt frukt = ["butternut squash", "aprikos", "cantaloupe"]; fruit.sort (); > "aprikos", "butternut squash", "cantaloupe"]
Men vi stöter på ett problem så snart ett av elementen är versaler:

Låt frukt = ["butternut squash", "aprikos", "Cantalope"]; fruit.sort (); > "Cantaloupe", "aprikos", "butternut squash"]
Detta beror på att sorteraren som standard jämför det första tecknet som representeras i Unicode. Unicode är en unik kod för alla tecken, oavsett plattform, oavsett program, oavsett språk. Om du till exempel tittar på kodtabellen har tecknet "a" värdet U + 0061 (i hexadecimalt system 0x61), medan tecknet "C" har koden U + 0043 (0x43), som kommer tidigare i Unicode-tabell än tecknet "A".

För att sortera en array, som kan innehålla blandade versaler av de första bokstäverna, måste vi antingen konvertera alla element tillfälligt till gemener, eller definiera vår egen sorteringsordning med metoden localeCompare () med några argument. Som regel, för ett sådant fall, är det bättre att omedelbart skapa en funktion för upprepad användning:

Funktion alphaSort (arr) (arr.sort (funktion (a, b) (retur a.localeCompare (b, "en", ("känslighet": "bas"));));) låt frukt = ["butternut squash "," aprikos "," Cantaloupe "]; alphaSort (frukt)>
Om du vill få en array sorterad i omvänd alfabetisk ordning, byt bara position a och b i funktionen:

Funktion alphaSort (arr) (arr.sort (funktion (a, b) (retur b.localeCompare (a, "en", ("känslighet": "bas"));));) låt frukt = ["butternut squash "," aprikos "," Cantaloupe "]; alphaSort (frukt)> ["Cantaloupe", "butternut squash", "aprikos"]
Det är värt att notera här att localeCompare används med argument, du måste också komma ihåg att det stöds av IE11 +, för äldre versioner av IE kan vi använda det utan argument, och med gemener:

Funktion caseSort (arr) (arr.sort (funktion (a, b) (retur a.toLowerCase (). LocaleCompare (b.toLowerCase ());));) let fruit = ["butternut squash", "aprikos", "Cantaloupmelon"]; fallSortera (frukt)> ["aprikos", "butternut squash", "Cantaloupe"]

Numerisk sortering

Allt detta gäller inte exemplet som vi pratade om ovan om mängden spelrekord. Med vissa numeriska arrayer fungerar sortering bra, men någon gång kan resultatet vara oförutsägbart:

Låt highScores =; highScores.sort (); >
Faktum är att metoden sort () utför en lexikografisk jämförelse: vilket innebär att talen kommer att konverteras till en sträng och jämförelser kommer att utföras igen genom att matcha det första tecknet i denna sträng i ordningen för Unicode-tabelltecken. Därför måste vi återigen definiera vår sorteringsordning:

Låt highScores =; highScores.sort (funktion (a, b) (retur a - b;)); >
Återigen, för att sortera siffrorna i omvänd ordning, byt ut positionerna för a och b i funktionen.

Sorterar en JSON-liknande struktur

Slutligen, om vi har en JSON-liknande datastruktur, representerad som en rad spelrekord:

Låt poäng = [("namn": "Daniel", "poäng": 21768), ("namn": "Michael", "poäng": 33579), ("namn": "Alison", "poäng": 38395 )];
I ES6 + kan du använda pilfunktioner:

Scores.sort ((a, b) => b.score - a.score));
För äldre webbläsare som inte har detta stöd:

Scores.sort (funktion (a, b) (retur a.score - b.score));
Som du kan se är sortering i JavaScript inte en självklar sak, jag hoppas att dessa exempel gör livet lättare på något sätt.

Arbeta med kraftfunktioner

Exponentiering är en operation som ursprungligen definierades som resultatet av multiplikation av ett naturligt tal med sig själv, kvadratroten ur a är talet som ger a när det är kvadratiskt. Vi skulle kunna använda dessa funktioner hela tiden i vardagen i matematiklektioner, inklusive när vi beräknar ytor, volymer eller till och med i fysisk modellering.

I JavaScript representeras exponentialfunktionen som Math.pow (), i den nya ES7-standarden introduceras en ny exponentieringsoperator - "* *".

Exponentiering

För att höja ett tal till n:te potens, använd Math.pow ()-funktionen, där det första argumentet är talet som ska höjas till potensen, det andra argumentet är exponenten:

Math.pow (3,2)> 9
Denna form av notation betyder 3 i kvadrat, eller 3 × 3, vilket leder till resultatet 9. Du kan naturligtvis ge ett annat exempel:

Math.pow (5.3); > 125
Det vill säga, 5 kuber, eller 5 × 5 × 5, är lika med 125.

ECMAScript 7 är nästa version av JavaScript, i princip kan vi använda den nya föreslagna exponentieringsoperatorn - * *, denna form av notation kan vara mer beskrivande:

3 ** 2 > 9
För närvarande är stödet för den här operatören ganska begränsat, så det rekommenderas inte att använda det.

En kraftfunktion kan komma till användning i en mängd olika situationer. Ett enkelt exempel, beräkna antalet sekunder i en timme: Math.pow (60,2).

Kvadratur och kubrot

Math.sqrt () och Math.cbrt () är motsatsen till Math.pow ()-funktionen. Kom ihåg att kvadratroten ur a är det tal som ger a när det är kvadratiskt.

Math.sqrt (9)> 3
Samtidigt är kubroten av talet a det tal som ger a när det höjs till en kub.

Math.cbrt (125)> 5
Math.cbrt () introducerades till JavaScript-specifikationen alldeles nyligen och stöds därför endast i moderna webbläsare: Chrome 38+, Firefox och Opera 25+ och Safari 7.1+. Du kommer att märka att Internet Explorer inte finns på den här listan, men du hittar en polyfill på MDN.

Exempel på

Naturligtvis kan vi också använda icke-heltalsvärden i en av dessa funktioner:

Math.pow (1,25, 2); > 1,5625 Math.cbrt (56,57)> 3,8387991760286138
Observera att detta också fungerar bra för negativa argumentvärden:

Math.pow (-5,2)> 25 Math.pow (10, -2)> 0,01
Men för en kvadratrot kommer detta inte att fungera:

Math.sqrt (-9)> NaN
Vi vet från matematisk analys att ett imaginärt tal förstås som kvadratrötterna av negativa tal. Och detta kan leda oss till en annan teknik för att arbeta med komplexa tal, men det är en annan historia.

Du kan använda bråkvärden i Math.pow () för att hitta kvadrat- och kubrötter av tal. Kvadratroten använder en exponent på 0,5:

Math.pow (5, 0,5); // = Math.sqrt (5) = 5 ** (1/2)> 2,23606797749979
Men på grund av flytpunktens nycker kan du inte gissa det korrekta resultatet exakt:

Math.pow (2,23606797749979.2)> 5,0000000000000001
I sådana situationer måste du ta till trunkering av tecknen från siffran eller avrundning till något värde.

Vissa, av någon okänd anledning i JavaScript, blandar ihop Math.pow ()-funktionen med Math.exp (), som är en exponentiell funktion för tal i allmänhet. Notera: på engelska översätts "exponent" som "exponent", så det är mer sannolikt att detta refererar till engelsktalande, även om det finns alternativa namn för exponenten, såsom index, makt.

Matematiska konstanter

Att arbeta med matematik i JavaScript underlättas av ett antal inbyggda konstanter. Dessa konstanter är egenskaper hos Math-objektet. Det är värt att notera att konstanter skrivs med versaler, inte CamelCase-notation.

Endast registrerade användare kan delta i undersökningen. , snälla du.

Taggar: Lägg till taggar

Det finns flera exempel:

/ ** * Returnerar ett slumptal mellan min (inklusive) och max (exklusivt) * / funktion getRandomArbitrary (min, max) (retur Math.random () * (max - min) + min;) / ** * Returnerar en slumpmässigt heltal mellan min (inklusive) och max (inklusive). * Värdet är inte lägre än min (eller nästa heltal större än min * om min inte är "t ett heltal) och inte större än max (eller nästa heltal * lägre än max om max inte är ett heltal). * Att använda Math.round () kommer att ge dig en olikformig distribution! * / funktion getRandomInt (min, max) (min = Math.ceil (min); max = Math.floor (max); return Math.floor (Math.random () * (max - min + 1)) + min; )

Här är logiken bakom det. Detta är en enkel regel av tre:

Math.random () returnerar ett tal mellan 0 (inklusive) och 1 (undantag). Så vi har ett intervall så här:

Num3; num3 = num2 - num3; om (nummer3< 0) { num3 += 2147483647; } num2 = this.SeedArray; } for (var j = 1; j < 5; j++) { for (var k = 1; k < 56; k++) { this.SeedArray[k] -= this.SeedArray; if (this.SeedArray[k] < 0) { this.SeedArray[k] += 2147483647; } } } this.inext = 0; this.inextp = 21; Seed = 1; } Random.prototype.milliseconds = function () { var str = new Date().valueOf().toString(); return parseInt(str.substr(str.length - 6)); }; Random.prototype.InternalSample = function () { var num = this.inext; var num2 = this.inextp; if (++num >= 56) (num = 1;) om (++ num2> = 56) (num2 = 1;) var num3 = this.SeedArray - this.SeedArray; if (num3 == 2147483647) (num3--;) if (num3< 0) { num3 += 2147483647; } this.SeedArray = num3; this.inext = num; this.inextp = num2; return num3; }; Random.prototype.Sample = function () { return this.InternalSample() * 4.6566128752457969E-10; }; Random.prototype.GetSampleForLargeRange = function () { var num = this.InternalSample(); var flag = this.InternalSample() % 2 == 0; if (flag) { num = -num; } var num2 = num; num2 += 2147483646.0; return num2 / 4294967293.0; }; Random.prototype.Next = function (minValue, maxValue) { if (!minValue && !maxValue) return this.InternalSample(); var num = maxValue - minValue; if (num <= 2147483647) { return parseInt((this.Sample() * num + minValue).toFixed(0)); } return this.GetSampleForLargeRange() * num + minValue; }; Random.prototype.NextDouble = function () { return this.Sample(); }; Random.prototype.NextBytes = function (buffer) { for (var i = 0; i < buffer.length; i++) { buffer[i] = this.InternalSample() % 256; } }; return Random; }());

Ansökan:

Var r = ny Slumpmässig (); var nextInt = r.Next (1, 100); // returnerar ett heltal mellan intervallet var nextDbl = r.NextDouble (); // returnerar en slumpmässig decimal

När ett slumptal väl har genererats med hjälp av ett datorprogram, anses det fortfarande vara ett slumptal om det valda numret är en del av eller komplett av originalet. Men om det ändrades då matematiker accepterar det inte som ett slumptal och de kan kalla det ett partiskt tal. Men om du utvecklar ett program för en enkel uppgift kommer detta inte att vara fallet. Men om du utvecklar ett program för att generera ett slumpmässigt antal för ett värdefullt material som ett lotteriprogram eller hasardspel, kommer ditt program att avvisas av ledningen om du inte överväger detta fall.

Så, för dessa människor, här är mitt förslag:

Generera ett slumptal med Math.random () (säg att det är n)

Nu för, då är våning n * 10 ditt svar, och om du behöver så är våning n * 100 ditt svar, etc.

Ange nu din roll:

Du har begärt nummer inom ett specifikt intervall. (I det här fallet förskjuts man i det intervallet. – Genom att ta numret från, kasta tärningen, blir man beroende av, men det är fortfarande en slump om och bara om döden är opartisk.)

Så överväg ditt intervall ==> antal element i intervallet = 247 - 78 + 1 = 170; (eftersom båda gränserna är på.

/ * Metod 1: * / vari = 78, j = 247, k = 170, a =, b =, c, d, e, f, l = 0; för (; jag<= j; i++){ a.push(i); } while(l < 170){ c = Math.random()*100; c = Math.floor(c); d = Math.random()*100; d = Math.floor(d); b.push(a[c]); e = c + d; if((b.length != k) && (e < k)){ b.push(a[e]); } l = b.length; } console.log("Method 1:"); console.log(b); /*Method 2:*/ var a, b, c, d = , l = 0; while(l < 170){ a = Math.random()*100; a = Math.floor(a); b = Math.random()*100; b = Math.floor(b); c = a + b; if(c <= 247 || c >= 78) (d. tryck (c);) annars (d. tryck (a);) l = d. längd; ) console.log ("Metod 2:"); console.log (d);

Notera. Först, i den första metoden, skapade jag en array som innehåller de siffror du vill ha, och sedan slumpmässigt placerade jag dem i en annan array. I metod två genererar du slumpmässigt tal och testar dem i det intervall du vill ha. Lägg den sedan i en array. Här har jag genererat två slumptal och använt dem för att maximera programmets hastighet samtidigt som jag minimerar avvisningsfrekvensen samtidigt som jag får ett användbart nummer. Men att lägga till de genererade siffrorna kommer också att ge viss bias. Därför skulle jag rekommendera min första metod för att generera slumptal i ett specifikt intervall.

I båda metoderna kommer din konsol att visa resultatet. (Tryck på f12-knappen i Chrome för att öppna konsolen)

För ett slumpmässigt heltal med ett intervall, försök:

Funktion slumpmässig (minimum, maximum) (var bool = sant; medan (bool) (var nummer = (Math.floor (Math.random () * maximum + 1) + minimum); if (tal> 20) (bool = sant ;) annat (bool = falskt;)) returnummer;)

Med hjälp av följande kod kan du generera en array av slumptal utan att upprepa i ett givet intervall.

Funktion genRandomNumber (how_many_number, min, max) (// parametrar // how_many_number: hur många tal du vill generera. Det är till exempel 5. // min (inklusive): minimum/lågt värde för ett intervall. Det måste vara någon positivt heltal men mindre än max. dvs. 4 // max (inklusive): maxvärdet för ett intervall. det måste vara vilket positivt heltal som helst. dvs. 50 // returtyp: array var random_number =; för (var i = 0; i< how_many_number; i++) { var gen_num = parseInt((Math.random() * (max-min+1)) + min); do { var is_exist = random_number.indexOf(gen_num); if (is_exist >= 0) (gen_num = parseInt ((Math.random () * (max-min + 1)) + min);) else (random_number.push (gen_num); is_exist = -2;)) while (is_exist> -1 ); ) document.getElementById ("box"). innerHTML = random_number; )

För att få ett slumpmässigt tal, säg mellan 1 och 6, gör först:

0,5 + (Math.random () * ((6 - 1) + 1))

Detta multiplicerar slumptalet med 6 och lägger sedan till 0,5 till det. Avrunda sedan talet till ett positivt heltal genom att göra:

Math.round (0,5 + (Math.random () * ((6 - 1) + 1))

Detta avrundar talet till närmaste heltal.

Eller, för att göra det tydligare, gör följande:

Var värde = 0,5 + (Math.random () * ((6 - 1) + 1)) var roll = Math.round (värde); returrulle;

I allmänhet, koden för att göra detta med hjälp av variabler:

Var värde = (Min - 0,5) + (Math.random () * ((Max - Min) + 1)) var roll = Math.round (värde); returrulle;

Anledningen till att subtrahera 0,5 från minimivärdet är att om du bara använder minimivärdet kan du få ett heltal som är större än ditt maximala värde. Genom att ta bort 0,5 från minimivärdet förhindrar du i princip att det maximala värdet avrundas.

Hoppas det hjälper.

Slumpmässigt heltal mellan lägsta och högsta:

Funktion randomRange (l, h) (var range = (hl); var random = Math.floor (Math.random () * range); if (slumpmässigt === 0) (slumpmässigt + = 1;) returnera l + random ;)

Inte den mest eleganta lösningen.. men något snabbt.

Funktionen getRandomInt (nedre, övre) (// för att skapa en jämn provfördelning returnera Math.floor (lower + (Math.random () * (upper - lower + 1))); // för att skapa en ojämn sampelfördelning // return Math.round (lower + (Math.random () * (övre - nedre))); // för att utesluta maxvärdet från de möjliga värdena // return Math.floor (lower + (Math.random () * (övre - nedre)));)

För att testa den här funktionen och varianter av den här funktionen, spara HTML / JavaScript nedan i en fil och öppna den i en webbläsare. Koden kommer att visa en graf som visar fördelningen av en miljon funktionsanrop. Koden kommer också att registrera kantfall, så om funktionen producerar ett värde som är större än max eller mindre än min, kommer du.att.veta.om.det.

Här använder jag för att generera slumptal.

Funktion slumpmässig (hög, låg) (hög ++; return Math.floor ((Math.random ()) * (hög-låg)) + låg;)

Vi gör höga ++ eftersom Math.random () genererar ett slumptal mellan 0, (inklusive) och 1 (undantag). Uteslutet betyder att vi måste öka med max en innan vi gör någon matematik. Vi subtraherar sedan det låga värdet från det höga, vilket ger oss det högsta talet att generera - lågt, sedan + lågt, vilket återgår till det normala och gör det lägsta talet åtminstone lågt. sedan returnerar vi det resulterande numret

slumpmässig (7,3) kan returnera 3,4,5,6 eller 7

Här är ett exempel på en javascript-funktion som kan generera ett slumptal av vilken längd som helst utan att använda Math.random ():

Funktion genRandom (längd) (konst t1 = nytt datum (). GetMilliseconds (); var min = "1", max = "9"; var resultat; var numLength = längd; if (numLength! = 0) (för (var) i = 1; i< numLength; i++) { min = min.toString() + "0"; max = max.toString() + "9"; } } else { min = 0; max = 0; return; } for (var i = min; i <= max; i++) { //Empty Loop } const t2 = new Date().getMilliseconds(); console.log(t2); result = ((max - min)*t1)/t2; console.log(result); return result; }

Uint8Array skapar en array fylld med upp till tre siffror, som inte får vara fler än 999. Denna kod är mycket kort.

detta är mitt val av ett slumptal i ett intervall eftersom jag ville få ett slumptal i intervallet från bas till exponent. t ex bas = 10, exponent = 2, ger ett slumptal mellan 0 och 100, helst, etc.

om det hjälper att använda det, här är det:

// få slumptal inom tillhandahållen bas + exponent // av Goran Biljetina -> 2012 funktion är Tom (värde) (retur (typvärde === "(! LANG: odefinierad" || value === null); } var numSeq = new Array(); function add(num,seq){ var toAdd = new Object(); toAdd.num = num; toAdd.seq = seq; numSeq = toAdd; } function fillNumSeq (num,seq){ var n; for(i=0;i!}<=seq;i++){ n = Math.pow(num,i); add(n,i); } } function getRandNum(base,exp){ if (isEmpty(base)){ console.log("Specify value for base parameter"); } if (isEmpty(exp)){ console.log("Specify value for exponent parameter"); } fillNumSeq(base,exp); var emax; var eseq; var nseed; var nspan; emax = (numSeq.length); eseq = Math.floor(Math.random()*emax)+1; nseed = numSeq.num; nspan = Math.floor((Math.random())*(Math.random()*nseed))+1; return Math.floor(Math.random()*nspan)+1; } console.log(getRandNum(10,20),numSeq); //testing: //getRandNum(-10,20); //console.log(getRandNum(-10,20),numSeq); //console.log(numSeq);

Math.random () är snabb och lämplig för många ändamål, men den är inte lämplig om du behöver kryptografiskt säkra värden (osäkra) eller om du vill ha heltal från en perfekt enhetlig opartisk fördelning (multiplikationsmetoden som används i andra svar ger vissa värden lite oftare än andra).

I sådana fall kan vi använda crypto.getRandomValues ​​() för att generera säkra heltal och förkasta alla genererade värden som vi inte kan mappa enhetligt till målområdet. Detta kommer att gå långsammare, men det borde inte vara betydande om du inte genererar ett mycket stort antal värden.

För att klargöra problemet med snedfördelning, överväg fallet där vi vill generera ett värde mellan 1 och 5, men vi har en slumptalsgenerator som producerar värden mellan 1 och 16 (ett 4-bitars värde). Vi vill ha samma antal genererade värden mappade till varje utdatavärde, men 16 är inte jämnt delbart med 5: det finns en återstod av 1. Så vi måste förkasta 1 av de möjliga genererade värdena och bara fortsätta när vi får ett av 15 mindre värden som kan mappas jämnt till vårt målområde. Vårt beteende kan se ut så här:

Generera ett 4-bitars heltal i intervallet 1-16. Om vi ​​genererade 1, 6 eller 11 så utgång 1. Om vi ​​genererade 2, 7 eller 12 så utgång 2. Om vi ​​genererade 3, 8 eller 13 så utgång 3. Om vi ​​genererade 4, 9 eller 14 så utgång 4. Om vi ​​genererade 5, 10 eller 15, utgång 5. Om vi ​​genererade 16, avvisa det och försök igen.

Följande kod använder liknande logik, men genererar istället ett 32-bitars heltal eftersom det är den största vanliga heltalsstorleken som kan representeras av standardnummertypen JavaScript. (Detta kan ändras till att använda BigInt om du behöver ett större intervall.) Oavsett vilket intervall som väljs kommer andelen genererade värden som avviker alltid att vara mindre än 0,5, så den förväntade avvikelsen kommer alltid att vara mindre än 1,0, och vanligtvis nära 0,0; Du behöver inte oroa dig för att det ska fastna för alltid.

const randomInteger = (min, max) => (konst intervall = max - min; const maxGeneratedValue = 0xFFFFFFFF; const possibleResultValues ​​= intervall + 1; const possibleGeneratedValues ​​= maxGeneratedValue + 1; const maxGeneratedValue = 0xFFFFFFFF ​​= maxGeneratedValues ​​= maxGeneratedValues ​​= max ; om (! Number.isInteger (min) ||! Number.isInteger (max) || max> Number.MAX_SAFE_INTEGER || min< Number.MIN_SAFE_INTEGER) { throw new Error("Arguments must be safe integers."); } else if (range >maxGeneratedValue) (kasta nytt fel ("Omfång för $ (intervall) (från $ (min) till $ (max))> $ (maxGeneratedValue).");) annat om (max.< min) { throw new Error("max (${max}) must be >= min ($ (min)). ");) annars om (min === max) (retur min;) låter genereras; gör (genererad = crypto.getRandomValues ​​(ny Uint32Array (1));) while ( genererad> maxUnbiased); return min + (genererade % möjliga ResultatValues);); console.log (randomInteger (-8, 8)); // -2 console.log (randomInteger (0, 0)); // 0 console. log ( randomInteger (0, 0xFFFFFFFF)); // 944450079 console.log (randomInteger (-1, 0xFFFFFFFF)); // Fel: Intervallet 4294967296 som täcker -1 till 4294967295 is> 429529 (Array. console.6 (new console.6) ). fyll (). map (n => randomInteger (8, 12))); //

De Math.random () funktion returnerar ett flyttal, pseudoslumptal i intervallet 0–1 (inklusive 0, men inte 1) med ungefär enhetlig fördelning över det intervallet - som du sedan kan skala till ditt önskade intervall. Implementeringen väljer det initiala fröet till algoritmen för generering av slumptal; den kan inte väljas eller återställas av användaren.

Math.random () gör inte tillhandahålla kryptografiskt säkra slumptal. Använd dem inte för något som har med säkerhet att göra. Använd Web Crypto API istället, och mer exakt metoden.

Syntax

Math.random ()

Returvärde

Ett flyttande, pseudo-slumptal mellan 0 (inklusive) och 1 (exklusivt).

Exempel

Observera att eftersom siffror i JavaScript är IEEE 754 flyttal med avrundat-till-närmast-jämnt beteende, är intervallen som gör anspråk på funktionerna nedan (exklusive det för själva Math.random () inte exakta. Om extremt stora gränser är valda (2 53 eller högre), är det möjligt i ytterst sällsynta fall för att beräkna den vanligtvis uteslutna övre gränsen.

Få ett slumptal mellan 0 (inklusive) och 1 (exklusivt)

funktion getRandom () (retur Math.random ();)

Få ett slumptal mellan två värden

Detta exempel returnerar ett slumptal mellan de angivna värdena. Det returnerade värdet är inte lägre än (och kan möjligen vara lika med) min och är mindre än (och inte lika med) max.

Funktion getRandomArbitrary (min, max) (retur Math.random () * (max - min) + min;)

Få ett slumpmässigt heltal mellan två värden

Detta exempel returnerar en slumpmässig heltal mellan de angivna värdena. Värdet är inte lägre än min (eller nästa heltal större än min om min inte är ett heltal) och är mindre än (men inte lika med) max.

Funktion getRandomInt (min, max) (min = Math.ceil (min); max = Math.floor (max); return Math.floor (Math.random () * (max - min)) + min; // Maximum är exklusiv och minimum är inklusive)

Det kan vara frestande att använda Math.round () för att åstadkomma det, men om du gör det skulle dina slumptal följa en olikformig fördelning, vilket kanske inte är acceptabelt för dina behov.

Att få ett slumpmässigt heltal mellan två värden, inklusive

Medan funktionen getRandomInt () ovan är inkluderande som minimum, är den maximalt exklusiv. Vad händer om du behöver att resultaten ska vara inkluderande på både minimum och maximum? Funktionen getRandomIntInclusive () nedan åstadkommer det.

Funktion getRandomIntInclusive (min, max) (min = Math.ceil (min); max = Math.floor (max); return Math.floor (Math.random () * (max - min + 1)) + min; // Maximum är inklusive och minimum är inklusive)

Specifikationer

Specifikation Status Kommentar
ECMAScript 1:a upplagan (ECMA-262) Standard Initial definition. JavaScript 1.0 (endast UNIX) / JavaScript 1.1 (alla plattformar).
ECMAScript 5.1 (ECMA-262)
Standard
ECMAScript 2015 (6:e upplagan, ECMA-262)
Definitionen av "Math.random" i den specifikationen.
Standard
ECMAScript senaste utkast (ECMA-262)
Definitionen av "Math.random" i den specifikationen.
Förslag

Webbläsarkompatibilitet

Kompatibilitetstabellen på den här sidan genereras från strukturerad data. Om du "vill bidra till datan, kolla in https://github.com/mdn/browser-compat-data och skicka oss en pull-förfrågan.

Uppdatera kompatibilitetsdata på GitHub

SkrivbordMobilServer
KromKantFirefoxInternet ExplorerOperaSafariAndroid webbvyChrome för AndroidFirefox för AndroidOpera för AndroidSafari på iOSSamsung InternetNode.js
slumpmässigChrome Fullt stöd JaEdge Fullständigt stöd 12Firefox Fullständigt stöd 1IE Fullt stöd JaOpera Fullt stöd JaSafari Fullt stöd JaWebView Android Fullt stöd JaChrome Android Fullt stöd JaFirefox Android Fullständigt stöd 4Opera Android Fullt stöd JaSafari iOS Fullständigt stöd JaSamsung Internet Android Fullt stöd Janodejs Fullt stöd Ja

En "algoritm" för slumpmässigt urval av värden från en array utan att upprepa dem. Mer specifikt, som en del av JS-träning, använde jag den för att skapa en klassisk RPG-grupp av karaktärer (barbar, magiker, tjuv, riddare, präst), utan att upprepa klasser och namn.

Principen är extremt enkel, men den kan vara användbar för JS-nybörjare som jag. Länken till RPG är extremt symbolisk – nu försöker jag aktivt ändra min profil från marknadsföring till IT (jag insåg att min själ ljuger), och det är mycket mer intressant att träna på ett lekfullt sätt.

1. Skapa en mall

Innan du skapar en grupp tecken måste du ställa in en mall för att generera dem. Egentligen här:

Funktion GamePlayer (n, r, l, p) (this.nick = n; this.role = r; this.level = l; this.portrait = p;)
Faktum är att den här funktionen kommer att skapa tecken från de variabler som den kommer att anropas genom. Till exempel:

Var player1 = ny GamePlayer ("Power Ranger", "barbar", "64", "img / barbarian.jpg")
Nu lagrar variabeln spelare1 en Power Ranger-barbar på nivå 64 med ett visst porträtt; vi kan visa vilken som helst av dess parametrar i kroppen på sidan med hjälp av player1.nick, player1.level, etc.

Värdena (n, r, l, p) från GamePlayer ansvarar för att ta emot och ta emot data till funktionen. Om n och r byts om i exemplet, kommer den mäktiga ranger Barbarian att stanna kvar i spelare1, vilket inte riktigt motsvarar uppgiften.

2. Ställa in arrayer

För att inte skapa karaktärer på egen hand, utan nästan slumpmässigt generera dem (som utlovat i titeln), behöver vi arrayer från vilka vi tar parametrarna för just dessa karaktärer. Som redan beskrivits ovan har vi bara 4 parametrar: karaktärsnamn, klass, nivå och porträtt.

Array för namn:

Var playerNames = ["Rabbit Helpless", "Warm Dreaded Foal", "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"];
Det skulle vara möjligt att gå längre och generera namn på 2-3 komponenter, men algoritmen för en sådan förbättring innehåller inget nytt (samma slumpmässighet), och skulle då helt enkelt komplicera utbildningsprocessen.

Array för klassen:

Var playerRoles = ["barbar", "mage", "skurk", "riddare", "präst"];
Allt är lika självklart. Flera strängar, från vilka vi sedan väljer värden som ska visas på sidan.

Array för nivån:

För ett specifikt exempel ville jag att alla gruppmedlemmar skulle vara mellan nivå 60 och 70. Men eftersom förutsättningarna kan ändras, var det nödvändigt att skapa en array från 0 till 80 nivåer, från vilken man sedan väljer önskade värden. Skapat i en loop:

Var playerLevels =; för (i = 0; i<= 80;i++) { console.log(i); playerLevels[i] = i; }
Resultatet är en array playerLevels, där varje cell innehåller en int med sitt eget nummer.

Array för porträtt:

Var playerPortraits = ["img / barbarian.jpg", "img / mage.jpg", "img / rogue.jpg", img / knight.jpg "," img / priest.jpg "];
Samma princip, men istället för text använder vi länkar till bilder. Vidare kan vi ersätta dem i bakgrundsbildsparametern för önskad div (eller i src-parametern för den önskade bilden, eftersom det är bekvämare för alla).

Det är viktigt att ordningen på bilderna i playerPortraits arrayen är identisk med ordningen på klasserna i playerRoles arrayen, då kan vi använda samma slumpvariabel för att generera dem (så att bilden matchar klassen).

3. Generera tecken

Det ska som sagt finnas 5 tecken i gruppen. Därför skapar vi en cykel:

För (i = 0; i<=4;i++) { }
Innan loopen är det viktigt att deklarera en array för våra framtida karaktärer:

Var spelare =;

Var namerand = Math.floor (Math.random () * playerNames.length)

  • Marh.random () används för att generera ett slumptal;
  • Multiplikation med playerNames.length (längden på playerNames-arrayen) - för att begränsa slumptalet till antalet namn i arrayen;
  • Math.floor - för att konvertera det resulterande talet till ett heltal.
Nyansen är att Math.floor avrundas nedåt, men eftersom numreringen i arrayerna börjar från 0 så passar det oss.

Skapar klasser

Principen och genomförandet är densamma:

Var rolerand = Math.floor (Math.random () * (playerRoles.length));
Den enda skillnaden är att för klasserna använder vi arrayen playerRoles.

Nivågenerering

Var levelrand = Math.floor (Math.random () * (70 - 60 + 1) + 60);
Beräkningen av slumpmässigt i ett visst intervall sker enligt formeln Math.random () * (max - min) + min.

I exemplet får vi slumpen från 0 till 10 och lägger sedan till 60 till det, och får intervallet från 60 + 0 till 60 + 10 (vilket är vad vi behöver). Att lägga till en enhet är nödvändigt på grund av användningen av Math.floor (läs ovan).

Genererar karaktärer

Före sista steget. För att bilda ett tecken måste vi kombinera alla dess parametrar till en variabel, som i det första exemplet. Det ser ut så här:

Spelare [i] = ny Spelare (spelarenamn, spelarroller, spelarnivåer, spelarporträtt);
Faktum är att varje karaktär blir en del av spelararrayen med sitt eget ordningsnummer. Dess parametrar:

  • spelarnamn - namn, slumpmässigt urval från namn (cell under namn och nummer i spelarnamn);
  • playerRoles - klass, slumpmässigt urval från klasser;
  • playerLevels - klass, slumpmässigt val av nivå i intervallet 60-70;
  • playerPortraits - porträtt, slumpmässigt urval från porträtt.
Som jag noterade ovan måste uppsättningarna av porträtt och klasser vara identiska för att "bilden ska matcha"; därför kan vi använda samma slumpmässiga i båda fallen.

Styrt slumpmässigt

Den slutliga. Om det lämnas som det är kommer det att fungera. Däremot kommer vi att få en grupp karaktärer av väldigt olika klasser (t.ex. 3 magiker och 2 tjuvar) med samma namn. För att undvika detta räcker det med ett par enkla steg:

Spelare [i] = ny Spelspelare (spelarenamn, spelareroller, spelarenivåer, spelareporträtt); playerNames.splice (namnrand, 1); playerRoles.splice (rolerand, 1); playerPortraits.splice (rolerand, 1);
Omedelbart efter att vi tilldelar tecknet parametrar tar vi bort deras celler från motsvarande arrayer.

Närmare bestämt tar playerNames.splice (namerand, 1) bort luckan numrerad namerand från playerNames-arrayen med splice-operationen. Enheten efter decimaltecknet visar hur många celler som behöver tas bort från den angivna; vi behöver bara ta bort en, den angivna cellen själv.

Vidare upprepas slingan igen och kan returnera odefinierad om den stöter på den sista cellen i arrayen (trots allt minskade vi den med 1). Men eftersom vår Math.random använder playerNames.length och andra, beror det direkt på längden på arrayen och kommer bara att producera nya, icke-duplicerade värden.

4. Slutsats

Dessutom kan du beskriva interaktionen mellan det här skriptet och sidan: visa "kort" av karaktärer, ladda deras porträtt, etc., men detta är en ganska uppenbar process förknippad med JS huvudfunktioner. Dessutom har jag redan skärpt min enkla manual lite. Så du kan se visualiseringen av processen i exemplet.






2021 gtavrl.ru.