`Math`-objektet

Den här artikeln förklarar Math-objektet.

Den förklarar steg för steg, från grundläggande användning till vanliga praktiska mönster, samt fallgropar och motåtgärder.

YouTube Video

Math-objektet

Math-objektet i JavaScript tillhandahåller en uppsättning inbyggda verktyg för numeriska beräkningar.

Konstanter

Konstanterna som definieras i Math är användbara när man hanterar högprecisionsvärden.

Följande kod visar några typiska konstanter.

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
  • Dessa konstanter kan användas direkt för trigonometriska funktioner, logaritmiska omvandlingar, normalisering med mera. Till exempel behövs Math.PI för att omvandla vinklar till radianer.

Grundläggande avrundning och absolutbelopp (abs, floor, ceil, round, trunc)

Avrundning och hantering av tecken används ofta, så det är viktigt att förstå skillnaderna mellan Math.floor, Math.ceil och Math.round. Speciellt när man hanterar negativa tal kan resultaten skilja sig från intuitionen, så det är nödvändigt att vara uppmärksam på hur varje avrundningsregel fungerar och använda dem korrekt.

Följande exempel visar skillnaderna mellan avrundningsfunktionerna.

 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.floor rundar nedåt mot det mindre hållet för negativa tal, så -3.7 blir -4.
  • Math.ceil rundar uppåt mot det större hållet för negativa tal, så -3.7 blir -3.
  • Math.round avrundar 0,5 uppåt för positiva tal, och för negativa tal avrundar den mot noll.
  • Negativa tal kan ge resultat som skiljer sig från intuitionen, så det är viktigt att förstå åt vilket håll talen avrundas.
  • Avrundningsfunktioner bör väljas utifrån användningsfall. Till exempel: använd Math.floor för indexberäkningar, Math.ceil för övre gränser och Math.trunc när du bara vill ta bort decimaldelen.

Multiplikation, potens och rötter (pow, **, sqrt, cbrt, hypot)

Upphöjning och kvadratrötter kan göras med Math.pow eller med **-operatorn. Math.hypot beräknar säkert kvadratroten av summan av kvadrater (avstånd).

Nedanför finns exempel på upphöjning och hypot. Math.hypot motverkar effekten av overflow och 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 är användbar vid beräkning av triangelns sidor eller längder av flerdimensionella vektorer.

Exponentiella och logaritmiska funktioner (exp, log, log10, log2)

Exponentiella och logaritmiska funktioner används ofta inom sannolikhet, exponentiell avklingning och skalning.

Härnäst följer grundläggande exempel på exp och logaritmer. Använd rätt funktion beroende på basen för logaritmen.

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
  • Naturliga logaritmer (Math.log) är standard inom statistik och differentialekvationer. Vanliga logaritmer och logaritmer med bas 2 väljs också beroende på tillämpning.

Trigonometriska funktioner (sin, cos, tan, asin, acos, atan2)

Trigonometriska funktioner är nödvändiga för vinkelberäkningar, rotationer och koordinatomvandlingar. Math.atan2(y, x) är användbar för att beräkna vinklar med hänsyn till korrekt kvadrant.

Nedanför finns grundläggande exempel och användning av atan2. Vinklar måste hanteras i radianer.

 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
  • atan2 kan säkert bestämma vinkeln på en vektor, vilket gör den lämplig för rotationer och riktningsberäkningar.

Slumptalsgenerering (Math.random och praktiska mönster)

Math.random() returnerar ett jämnt fördelat slumptal i intervallet [0, 1). Du kan konvertera eller utöka det vid behov för heltalsintervall eller normalfördelningar, till exempel.

Följande är exempel på hjälpfunktioner för slumptal. Om du behöver kryptografiskt säkra slumptal, använd 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 är praktisk för allmänt bruk, men för speluppspelningar eller kryptografi krävs åtgärder för reproducerbarhet eller säkerhet.

Praktiska hjälpfunktioner (clamp, lerp, mapRange, vinkelnormalisering)

Det är användbart att skriva små hjälpfunktioner själv för ofta förekommande matematiska uppgifter.

Här är implementeringsexempel på vanliga hjälpfunktioner.

 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));
  • Den här koden samlar små hjälpfunktioner som ofta används för numeriska operationer såsom värdeklämning, interpolation, intervallmappning och vinkelnormalisering. clamp begränsar ett värde till ett angivet intervall medan lerp och mapRange utför smidig interpolation eller omvandling till ett annat intervall. Dessutom normaliserar normalizeAngle alltid vinklar till intervallet [-π, π) för att stabilisera rotationsberäkningar.
  • Dessa hjälpfunktioner används ofta inom grafik, spel och interaktionsprogrammering. normalizeAngle är viktigt för att jämföra vinkelavvikelser och för interpolation.

Flyttal och avrundningsvarningar (precision och jämförelse)

JavaScript-nummer är IEEE-754 dubbelprecision flyttal (64-bit), så försiktighet krävs vid jämförelse eller avrundning. Till exempel, 0.1 + 0.2 !== 0.3.

Här är ett exempel på hur avrundningsfel kan hanteras. Det är viktigt att använda jämförelser som tolererar små fel, eller lämpliga avrundningsfunktioner.

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
  • För robusta numeriska likhetskontroller, använd absolut fel (eps) eller relativt fel.

Prestandatips

Math-funktionerna är inbyggt optimerade och är ofta snabbare än egen implementation. Om samma beräkning (t.ex. Math.PI / 180) upprepas i en loop, minska onödigt overhead genom att tilldela det till en variabel i förväg.

Här är ett exempel på att omvandla grader till radianer genom att skapa en konstant utanför loopen.

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}
  • Det är bäst att verifiera verkliga flaskhalsar med en profilerare innan du utför optimeringar.
  • Det är effektivt att cacha konstanter som används ofta.

Kompatibilitet och polyfills

Math har funnits länge, men vissa funktioner som Math.cbrt, Math.log10, Math.log2 och Math.hypot kan saknas i äldre miljöer. Förbered en enkel polyfill vid behov.

Nedanför visas ett exempel på en enkel polyfill för 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));

Många miljöer stödjer dem redan, men kontrollera kompatibiliteten vid behov.

Kontrollera webbläsarstöd enligt din projekts målmiljö.

Praktiskt exempel: Tidsdiskret uppdatering i en enkel fysiksimulering

Slutligen, här är ett praktiskt exempel som kombinerar flera Math-funktioner. Detta är ett mycket enkelt exempel på att uppdatera position, hastighet och vinkelkontroll.

Det är en mycket förenklad modell av en fysikmotor.

 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);
  • Genom att kombinera Math-hjälpfunktioner på detta sätt kan simulerings- och animationslogik göras mer koncis.

Sammanfattning

  • Math täcker allt från konstanter och grundläggande funktioner till avancerade, och fungerar som grund för numerisk bearbetning.
  • Välj funktioner efter syfte, som slumptal, trigonometriska funktioner, exponenter/logaritmer eller avrundning; och skapa små hjälpfunktioner som clamp och lerp för praktisk användning.
  • Var uppmärksam på flyttalsprecision och stödet i din målmiljö, och förbered felhantering eller polyfills vid behov.

Du kan följa med i artikeln ovan med hjälp av Visual Studio Code på vår YouTube-kanal. Vänligen kolla även in YouTube-kanalen.

YouTube Video