Objeto `Math`
Este artigo explica sobre o objeto Math.
Explica passo a passo, desde o uso básico até padrões práticos comuns, além de armadilhas e contramedidas.
YouTube Video
Objeto Math
O objeto Math do JavaScript oferece um conjunto de utilitários embutidos para cálculos numéricos.
Constantes
As constantes definidas em Math são úteis ao lidar com valores de alta precisão.
O código a seguir mostra algumas constantes típicas.
1// Show common Math constants
2console.log("Math.PI:", Math.PI); // 3.141592653589793
3console.log("Math.E:", Math.E); // Euler's number
4console.log("Math.LN2:", Math.LN2); // Natural log of 2
5console.log("Math.SQRT2:", Math.SQRT2); // Square root of 2
- Essas constantes podem ser usadas como estão para funções trigonométricas, conversões logarítmicas, normalização e mais. Por exemplo,
Math.PIé necessário para converter ângulos em radianos.
Arredondamento básico e valores absolutos (abs, floor, ceil, round, trunc)
O arredondamento e o tratamento de sinais são usados frequentemente, portanto é importante entender corretamente as diferenças entre Math.floor, Math.ceil e Math.round. Especialmente ao lidar com números negativos, os resultados podem diferir da intuição, então é necessário ter cuidado com o funcionamento de cada regra de arredondamento e usá-las adequadamente.
Os exemplos a seguir ilustram as diferenças entre as funções de arredondamento.
1// Examples of rounding and absolute value functions
2const pos = 3.7;
3const neg = -3.7;
4
5// --- floor ---
6console.log("Math.floor(3.7):", Math.floor(pos)); // 3
7console.log("Math.floor(-3.7):", Math.floor(neg)); // -4
8// (rounds toward smaller value)
9
10// --- ceil ---
11console.log("Math.ceil(3.7):", Math.ceil(pos)); // 4
12console.log("Math.ceil(-3.7):", Math.ceil(neg)); // -3
13// (rounds toward larger value)
14
15// --- round ---
16console.log("Math.round(3.5):", Math.round(3.5)); // 4
17// (.5 goes up for positive numbers)
18console.log("Math.round(-3.5):", Math.round(-3.5)); // -3
19// (.5 moves toward zero for negative numbers)
20
21// --- trunc ---
22console.log("Math.trunc(3.7):", Math.trunc(pos)); // 3
23console.log("Math.trunc(-3.7):", Math.trunc(neg)); // -3
24// (fraction removed toward zero)
25
26// --- abs ---
27console.log("Math.abs(-3.7):", Math.abs(neg)); // 3.7
Math.floorarredonda para o menor valor em números negativos, então-3.7se torna-4.Math.ceilarredonda para o maior valor em números negativos, então-3.7se torna-3.Math.roundarredonda .5 para cima em números positivos e, para negativos, arredonda em direção a zero.- Números negativos podem produzir resultados que diferem da intuição, por isso é importante entender claramente para que direção os números estão sendo arredondados.
- As funções de arredondamento devem ser selecionadas de acordo com o caso de uso. Por exemplo, use
Math.floorpara cálculos de índice,Math.ceilpara limites superiores eMath.truncquando você quiser apenas descartar a parte decimal.
Multiplicação, exponenciação e raízes (pow, **, sqrt, cbrt, hypot)
Exponentiação e raízes quadradas podem ser feitas com Math.pow ou com o operador **. Math.hypot calcula com segurança a raiz quadrada da soma dos quadrados (distância).
Abaixo estão exemplos de exponenciação e de hypot. Math.hypot reduz o impacto de overflow e underflow.
1// Power, root and hypot examples
2console.log("2 ** 10:", 2 ** 10); // 1024
3console.log("Math.pow(2, 10):", Math.pow(2, 10));// 1024
4console.log("Math.sqrt(16):", Math.sqrt(16)); // 4
5console.log("Math.cbrt(27):", Math.cbrt(27)); // 3
6console.log("Math.hypot(3, 4):", Math.hypot(3, 4));// 5 (3-4-5 triangle)
Math.hypoté útil ao lidar com lados de triângulos ou comprimentos de vetores multidimensionais.
Funções exponenciais e logarítmicas (exp, log, log10, log2)
Exponenciais e logaritmos são frequentemente usados em probabilidade, decaimento exponencial e escalonamento.
A seguir estão exemplos básicos de exp e logaritmos. Certifique-se de usar a função apropriada, dependendo da base do logaritmo.
1// Exponential and logarithm examples
2console.log("Math.exp(1):", Math.exp(1)); // e^1
3console.log("Math.log(Math.E):", Math.log(Math.E)); // natural log, 1
4console.log("Math.log10(100):", Math.log10(100)); // 2
5console.log("Math.log2(8):", Math.log2(8)); // 3
- Os logaritmos naturais (
Math.log) são padrão em estatística e equações diferenciais. Logaritmos decimais e de base 2 também são escolhidos conforme a aplicação.
Funções trigonométricas (sin, cos, tan, asin, acos, atan2)
Funções trigonométricas são essenciais para cálculos de ângulo, rotações e transformações de coordenadas. Math.atan2(y, x) é útil para calcular ângulos considerando corretamente os quadrantes.
Abaixo estão exemplos básicos e o uso de atan2. Os ângulos devem ser trabalhados em radianos.
1// Trigonometry examples (angles in radians)
2const degToRad = deg => deg * (Math.PI / 180);
3const radToDeg = rad => rad * (180 / Math.PI);
4
5console.log("Math.sin(PI/2):", Math.sin(Math.PI / 2)); // 1
6console.log("Math.cos(0):", Math.cos(0)); // 1
7console.log("Math.tan(Math.PI / 4):", Math.tan(Math.PI / 4)); // ~1
8
9// Using atan2 to compute angle of vector (x, y)
10const x = -1, y = 1;
11const angle = Math.atan2(y, x); // returns angle in radians taking quadrant into account
12console.log("atan2(1, -1) in degrees:", radToDeg(angle)); // 135
atan2pode determinar com segurança o ângulo de um vetor, tornando-o preferível para cálculos de rotação e direção.
Geração de números aleatórios (Math.random e padrões práticos)
Math.random() retorna um número aleatório uniformemente distribuído no intervalo [0, 1). Você pode converter ou adaptar conforme necessário para intervalos inteiros ou distribuições normais, por exemplo.
A seguir estão exemplos de funções utilitárias para números aleatórios. Se precisar de números aleatórios criptograficamente seguros, use crypto.getRandomValues.
1// Random utilities using Math.random
2
3// Get integer in [min, max] inclusive
4function randomInt(min, max) {
5 // Returns integer between min and max (inclusive)
6 return Math.floor(Math.random() * (max - min + 1)) + min;
7}
8console.log("randomInt(1, 6):", randomInt(1, 6)); // dice roll example
9
10// Get float in [min, max)
11function randomFloat(min, max) {
12 return Math.random() * (max - min) + min;
13}
14console.log("randomFloat(0, 5):", randomFloat(0, 5));
15
16// Fisher-Yates shuffle
17function shuffle(array) {
18 for (let i = array.length - 1; i > 0; i--) {
19 const j = Math.floor(Math.random() * (i + 1));
20 // swap array[i] and array[j]
21 [array[i], array[j]] = [array[j], array[i]];
22 }
23 return array;
24}
25console.log("shuffle([1,2,3,4,5]):", shuffle([1,2,3,4,5]));Math.randomé conveniente para uso geral, mas para replays de jogos ou criptografia, são necessárias contramedidas para reprodutibilidade ou segurança.
Auxiliares práticos (clamp, lerp, mapRange, normalização de ângulo)
É útil escrever pequenas funções utilitárias para tarefas matemáticas frequentemente utilizadas.
Aqui estão exemplos de implementação de utilitários comumente usados.
1// Utility functions: clamp, lerp, mapRange, normalizeAngle
2
3// Clamp value between min and max
4function clamp(v, min, max) {
5 return Math.max(min, Math.min(max, v));
6}
7console.log("clamp(10, 0, 5):", clamp(10, 0, 5)); // 5
8
9// Linear interpolation: t in [0,1]
10function lerp(a, b, t) {
11 return a + (b - a) * t;
12}
13console.log("lerp(0, 10, 0.25):", lerp(0, 10, 0.25)); // 2.5
14
15// Map value from one range to another
16function mapRange(v, inMin, inMax, outMin, outMax) {
17 const t = (v - inMin) / (inMax - inMin);
18 return lerp(outMin, outMax, t);
19}
20console.log("mapRange(5, 0, 10, 0, 100):", mapRange(5, 0, 10, 0, 100));
21// -> 50
22
23// Normalize angle to [-PI, PI)
24function normalizeAngle(rad) {
25 return Math.atan2(Math.sin(rad), Math.cos(rad));
26}
27console.log("normalizeAngle(3*PI):", normalizeAngle(3 * Math.PI));- Este código reúne pequenas funções utilitárias comumente usadas em operações numéricas, como limitar valores, interpolação, mapeamento de intervalo e normalização de ângulo.
clamplimita um valor a um intervalo especificado, enquantolerpemapRangerealizam interpolação suave ou conversão para outro intervalo. Além disso,normalizeAnglesempre normaliza ângulos para o intervalo[-π, π)para estabilizar cálculos de rotação. - Esses auxiliares são usados frequentemente em gráficos, jogos e programação de interação.
normalizeAngleé importante para comparar diferenças angulares e para interpolação.
Advertências sobre ponto flutuante e arredondamento (precisão e comparação)
Os números em JavaScript são ponto flutuante de precisão dupla IEEE-754 (64 bits), portanto, é necessário ter cautela ao comparar ou arredondar números. Por exemplo, 0.1 + 0.2 !== 0.3.
Aqui está um exemplo de como lidar com erros de arredondamento. É importante usar comparações que tolerem pequenos erros ou funções de arredondamento apropriadas.
1// Floating point precision example and safe equality
2console.log("0.1 + 0.2 === 0.3 :", 0.1 + 0.2 === 0.3); // false
3
4function nearlyEqual(a, b, eps = 1e-12) {
5 return Math.abs(a - b) <= eps;
6}
7console.log("nearlyEqual(0.1+0.2, 0.3):", nearlyEqual(0.1 + 0.2, 0.3));
8// -> true
- Para verificações robustas de igualdade numérica, use erro absoluto (
eps) ou erro relativo.
Dicas de desempenho
As funções de Math são otimizadas nativamente e geralmente são mais rápidas do que uma lógica equivalente escrita manualmente. Se o mesmo cálculo (por exemplo, Math.PI / 180) for repetido em um loop, atribuí-lo a uma variável previamente reduz sobrecarga desnecessária.
Abaixo está um exemplo de como converter graus para radianos criando uma constante fora do loop.
1// Cache conversion factor for performance
2const DEG_TO_RAD = Math.PI / 180;
3const RAD_TO_DEG = 180 / Math.PI;
4
5for (let deg = 0; deg < 360; deg += 10) {
6 // Use cached constant instead of computing each time
7 const rad = deg * DEG_TO_RAD;
8 // ... do work with rad
9}- É melhor verificar os pontos críticos reais com um profiler antes de realizar otimizações.
- É eficiente armazenar em cache constantes que são usadas frequentemente.
Compatibilidade e polyfills
Math existe há muito tempo, mas algumas funções como Math.cbrt, Math.log10, Math.log2 e Math.hypot podem não ser suportadas em ambientes antigos. Prepare um polyfill simples se necessário.
Abaixo está um exemplo de polyfill simples para Math.log2.
1// Polyfill for Math.log2 if needed
2if (!Math.log2) {
3 Math.log2 = function(x) {
4 return Math.log(x) / Math.LN2;
5 };
6}
7console.log("Math.log2(8):", Math.log2(8));Muitos ambientes já dão suporte, mas verifique a compatibilidade se necessário.
Verifique o suporte do navegador conforme o ambiente-alvo do seu projeto.
Exemplo prático: atualizações em passos de tempo em uma simulação física simples
Finalmente, aqui está um exemplo prático combinando várias funções do Math. Este é um exemplo muito simples para atualizar posição, velocidade e controle de ângulo.
É um modelo altamente simplificado de um motor físico.
1// Clamp value between min and max
2function clamp(v, min, max) {
3 return Math.max(min, Math.min(max, v));
4}
5
6// Normalize angle to [-PI, PI)
7function normalizeAngle(rad) {
8 return Math.atan2(Math.sin(rad), Math.cos(rad));
9}
10
11// Simple physics step example using Math utilities
12function step(state, dt) {
13 // state: { x, y, vx, vy, angle, angularVelocity }
14 // dt: time delta in seconds
15 // Integrate linear motion
16 state.x += state.vx * dt;
17 state.y += state.vy * dt;
18
19 // Integrate angular motion and normalize angle
20 state.angle = normalizeAngle(state.angle + state.angularVelocity * dt);
21
22 // Keep position within bounds [0, width] x [0, height]
23 state.x = clamp(state.x, 0, state.width);
24 state.y = clamp(state.y, 0, state.height);
25 return state;
26}
27
28const state = { x: 10, y: 10, vx: 2, vy: 0.5, angle: 0, angularVelocity: 0.1, width: 100, height: 100 };
29console.log("before:", state);
30step(state, 0.016); // simulate ~1 frame at 60fps
31console.log("after:", state);- Ao combinar auxiliares de
Mathdessa forma, a lógica de simulação e animação pode se tornar mais concisa.
Resumo
Mathcobre desde constantes e funções básicas até avançadas, servindo como base para o processamento numérico.- Selecione funções conforme o objetivo, como números aleatórios, funções trigonométricas, exponenciais/logaritmos ou arredondamento; e crie pequenos utilitários como
clampelerppara uso prático. - Preste atenção na precisão em ponto flutuante e no suporte do ambiente alvo, e prepare tolerância a erros ou polyfills se necessário.
Você pode acompanhar o artigo acima usando o Visual Studio Code em nosso canal do YouTube. Por favor, confira também o canal do YouTube.