`Math`-objektet

Denne artikkelen forklarer om Math-objektet.

Den forklarer trinn for trinn, fra grunnleggende bruk til vanlige praktiske mønstre, samt fallgruver og mottiltak.

YouTube Video

Math-objektet

Math-objektet i JavaScript tilbyr et sett med innebygde funksjoner for numeriske beregninger.

Konstanter

Konstanter definert i Math er nyttige når man arbeider med verdier som krever høy presisjon.

Følgende kode viser noen typiske 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
  • Disse konstantene kan brukes som de er for trigonometriske funksjoner, logaritmiske konverteringer, normalisering og mer. For eksempel er Math.PI nødvendig for å konvertere vinkler til radianer.

Grunnleggende avrunding og absolutte verdier (abs, floor, ceil, round, trunc)

Avrunding og håndtering av fortegn brukes ofte, så det er viktig å forstå forskjellene mellom Math.floor, Math.ceil og Math.round. Spesielt når man håndterer negative tall kan resultatene avvike fra intuisjonen, så det er nødvendig å være oppmerksom på hvordan hver avrundingsregel fungerer og bruke dem riktig.

Følgende eksempler illustrerer forskjellene mellom avrundingsfunksjonene.

 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 runder mot det mindre for negative tall, så -3.7 blir til -4.
  • Math.ceil runder mot det større for negative tall, så -3.7 blir til -3.
  • Math.round runder .5 opp for positive tall, og for negative tall runder den mot null.
  • Negative tall kan gi resultater som ikke er intuitive, så det er viktig å forstå hvilken retning tallene avrundes.
  • Avrundingsfunksjoner bør velges basert på bruksområde. Bruk for eksempel Math.floor for indeksberegninger, Math.ceil for øvre grenser, og Math.trunc når du kun vil fjerne desimaldelen.

Multiplikasjon, eksponentiering og røtter (pow, **, sqrt, cbrt, hypot)

Eksponentiering og kvadratrøtter kan gjøres med Math.pow eller med **-operatoren. Math.hypot beregner trygt kvadratroten av summen av kvadrater (avstand).

Nedenfor er eksempler på eksponentiering og bruk av hypot. Math.hypot reduserer risikoen for overflyt og underflyt.

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 er nyttig ved beregning av sider i trekanter eller lengden av fler-dimensjonale vektorer.

Eksponential- og logaritmefunksjoner (exp, log, log10, log2)

Eksponentialer og logaritmer brukes ofte i sannsynlighet, eksponentielt forfall og skalering.

Her følger grunnleggende eksempler på bruk av exp og logaritmer. Pass på å bruke riktig funksjon, avhengig av logaritmens grunntall.

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
  • Naturlige logaritmer (Math.log) er standard i statistikk og differensialligninger. Vanlige logaritmer og logaritmer med base 2 velges også ut fra bruksområde.

Trigonometriske funksjoner (sin, cos, tan, asin, acos, atan2)

Trigonometriske funksjoner er essensielle for vinkelberegninger, rotasjoner og koordinattransformasjoner. Math.atan2(y, x) er nyttig for å beregne vinkler med korrekt hensyn til kvadranter.

Nedenfor er grunnleggende eksempler og bruk av atan2. Vinkler må behandles 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 trygt bestemme vinkelen til en vektor, noe som gjør den foretrukket for rotasjoner og retning.

Generering av tilfeldige tall (Math.random og praktiske mønstre)

Math.random() returnerer et jevnt fordelt tilfeldig tall i området [0, 1). Du kan konvertere eller tilpasse det som nødvendig, for eksempel til heltallsområder eller normale fordelinger.

Her er eksempler på nyttefunksjoner for tilfeldige tall. Hvis du trenger kryptografisk sikre tilfeldige tall, bruk 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 er praktisk til generell bruk, men for spill-repriser eller kryptografi kreves tiltak for reproduserbarhet eller sikkerhet.

Praktiske hjelpefunksjoner (clamp, lerp, mapRange, vinkelnormalisering)

Det er nyttig å lage små hjelpefunksjoner selv for ofte brukte matematiske oppgaver.

Her er implementeringseksempler på vanlige hjelpefunksjoner.

 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));
  • Denne koden samler små hjelpefunksjoner som ofte brukes til numeriske operasjoner som begrensning av verdier, interpolering, områdekartlegging og vinkelnormalisering. clamp begrenser en verdi til et bestemt område, mens lerp og mapRange utfører glatt interpolering eller konvertering til et annet område. I tillegg normaliserer normalizeAngle alltid vinkler til området [-π, π) for å stabilisere rotasjonsberegninger.
  • Disse hjelpefunksjonene brukes ofte i grafikk, spill og interaksjonsprogrammering. normalizeAngle er viktig for å sammenligne vinkelendringer og for interpolering.

Forbehold rundt flyttall og avrunding (presisjon og sammenligning)

JavaScript-tall er IEEE-754 flyttall med dobbel presisjon (64-bit), så vær forsiktig ved sammenligning eller avrunding. For eksempel, 0.1 + 0.2 !== 0.3.

Her er et eksempel på håndtering av avrundingsfeil. Det er viktig å bruke sammenligninger som tolererer små feil, eller passende avrundingsfunksjoner.

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
  • For robuste numeriske likhetskontroller, bruk absolutt feil (eps) eller relativ feil.

Ytelsestips

Math-funksjonene er optimalisert i kjernen og er ofte raskere enn tilsvarende håndskrevne funksjoner. Hvis den samme beregningen (for eksempel Math.PI / 180) gjentas i en løkke, reduserer det unødvendig overhead å tildele det til en variabel på forhånd.

Nedenfor er et eksempel på å konvertere grader til radianer ved å opprette en konstant utenfor en løkke.

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 er best å verifisere reelle flaskehalser med en profiler før du optimaliserer.
  • Det er effektivt å mellomlagre konstanter som brukes ofte.

Kompatibilitet og polyfills

Math har eksistert lenge, men noen funksjoner som Math.cbrt, Math.log10, Math.log2 og Math.hypot kan mangle støtte i eldre miljøer. Lag en enkel polyfill ved behov.

Nedenfor er et eksempel på en enkel polyfill for 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));

Mange miljøer støtter disse allerede, men sjekk kompatibilitet ved behov.

Sjekk nettleserstøtte i henhold til prosjektets målmiljø.

Praktisk eksempel: Trinnvise oppdateringer i en enkel fysikksimulering

Til slutt følger et praktisk eksempel som kombinerer flere Math-funksjoner. Dette er et svært enkelt eksempel på oppdatering av posisjon, hastighet og vinkling.

Det er en sterkt forenklet modell av en fysikkmotor.

 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);
  • Ved å kombinere slike Math-hjelpere kan simulerings- og animasjonslogikk gjøres mer konsis.

Sammendrag

  • Math dekker alt fra konstanter og grunnleggende funksjoner til avanserte funksjoner, og fungerer som fundament for numeriske beregninger.
  • Velg funksjoner etter formål, som tilfeldige tall, trigonometriske funksjoner, eksponentialer/logaritmer eller avrunding; og lag små nyttefunksjoner som clamp og lerp for praktisk bruk.
  • Vær oppmerksom på flyttallspresisjon og støtte i ditt målmiljø, og forbered feiltoleranse eller polyfills om nødvendig.

Du kan følge med på artikkelen ovenfor ved å bruke Visual Studio Code på vår YouTube-kanal. Vennligst sjekk ut YouTube-kanalen.

YouTube Video