Pergunta

Em JavaScript, como faço para obter:

  1. Todo o número de vezes que um determinado número inteiro entra em outro?
  2. o restante?
Foi útil?

Solução

Para algum número y e algum divisor x Calcule o quociente (quotient) e restante (remainder) Como:

var quotient = Math.floor(y/x);
var remainder = y % x;

Outras dicas

Não sou especialista em operadores bit newise, mas aqui está outra maneira de obter o número inteiro:

var num = ~~(a / b);

Isso também funcionará corretamente para números negativos, enquanto Math.floor() irá arredondar na direção errada.

Isso parece correto também:

var num = (a / b) >> 0;

Fiz alguns testes de velocidade no 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

O acima é baseado em 10 milhões de ensaios para cada um.

Conclusão: Usar (a/b>>0) (ou (~~(a/b)) ou (a/b|0)) alcançar cerca de 20% de ganho de eficiência. Também lembre -se de que todos são inconsistentes com Math.floor, quando a/b<0 && a%b!=0.

ES6 apresenta o novo Math.trunc método. Isso permite consertar @Resposta de Markelliot Para fazê -lo funcionar para números negativos também:

var div = Math.trunc(y/x);
var rem = y % x;

Observe que Math Os métodos têm a vantagem sobre os operadores bit -bit que eles trabalham com números acima de 231.

var remainder = x % y;
return (x - remainder) / y;

Você pode usar a função parseInt Para obter um resultado truncado.

parseInt(a/b)

Para obter um restante, use o operador de mod:

a%b

Parseint tem algumas armadilhas com cordas, para evitar o uso de parâmetro Radix com a base 10

parseInt("09", 10)

Em alguns casos, a representação da string do número pode ser uma notação científica; nesse caso, o Parseint produzirá um resultado errado.

parseInt(100000000000000000000000000000000, 10) // 1e+32

Esta chamada produzirá 1 como resultado.

Eu normalmente uso:

const quotient =  (a - a % b) / b;
const remainder = a % b;

Provavelmente não é o mais elegante, mas funciona.

O JavaScript calcula a direita o piso de números negativos e o restante de números não inteiros, seguindo as definições matemáticas para eles.

O piso é definido como "o maior número inteiro menor que o parâmetro", assim:

  • números positivos: piso (x) = parte inteira de x;
  • Números negativos: piso (x) = parte inteira de x menos 1 (porque deve ser menor que o parâmetro, ou seja, mais negativo!)

O restante é definido como o "restante" de uma divisão (aritmética euclidiana). Quando o dividendo não é um número inteiro, o quociente geralmente também não é um número inteiro, ou seja, não há restante, mas se o quociente for forçado a ser um número inteiro (e é isso que acontece quando alguém tenta obter o restante ou módulo de um Número de ponto flutuante), haverá um "não inteiro", obviamente.

JavaScript does calculate everything as expected, so the programmer must be careful to ask the proper questions (and people should be careful to answer what is asked!) Yarin's first question was NOT "what is the integer division of X by Y", but, Em vez disso, "o número inteiro de vezes que um determinado número inteiro entra em outro". Para números positivos, a resposta é a mesma para ambos, mas não para números negativos, porque a divisão inteira (dividendo pelo divisor) será -1 menor do que os tempos que um número (divisor) "entra em" outro (dividendo). Em outras palavras, o piso retornará a resposta correta para uma divisão inteira de um número negativo, mas Yarin não perguntou isso!

Gammax respondeu corretamente, esse código funciona conforme solicitado por Yarin. Por outro 3):

Restante = x % y = -100 % 3 = -1

GoSinto = (x -restante) / y = (-100 --1) / 3 = -99 / 3 = -33

A propósito, testei o código no Firefox 27.0.1, ele funcionou como esperado, com números positivos e negativos e também com valores não inteiros, tanto para dividendos quanto de divisor. Exemplo:

-100.34 / 3.57: GoSinto = -28, restante = -0.3800000000000079

Sim, notei, há um problema de precisão lá, mas não tive tempo de verificar (não sei se é um problema com o Firefox, Windows 7 ou com a FPU da minha CPU). Para a pergunta de Yarin, porém, que envolve apenas números inteiros, o código do Gammax funciona perfeitamente.

Math.floor(operation) Retorna o valor arredondado da operação.

Exemplo de 1st pergunta:

var x = 5;
var y = 10.4;
var z = Math.floor(x + y);

console.log(z);

Console:

15

Exemplo de 2nd pergunta:

var x = 14;
var y = 5;
var z = Math.floor(x%y);

console.log(x);

Console:

4

Alex Moore-NiemiComentário está como resposta:

Para rubyistas aqui do Google em busca de divmod, você pode implementá -lo como tal:

function divmod(x, y) {
  var div = Math.trunc(x/y);
  var rem = x % y;
  return [div, rem];
}

Resultado:

// [2, 33]

Se você está apenas se dividindo com poderes de dois, pode usar operadores bit -new:

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];
}

(O primeiro é o quociente, o segundo o restante)

O número de páginas calculistas pode ser feito em uma etapa: math.ceil (x/y)

Você pode usar o ternário para decidir como lidar com valores inteiros positivos e negativos também.

var myInt = (y > 0) ? Math.floor(y/x) : Math.floor(y/x) + 1

Se o número for positivo, está tudo bem. Se o número for negativo, ele adicionará 1 por causa de como o piso lida com os negativos.

Isso sempre trará para zero. Não tenho certeza se é tarde demais, mas aqui vai:

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
    };
}

Se você precisar calcular o restante para números inteiros muito grandes, que o tempo de execução do JS não pode representar como tal (qualquer número inteiro maior que 2^32 é representado como bóia e, portanto, perde precisão), você precisa fazer algum truque.

Isso é especialmente importante para verificar muitos casos de dígitos que estão presentes em muitos casos de nossa vida diária (números de contas bancárias, cartões de crédito, ...)

Antes de tudo, você precisa do seu número como uma string (caso contrário, você já perdeu a precisão e o restante não faz sentido).

str = '123456789123456789123456789'

Agora você precisa dividir a corda em peças menores, pequenas o suficiente para que a concatenação de qualquer restante e um pedaço de corda possa caber em 9 dígitos.

digits = 9 - String(divisor).length

Prepare uma expressão regular para dividir a corda

splitter = new RegExp(`.{1,${digits}}(?=(.{${digits}})+$)`, 'g')

Por exemplo, se digits é 7, o regexp é

/.{1,7}(?=(.{7})+$)/g

Ele corresponde a uma substring não vazia do comprimento máximo 7, que é seguido ((?=...) é um lookahead positivo) por vários caracteres que são múltiplos de 7. O 'G' é fazer com que a expressão seja executada em toda a string, não parando na primeira partida.

Agora converta cada parte em número inteiro e calcule os restos por reduce (Adicionando novamente o restante anterior - ou 0 - multiplicado pela potência correta de 10):

reducer = (rem, piece) => (rem * Math.pow(10, digits) + piece) % divisor

Isso funcionará por causa do algoritmo restante da "subtração":

n mod d = (n - kd) mod d

que permite substituir qualquer 'parte inicial' da representação decimal de um número com seu restante, sem afetar o restante final.

O código final seria:

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);
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top