entero - math.floor javascript
¿División entera con resto en JavaScript? (15)
ES6 introduce el nuevo método Math.trunc
. Esto permite corregir la respuesta de @ MarkElliot para que funcione con números negativos también:
var div = Math.trunc(y/x);
var rem = y % x;
Tenga en cuenta que los métodos Math
tienen la ventaja sobre los operadores bitwise que trabajan con números mayores de 2 31 .
En JavaScript, ¿cómo obtengo:
- ¿El número entero de veces que un entero dado entra en otro?
- ¿el resto?
El cálculo del número de páginas se puede hacer en un solo paso: Math.ceil (x / y)
El comentario de Alex Moore-Niemi como respuesta:
Para los Rubyists aquí de Google en busca de divmod
, puedes implementarlo como tal:
function divmod(x, y) {
var div = Math.trunc(x/y);
var rem = x % y;
return [div, rem];
}
Resultado:
// [2, 33]
Esto siempre se truncará hacia cero. No estoy seguro si es demasiado tarde, pero aquí va:
function intdiv(dividend, divisor) {
divisor = divisor - divisor % 1;
if (divisor == 0) throw new Error("division by zero");
dividend = dividend - dividend % 1;
var rem = dividend % divisor;
return {
remainder: rem,
quotient: (dividend - rem) / divisor
};
}
Hice algunas pruebas de velocidad en Firefox.
-100/3 // -33.33..., 0.3663 millisec
Math.floor(-100/3) // -34, 0.5016 millisec
~~(-100/3) // -33, 0.3619 millisec
(-100/3>>0) // -33, 0.3632 millisec
(-100/3|0) // -33, 0.3856 millisec
(-100-(-100%3))/3 // -33, 0.3591 millisec
/* a=-100, b=3 */
a/b // -33.33..., 0.4863 millisec
Math.floor(a/b) // -34, 0.6019 millisec
~~(a/b) // -33, 0.5148 millisec
(a/b>>0) // -33, 0.5048 millisec
(a/b|0) // -33, 0.5078 millisec
(a-(a%b))/b // -33, 0.6649 millisec
Lo anterior se basa en 10 millones de pruebas para cada uno.
Conclusión: Utilice (a/b>>0)
(o (~~(a/b))
o (a/b|0)
) para lograr aproximadamente un 20% de ganancia en eficiencia. También tenga en cuenta que todas son inconsistentes con Math.floor
, cuando a/b<0 && a%b!=0
.
JavaScript calcula correctamente el piso de los números negativos y el resto de los números no enteros, siguiendo las definiciones matemáticas para ellos.
FLOOR se define como "el mayor número entero más pequeño que el parámetro", por lo tanto:
- números positivos: PISO (X) = parte entera de X;
- Números negativos: PISO (X) = parte entera de X menos 1 (porque debe ser MÁS PEQUEÑO que el parámetro, es decir, ¡más negativo!)
REMAINDER se define como la "sobra" de una división (aritmética euclidiana). Cuando el dividendo no es un número entero, el cociente generalmente tampoco es un número entero, es decir, no hay un resto, pero si el cociente es forzado a ser un número entero (y eso es lo que sucede cuando alguien intenta obtener el resto o el módulo de un número de punto flotante), habrá un "sobrante" no entero, obviamente.
JavaScript calcula todo como se espera, por lo que el programador debe tener cuidado de hacer las preguntas correctas (¡y la gente debe tener cuidado de responder lo que se pregunta!) La primera pregunta de Yarin NO fue "¿cuál es la división entera de X por Y", pero en cambio, "el número ENTERO de veces que un entero dado VA A UN OTRO". Para números positivos, la respuesta es la misma para ambos, pero no para números negativos, porque la división entera (dividendo por divisor) será -1 más pequeña que las veces que un número (divisor) "entra en" otro (dividendo). En otras palabras, FLOOR devolverá la respuesta correcta para una división entera de un número negativo, ¡pero Yarin no preguntó eso!
Gammax respondió correctamente, ese código funciona según lo solicitado por Yarin. Por otra parte, Samuel está equivocado, no hizo los cálculos, supongo, o habría visto que funciona (también, no dijo cuál fue el divisor de su ejemplo, pero espero que haya sido así). 3):
El resto = X% Y = -100% 3 = -1
GoesInto = (X - Resto) / Y = (-100 - -1) / 3 = -99 / 3 = -33
Por cierto, probé el código en Firefox 27.0.1, funcionó como se esperaba, con números positivos y negativos y también con valores no enteros, tanto para dividendos como para divisores. Ejemplo:
-100.34 / 3.57: GoesInto = -28, resto = -0.3800000000000000
Sí, me di cuenta de que hay un problema de precisión, pero no tuve tiempo de comprobarlo (no sé si es un problema con Firefox, Windows 7 o con la FPU de mi CPU). Sin embargo, para la pregunta de Yarin, que solo involucra a los enteros, el código del gammax funciona perfectamente.
No soy un experto en operadores bitwise, pero aquí hay otra manera de obtener el número completo:
var num = ~~(a / b);
Esto también funcionará correctamente para los números negativos, mientras que Math.floor()
redondeará en la dirección incorrecta.
Esto parece correcto también:
var num = (a / b) >> 0;
Normalmente uso (a - a % b) / b
. Probablemente no sea el más elegante, pero funciona.
Puede usar ternario para decidir cómo manejar valores enteros positivos y negativos también.
var myInt = (y > 0) ? Math.floor(y/x) : Math.floor(y/x) + 1
Si el número es positivo, todo está bien. Si el número es negativo, agregará 1 debido a cómo Math.floor maneja los negativos.
Puede utilizar la función parseInt
para obtener un resultado truncado.
parseInt(a/b)
Para obtener un resto, use mod operador:
a%b
parseInt tiene algunas trampas con cadenas, para evitar usar el parámetro radix con base 10
parseInt("09", 10)
En algunos casos, la representación en cadena del número puede ser una notación científica; en este caso, parseInt producirá un resultado incorrecto.
parseInt(100000000000000000000000000000000, 10) // 1e+32
Esta llamada producirá 1 como resultado.
Si necesita calcular el resto para enteros muy grandes, que el tiempo de ejecución de JS no puede representar como tal (cualquier entero mayor que 2 ^ 32 se representa como un flotador y por lo tanto pierde precisión), debe hacer algún truco.
Esto es especialmente importante para verificar muchos casos de dígitos de cheque que están presentes en muchos casos de nuestra vida diaria (números de cuentas bancarias, tarjetas de crédito, ...)
En primer lugar, necesita su número como una cadena (de lo contrario, ya ha perdido precisión y el resto no tiene sentido).
str = ''123456789123456789123456789''
Ahora necesita dividir su cadena en partes más pequeñas, lo suficientemente pequeñas para que la concatenación de cualquier resto y un trozo de cuerda pueda caber en 9 dígitos.
digits = 9 - String(divisor).length
Prepare una expresión regular para dividir la cadena
splitter = new RegExp(`.{1,${digits}}(?=(.{${digits}})+$)`, ''g'')
Por ejemplo, si los digits
son 7, la expresión regular es
/.{1,7}(?=(.{7})+$)/g
Coincide con una subcadena no vacía de longitud máxima 7, que se sigue ( (?=...)
es un lookahead positivo) por un número de caracteres que es múltiplo de 7. La ''g'' hace que la expresión pase por toda la cadena , no se detiene en el primer partido.
Ahora convierta cada parte a entero, y calcule los restos reduce
(agregando el resto anterior, o 0, multiplicado por la potencia correcta de 10):
reducer = (rem, piece) => (rem * Math.pow(10, digits) + piece) % divisor
Esto funcionará debido al algoritmo de resto "resta":
n mod d = (n - kd) mod d
que permite reemplazar cualquier ''parte inicial'' de la representación decimal de un número con su resto, sin afectar el resto final.
El código final se vería así:
function remainder(num, div) {
const digits = 9 - String(div).length;
const splitter = new RegExp(`.{1,${digits}}(?=(.{${digits}})+$)`, ''g'');
const mult = Math.pow(10, digits);
const reducer = (rem, piece) => (rem * mult + piece) % div;
return str.match(splitter).map(Number).reduce(reducer, 0);
}
Si solo está dividiendo con potencias de dos, puede usar operadores bitwise:
export function divideBy2(num) {
return [num >> 1, num & 1];
}
export function divideBy4(num) {
return [num >> 2, num & 3];
}
export function divideBy8(num) {
return [num >> 3, num & 7];
}
(El primero es el cociente, el segundo el resto)
Math.floor(operation)
devuelve el valor redondeado hacia abajo de la operación.
Ejemplo de 1ª pregunta:
var x = 5;
var y = 10.4;
var z = Math.floor(x + y);
console.log(z);
Consola:
15
Ejemplo de 2ª pregunta:
var x = 14;
var y = 5;
var z = Math.floor(x%y);
console.log(x);
Consola:
4
Para algún número y
y algún divisor x
calcula el cociente ( quotient
) y el resto ( remainder
) como:
var quotient = Math.floor(y/x);
var remainder = y % x;
var remainder = x % y;
return (x - remainder) / y;