Función generadora de números aleatorios en javascript. Números aleatorios. Recortando la parte fraccionaria

Muy a menudo, los cálculos en JavaScript no dan exactamente los resultados que queremos. Por supuesto, podemos hacer lo que queramos con los números: redondear hacia arriba o hacia abajo, establecer rangos, cortar números innecesarios para una cierta cantidad decimales, todo depende de lo que quieras hacer a continuación con este número.

0.1 * 0.2; > 0.020000000000000004 0.3 - 0.1 > 0.19999999999999998
¿Por qué es necesario el redondeo?

Uno de los aspectos interesantes de JavaScript es que en realidad no almacena números enteros, trabajamos directamente con números de punto flotante. Esto, combinado con el hecho de que muchos valores fraccionarios no se pueden expresar en un número finito de decimales, en JavaScript podemos obtener resultados como este: A efectos prácticos, esta inexactitud no importa, en nuestro caso estamos hablando de un error de quintillones de partes, sin embargo, esto puede decepcionar a algunos. También podemos obtener resultados un tanto extraños al trabajar con números que representan monedas, porcentajes o tamaños de archivos. Para corregir estas imprecisiones, sólo necesitamos poder redondear los resultados, y basta con establecer la precisión decimal. Redondear números tiene aplicación práctica.

, podemos estar manipulando un número dentro de algún rango, por ejemplo queremos redondear el valor al entero más cercano en lugar de trabajar solo con parte decimal Redondear números decimales Para cortar numero decimal, utilice toFixed o el método toPrecision. Ambos toman un único argumento, que determina, respectivamente, cuántos
  • cifras significativas (es decir, el número total de dígitos utilizados en el número) o lugares decimales (el número después del punto decimal) deben incluir el resultado: Si un argumento no está definido para toFixed() entonces su valor predeterminado será cero, lo que significa 0 decimales que tiene el argumento.
  • valor máximo
  • , igual a 20.
    Tanto el método toFixed() como toPrecision() devuelven una representación de cadena del resultado, no un número. Esto significa que al sumar un valor redondeado con randNum, se producirá una concatenación de cadenas en lugar de una suma de números:

    Sea randNum = 6,25; dejar redondeado = randNum.toFixed(); // "6" console.log(randNum + redondeado); > "6.256"
    Si quieres que el resultado sea tipo numérico datos, entonces necesitarás aplicar parseFloat:

    Sea randNum = 6,25; let redondeado = parseFloat(randNum.toFixed(1)); console.log(redondeado); > 6.3
    Tenga en cuenta que los valores de 5 se redondean excepto en casos excepcionales.

    Los métodos toFixed() y toPrecision() son útiles porque no sólo pueden recortar parte fraccionaria, pero también para agregar decimales, lo cual es conveniente cuando se trabaja con moneda:

    Sea WholeNum = 1 let dólaresCents = WholeNum.toFixed(2); console.log(dólaresCents); > "1,00"
    Vale la pena señalar que toPrecision producirá el resultado en notación exponencial si el número de números enteros es mayor que la precisión misma:

    Sea num = 123.435 num.toPrecision(2); > "1.2e+2"

    Cómo evitar errores de redondeo con decimales En algunos casos, toFixed y toPrecision redondean el valor 5 hacia abajo y hacia arriba:

    Sea numTest = 1.005; numTest.toFixed(2); > "1,00"
    El resultado del cálculo anterior debería haber sido 1,01, no 1. Si desea evitar error similar, podemos utilizar la solución propuesta por Jack L Moore, que utiliza números exponenciales para calcular:

    Función ronda(valor, decimales) ( return Número(Math.round(valor+"e"+decimales)+"e-"+decimales); )
    Ahora:

    Ronda(1.005,2); > 1.01
    Si desea una solución más sólida que la que se muestra arriba, puede ir a MDN.

    Redondeo épsilon automático En ES6 se introdujo un método alternativo para redondear números decimales. El redondeo épsilon automático proporciona un margen de error razonable al comparar dos números de coma flotante. Sin redondeo, las comparaciones pueden producir resultados similares a los siguientes:

    0,1 + 0,2 === 0,3 > falso
    Usamos Math.EPSILON en nuestra función para obtener una comparación válida:

    Función epsEqu(x, y) (retorna Math.abs(x - y)< Number.EPSILON * Math.max(Math.abs(x), Math.abs(y)); }
    La función toma dos argumentos: el primero es el cálculo actual, el segundo es el resultado esperado. Devuelve una comparación de los dos:

    EpsEqu(0,1 + 0,2, 0,3) > verdadero
    Todos los navegadores modernos ya son compatibles con ES6 funciones matemáticas pero si desea compatibilidad con navegadores como IE 11, utilice polyfills.

    Cortar la parte fraccionaria Todos los métodos presentados anteriormente pueden redondear a números decimales. Para simplemente reducir un número a dos decimales, primero debes multiplicarlo por 100 y luego dividir el resultado entre 100:

    Función truncada(num) ( return Math.trunc(num * 100) / 100; ) truncada(3.1416) > 3.14
    Si desea adaptar el método a cualquier número de decimales, puede utilizar la doble negación bit a bit:

    Función truncada (num, decimalPlaces) ( let numPowerConverter = Math.pow(10, decimalPlaces); return ~~(num * numPowerConverter)/numPowerConverter; )
    Ahora:

    Sea randInt = 35,874993; truncado(randInt,3); > 35.874

    Redondear al número más cercano Para redondear un número decimal al número más cercano hacia arriba o hacia abajo, cualquiera que estemos más cerca, use Math.round():

    Ronda.matemáticas(4.3) > 4 Ronda.matemáticas(4.5) > 5
    Tenga en cuenta que "la mitad del valor", 0,5 se redondea a lado grande según las reglas de las matemáticas.

    Redondear hacia abajo al número entero más cercano Si desea redondear siempre hacia abajo, utilice Math.floor:

    Piso.matemáticas(42.23); > 42 Matemáticas.piso(36,93); > 36
    Tenga en cuenta que el redondeo hacia abajo funciona para todos los números, incluidos los números negativos. Imagine un rascacielos con un número infinito de pisos, incluidos los pisos del nivel inferior (que representan números negativos). Si estás en un ascensor nivel inferior entre 2 y 3 (que representa un valor de -2,5), Math.floor te llevará a -3:

    Piso.matemático(-2.5); > -3
    Pero si quiere evitar esta situación, utilice Math.trunc, que es compatible con todos navegadores modernos(excepto IE/Edge):

    Math.trunc(-41.43); > -41
    En MDN encontrará un polyfill que brindará soporte para Math.trunc en navegadores e IE/Edge.

    Redondear al número entero más cercano Por otro lado, si siempre necesitas redondear, utiliza Math.ceil. Nuevamente, recuerda el ascensor infinito: Math.ceil siempre irá "hacia arriba", independientemente de si el número es negativo o no:

    Matemáticas.ceil(42.23); > 43 Matemáticas.ceil(36,93); > 37 Matemáticas.ceil(-36.93); > -36

    Redondear hacia arriba/abajo al número necesario Si queremos redondear al múltiplo de 5 más cercano, la forma más sencilla es crear una función que divida el número entre 5, lo redondee y luego lo multiplique por la misma cantidad:

    Función roundTo5(num) ( return Math.round(num/5)*5; )
    Ahora:

    RedondearA5(11); > 10
    Si desea redondear a múltiplos de su valor, usamos más función general, pasándole el valor inicial y un múltiplo:

    Función roundToMultiple(num, multiple) ( return Math.round(num/multiple)*multiple; )
    Ahora:

    Sea NúmeroInicial = 11; sea ​​múltiplo = 10; roundToMultiple(númeroinicial, múltiple); > 10;

    Fijar un número en un rango Hay muchos casos en los que queremos obtener un valor de x que se encuentre dentro de un rango. Por ejemplo, es posible que necesitemos un valor entre 1 y 100, pero terminamos con un valor de 123. Para solucionar este problema, podemos usar min (devuelve el menor de un conjunto de números) y max (devuelve el mayor de cualquier conjunto). de números). En nuestro ejemplo, el rango es de 1 a 100:

    Sea límite bajo = 1; sea ​​límite alto = 100; let numInput = 123; dejar sujetado = Math.max(lowBound, Math.min(numInput, highBound)); console.log(sujetado); > 100;
    Nuevamente, podemos reutilizar la operación y envolver todo en una función, usando la solución propuesta por Daniel X. Moore:

    Número.prototipo.clamp = función(min, max) ( return Math.min(Math.max(this, min), max); );
    Ahora:

    NumInput.clamp(límite inferior, límite superior); > 100;

    Redondeo gaussiano El redondeo gaussiano, también conocido como redondeo bancario, es donde el redondeo en este caso se produce al número par más cercano. Este método de redondeo funciona sin errores estadísticos. La mejor solución fue sugerido por Tim Down:

    Función gaussRound(num, decimalPlaces) ( let d = decimalPlaces || 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; }
    Ahora:

    GaussRound(2.5) > 2 gaussRound(3.5) > 4 gaussRound(2.57,1) > 2.6
    Decimal en CSS:

    Dado que JavaScript se usa a menudo para crear asignaciones posicionales para elementos HTML, quizás te preguntes qué pasaría si generáramos valores decimales para nuestros elementos:

    #caja ( ancho: 63.667731993px; )
    La buena noticia es que los navegadores modernos respetarán los valores decimales en modelo de bloque, incluido el porcentaje o las unidades de píxeles.

    Ordenar Muy a menudo necesitamos ordenar algunos elementos, por ejemplo, tenemos una serie de registros del juego y deben organizarse en orden descendente según el rango del jugador. Desafortunadamente, método estándar sort() tiene algunas limitaciones sorprendentes: funciona bien con los utilizados con frecuencia en palabras en ingles, pero se estropea inmediatamente cuando encuentra números, caracteres únicos o palabras en mayúsculas. Ordenar por orden alfabético Parecería que ordenar una matriz alfabéticamente debería ser una tarea sencilla:

    Let fruta = ["calabaza", "albaricoque", "melón"]; fruta.sort(); > "albaricoque", "calabaza", "melón"]
    Sin embargo, nos encontramos con un problema en cuanto uno de los elementos está en mayúscula:

    Let fruta = ["calabaza", "albaricoque", "melón"]; fruta.sort(); > "Melón", "albaricoque", "calabaza"]
    Esto se debe a que, de forma predeterminada, el clasificador compara el primer carácter representado en Unicode. Unicode es código único para cualquier símbolo, independientemente de la plataforma, independientemente del programa, independientemente del idioma. Por ejemplo, si nos fijamos en la tabla de códigos, el carácter “a” tiene el valor U+0061 (en sistema hexadecimal 0x61), mientras que el carácter "C" tiene el código U+0043 (0x43), que aparece antes en la tabla Unicode que el carácter "a".

    Para ordenar una matriz que puede contener primeras letras en mayúsculas y minúsculas mixtas, necesitamos convertir todos los elementos temporalmente a minúscula, o defina su propio orden de clasificación utilizando el método localeCompare() con algunos argumentos. Como regla general, para tal caso, es mejor crear inmediatamente una función para uso repetido:

    Función alphaSort(arr) ( arr.sort(function (a, b) ( return a.localeCompare(b, "en", ("sensibilidad": "base")); )); ) let fruit = ["calabaza ", "albaricoque", "Melón"]; alfaOrdenar(fruta) >
    Si desea que la matriz esté ordenada en orden alfabético inverso, simplemente intercambie las posiciones de a y b en la función:

    Función alphaSort(arr) ( arr.sort(function (a, b) ( return b.localeCompare(a, "en", ("sensitivity": "base")); )); ) let fruit = ["calabaza ", "albaricoque", "Melón"]; alphaSort(fruta) > ["Melón", "calabaza", "albaricoque"]
    Aquí vale la pena señalar que localeCompare se usa con argumentos, también debemos recordar que es compatible con IE11+, para versiones anteriores de IE, podemos usarlo sin argumentos y en minúsculas:

    Función caseSort(arr) ( arr.sort(function (a, b) ( return a.toLowerCase().localeCompare(b.toLowerCase()); )); ) let fruit = ["calabaza", "albaricoque", "Cantalupo"]; caseSort(fruta) > ["albaricoque", "calabaza", "Melón"]

    Clasificación numérica Todo esto no se aplica al ejemplo del que hablamos anteriormente sobre la matriz de registros del juego. con algunos matrices numéricas La clasificación funciona perfectamente, pero en algún momento el resultado puede ser impredecible:

    Deje puntuaciones altas =; puntuaciones altas.sort(); >
    El caso es que método de clasificación() realiza una comparación lexicográfica: lo que significa que los números se convertirán en una cadena y las comparaciones se realizarán nuevamente haciendo coincidir el primer carácter de esa cadena en el orden de caracteres de la tabla Unicode. Por lo tanto, nuevamente necesitamos definir nuestro orden de clasificación:

    Deje puntuaciones altas =; highScores.sort(función(a,b) ( devolver a - b; )); >
    Nuevamente, para ordenar números en orden inverso, intercambie las posiciones de a y b en la función.

    Ordenar una estructura tipo JSON Finalmente, si tenemos una estructura de datos tipo JSON representada como una matriz de registros del juego:

    Deje puntuaciones = [ ( "nombre": "Daniel", "puntuación": 21768), ( "nombre": "Michael", "puntuación": 33579), ( "nombre": "Alison", "puntuación": 38395 ) ];
    En ES6+, puedes usar funciones de flecha:

    Puntuaciones.sort((a, b) => b.puntuación - a.puntuación));
    Para navegadores más antiguos que no tienen este soporte:

    Scores.sort(función(a, b) (devuelve a.score - b.score));
    Como puede ver, ordenar en JavaScript es algo bastante oscuro, espero que estos ejemplos le hagan la vida más fácil de alguna manera.

    Trabajar con funciones de potencia La exponenciación es una operación definida originalmente como el resultado de una multiplicación repetida. número natural sobre sí misma, la raíz cuadrada de a es el número que da a cuando se eleva al cuadrado. Podríamos utilizar estas funciones constantemente en vida cotidiana en lecciones de matemáticas, incluido el cálculo de áreas, volúmenes o incluso modelado físico.

    En JavaScript función de potencia introducido como Math.pow(), fue introducido en el nuevo estándar ES7 nuevo operador exponenciación - " * * ".

    Elevando a una potencia Para elevar un número a la enésima potencia, use la función Math.pow(), donde el primer argumento es el número que será elevado a la potencia, el segundo argumento es el exponente:

    Matemáticas.pow(3,2) > 9
    Esta forma de notación significa 3 al cuadrado, o 3 × 3, lo que lleva al resultado 9. Por supuesto, se puede dar otro ejemplo:

    Matemáticas.pow(5,3); > 125
    Es decir, 5 al cubo, o 5 × 5 × 5, es igual a 125.

    ECMAScript 7 es próxima versión En JavaScript, en principio, podemos usar el nuevo operador de exponenciación propuesto - * *, esta forma de notación puede ser más descriptiva:

    3 ** 2 > 9
    En en este momento El soporte para este operador es bastante limitado, por lo que no se recomienda su uso.

    La función de potencia puede resultar útil en la mayoría de los casos. diferentes situaciones. Un ejemplo sencillo, calculando el número de segundos en una hora: Math.pow (60,2).

    La raíz cuadrada y cúbica Math.sqrt() y Math.cbrt() son lo opuesto a Math.pow(). Como recordamos, la raíz cuadrada de a es el número que da a al elevarlo al cuadrado.

    Matemáticas.sqrt(9) > 3
    Al mismo tiempo, la raíz cúbica de a es un número que da a cuando se eleva a un cubo.

    Matemáticas.cbrt(125) > 5
    Math.cbrt() se introdujo recientemente en la especificación de JavaScript y, por lo tanto, solo es compatible con los navegadores modernos: Chrome 38+, Firefox y Opera 25+, y Safari 7.1+. Notarás que Explorador de Internet no está en esta lista, pero encontrarás un polyfill en MDN.

    Ejemplos Por supuesto, podemos usar valores no enteros en una de estas funciones:

    Matemáticas.pow(1,25, 2); > 1,5625 Matemáticas.cbrt(56,57) > 3,8387991760286138
    Tenga en cuenta que esto funciona bastante bien cuando se utiliza valores negativos argumentos:

    Matemáticas.pow(-5,2) > 25 Matemáticas.pow(10,-2) > 0,01
    Sin embargo, esto no funcionará para la raíz cuadrada:

    Matemáticas.sqrt(-9) > NaN
    De análisis matemático Sabemos que por número imaginario nos referimos a las raíces cuadradas de números negativos. Y esto puede llevarnos a otra técnica para trabajar con números complejos, pero esa es otra historia.

    Puedes usar valores fraccionarios en Math.pow() para encontrar cuadrados y raíces cúbicas números. Raíz cuadrada utiliza el exponente 0,5:

    Matemáticas.pow(5, 0,5); // = Math.sqrt(5) = 5 ** (1/2) > 2.23606797749979
    Sin embargo, debido a los caprichos del punto flotante, no se puede adivinar exactamente el resultado correcto:

    Matemáticas.pow(2.23606797749979,2) > 5.000000000000001
    En tales situaciones, tendrá que recurrir a cortar signos del número o redondearlo a algún valor.

    Algunas personas, por razones desconocidas, en JavaScript confunden la función Math.pow() con Math.exp() , que es función exponencial para números en general. Nota: en Inglés"exponente" se traduce como "exponente", por lo que es más probable que esto se aplique a los angloparlantes, aunque existen nombres alternativos para el exponente, como índice, potencia.

    Constantes matemáticas Trabajar con matemáticas en JavaScript se hace más fácil gracias a una serie de constantes integradas. Estas constantes son propiedades del objeto Math. Vale la pena señalar que las constantes se escriben en mayúsculas, no en notación CamelCase.

    Sólo los usuarios registrados pueden participar en la encuesta. , Por favor.

    Tags: Añadir etiquetas 2 junio 2013 a las 22:56 Controlado al azar en JavaScript
    • javascript

    Un "algoritmo" para seleccionar valores aleatoriamente de una matriz sin repetirlos. Más específicamente, como parte de mi entrenamiento en JS, lo usé para generar un grupo de personajes de RPG clásico (bárbaro, mago, ladrón, caballero, sacerdote), sin repetir clases ni nombres.

    El principio es extremadamente simple, pero puede resultar útil para principiantes en JS como yo. La conexión con los juegos de rol es puramente simbólica: ahora estoy intentando activamente cambiar mi perfil de marketing a TI (me di cuenta de que mi alma miente) y practicar forma de juego mucho más interesante.

    1. Crea una plantilla Antes de generar un grupo de personajes, debes configurar una plantilla para su generación. En realidad, aquí está:

    Función GamePlayer(n, r, l, p) ( this.nick = n; this.role = r; this.level = l; this.portrait = p; )
    De hecho, esta función creará caracteres a partir de las variables a través de las cuales será llamada. Por ejemplo:

    Var jugador1 = nuevo GamePlayer("Power Ranger","bárbaro","64","img/barbarian.jpg")
    Ahora la variable jugador1 almacena un bárbaro Power Ranger de nivel 64 con un retrato específico; podemos mostrar cualquiera de sus parámetros en el cuerpo de la página usando player1.nick, player1.level, etc.

    Los valores (n, r, l, p) de GamePlayer son responsables de la recepción y el orden en que se reciben los datos en la función. Si en el ejemplo intercambiamos n y r, entonces el poderoso guardabosques Bárbaro permanecerá en el jugador 1, lo que no corresponde del todo a la tarea.

    2. Definir matrices Para no crear personajes nosotros mismos, sino generarlos casi aleatoriamente (como se promete en el título), necesitamos matrices de las que tomaremos los parámetros de esos mismos personajes. Como ya se describió anteriormente, solo tenemos 4 parámetros: nombre del personaje, clase, nivel y retrato.

    Matriz para el nombre:

    Var playerNames = ["Conejo indefenso", "Potro cálido y temido", "Kit del deseo", "Ángel polvoriento", "Sweety Frozen", "Wombat pesado plateado", "Puma perdido", "Panda vital", "Sol rodante" , "Steel Runny", "Young Fox", "Needless Ruthless Volunteer", "Chipmunk Cult", "Indigo Puppy"];
    Sería posible ir más allá y generar nombres a partir de 2 o 3 componentes, pero el algoritmo para tal mejora no contiene nada nuevo (la misma aleatoriedad), y entonces simplemente complicaría el proceso de aprendizaje.

    Matriz para clase:

    Var playerRoles = ["bárbaro", "mago", "pícaro", "caballero", "sacerdote"];
    Todo es igual de obvio. Varias cadenas, de las cuales luego seleccionaremos valores para mostrar en la página.

    Matriz por nivel:

    EN ejemplo específico, Quería que todos los miembros del grupo estuvieran entre el nivel 60 y 70. Pero, como las condiciones pueden cambiar, fue necesario crear una matriz desde los niveles 0 al 80, desde la cual luego seleccionar valores requeridos. Creado en un bucle:

    Var niveles de jugador = ; para (yo = 0;yo

    
    Desplazarse hacia arriba