Come si arriva al primo decimale in Javascript?


Risposte:


729

Math.round(num * 10) / 10 funziona, ecco un esempio ...

var number = 12.3456789
var rounded = Math.round(number * 10) / 10
// rounded is 12.3

se vuoi che abbia un decimale, anche quando sarebbe uno 0, quindi aggiungi ...

var fixed = rounded.toFixed(1)
// fixed is always to 1 d.p.
// NOTE: .toFixed() returns a string!

// To convert back to number format
parseFloat(number.toFixed(2))
// 12.34
// but that will not retain any trailing zeros

// So, just make sure it is the last step before output,
// and use a number format during calculations!

EDIT: Aggiungi round con funzione di precisione ...

Usando questo principio, per riferimento, ecco una pratica piccola funzione rotonda che richiede precisione ...

function round(value, precision) {
    var multiplier = Math.pow(10, precision || 0);
    return Math.round(value * multiplier) / multiplier;
}

... utilizzo ...

round(12345.6789, 2) // 12345.68
round(12345.6789, 1) // 12345.7

... il valore predefinito è arrotondato al numero intero più vicino (precisione 0) ...

round(12345.6789) // 12346

... e può essere utilizzato per arrotondare ai 10 o 100 più vicini ecc ...

round(12345.6789, -1) // 12350
round(12345.6789, -2) // 12300

... e corretta gestione dei numeri negativi ...

round(-123.45, 1) // -123.4
round(123.45, 1) // 123.5

... e può essere combinato con toFixed per formattare coerentemente come stringa ...

round(456.7, 2).toFixed(2) // "456.70"

45
Fare attenzione .toFixed()quando restituisce una stringa quando si desidera un numero.
Cobby,

1
Bene, ovviamente usando parseFloatrimuoverà i decimali lasciati .toFixed()se è un numero intero (zeri). In generale, se vuoi fare i calcoli, è meglio seguire il tuo primo esempio. Se si desidera visualizzare un numero nell'interfaccia utente, utilizzare .toFixed().
Cobby,

Hmmm ... questo ha senso, qualsiasi modo in cui converti in numero deve sempre eliminare gli zeri errati, motivo per cui deve rimanere una stringa. Immagino che dovrebbe sempre essere l'ultimo passo prima della visualizzazione e non utilizzato nei calcoli.
Billy Moon,

2
Fare attenzione all'uso .toFixed()poiché potrebbe restituire risultati di arrotondamento diversi per browser diversi. Leggi questo post per i dettagli sull'argomento!
Wilt

1
Posso aggiungere uno zero se non sono presenti DP?
Nick,

102
var number = 123.456;

console.log(number.toFixed(1)); // should round to 123.5

4
A volte toFixed()ha problemi - l'ho visto in un browser Chrome in cui chiamo toFixed(), quindi converto in una stringa e mostra qualcosa di simile 10.00000000068- strano. Tuttavia, non è possibile riprodurlo in modo affidabile.
Hamish Grubijan,

Sì, ho riscontrato problemi con toFixed () anche con pochi decimali. Ha arrotondato la frazione 4 al successivo numero più alto invece che inferiore, se ricordo bene.
Dalibor,

1
come menzionato da @cobby sopra: stai attento usando .toFixed()come restituisce un Stringquando forse vuoi unNumber
Ricardo

28

Se usi Math.round(5.01), otterrai 5invece di 5.0.

Se lo usi toFixedti imbatti in problemi di arrotondamento .

Se vuoi il meglio di entrambi i mondi, combina i due:

(Math.round(5.01 * 10) / 10).toFixed(1)

Potresti voler creare una funzione per questo:

function roundedToFixed(_float, _digits){
  var rounded = Math.pow(10, _digits);
  return (Math.round(_float * rounded) / rounded).toFixed(_digits);
}

Perché i caratteri di sottolineatura per i parametri cioè (_float, _digits)? Sentiti libero di pubblicare un link dove posso trovare la risposta per me stesso. Grazie
Shark Lasers

23

lodashha un roundmetodo:

_.round(4.006);
// => 4

_.round(4.006, 2);
// => 4.01

_.round(4060, -2);
// => 4100

Doc .

Fonte .


11

Io voto per toFixed(), ma, per la cronaca, ecco un altro modo che usa il bit shifting per lanciare il numero su un int. Quindi, si arrotonda sempre verso lo zero (in basso per i numeri positivi, in alto per i negativi).

var rounded = ((num * 10) << 0) * 0.1;

Ma ehi, dal momento che non ci sono chiamate di funzione, è veloce. :)

Ed eccone uno che usa la corrispondenza delle stringhe:

var rounded = (num + '').replace(/(^.*?\d+)(\.\d)?.*/, '$1$2');

Non consiglio di usare la variante di stringa, basta dire.


7

Prova con questo:

var original=28.453

// 1.- round "original" to two decimals
var result = Math.round (original * 100) / 100  //returns 28.45

// 2.- round "original" to 1 decimal
var result = Math.round (original * 10) / 10  //returns 28.5

// 3.- round 8.111111 to 3 decimals
var result = Math.round (8.111111 * 1000) / 1000  //returns 8.111

meno complicato e più facile da implementare ...

con questo, puoi creare una funzione per fare:

function RoundAndFix (n, d) {
    var m = Math.pow (10, d);
    return Math.round (n * m) / m;
}

EDIT : vedi questo Come arrotondare usando ROUND HALF UP. Modalità di arrotondamento che la maggior parte di noi ha insegnato alle elementari


No: RoundAndFix (1.005, 2).
Noyo,

4

x = numero, n = decimali:

function round(x, n) {
    return Math.round(x * Math.pow(10, n)) / Math.pow(10, n)
}

No: rotondo (1.005, 2).
Noyo,

4

Perché non solo

let myNumber = 213.27321;
+myNumber.toFixed(1); // => 213.3
  1. toFixed : restituisce una stringa che rappresenta il numero dato usando la notazione a virgola fissa.
  2. Unary plus (+) : l'operatore unary plus precede il suo operando e valuta il suo operando ma tenta di convertirlo in un numero, se non lo è già.

3
var num = 34.7654;

num = Math.round(num * 10) / 10;

console.log(num); // Logs: 34.8

3

Per completare la migliore risposta:

var round = function ( number, precision )
{
    precision = precision || 0;
    return parseFloat( parseFloat( number ).toFixed( precision ) );
}

Il numero del parametro di input può "non" essere sempre un numero, in questo caso .toFixed non esiste.


3

Versione ES 6 della risposta accettata:

function round(value, precision) {
    const multiplier = 10 ** (precision || 0);
    return Math.round(value * multiplier) / multiplier;
}

3

Utilizzando il metodo toPrecision:

var a = 1.2345
a.toPrecision(2)

// result "1.2"

Di gran lunga la migliore risposta che ho provato. Grazie.
Ste

Ma devi stare attento perché lo 12.345.toPrecision( 2 )è "12".
Joshua Pinter,

2

Se il tuo metodo non funziona, per favore pubblica il tuo codice.

Tuttavia, è possibile eseguire l'attività di arrotondamento come:

var value = Math.round(234.567*100)/100

Ti darà 234,56

allo stesso modo

 var value = Math.round(234.567*10)/10

Darà 234,5

In questo modo è possibile utilizzare una variabile al posto della costante utilizzata in precedenza.


1

Piccolo filtro angolare se qualcuno lo vuole:

angular.module('filters').filter('decimalPlace', function() {
    return function(num, precision) {
        var multiplier = Math.pow(10, precision || 0);
        return Math.round(num * multiplier) / multiplier;
    };
});

utilizzare se tramite:

{{model.value| decimalPlace}}
{{model.value| decimalPlace:1}}
{{model.value| decimalPlace:2}}

:)


1

In generale, l'arrotondamento viene eseguito ridimensionando: round(num / p) * p

L'uso della notazione esponenziale gestisce correttamente l'arrotondamento di + ve numeri, Tuttavia, questo metodo non riesce a arrotondare correttamente i casi limite.

function round(num, precision = 2) {
	var scaled = Math.round(num + "e" + precision);
	return Number(scaled + "e" + -precision);
}

// testing some edge cases
console.log( round(1.005, 2) );  // 1.01 correct
console.log( round(2.175, 2) );  // 2.18 correct
console.log( round(5.015, 2) );  // 5.02 correct

console.log( round(-1.005, 2) );  // -1    wrong
console.log( round(-2.175, 2) );  // -2.17 wrong
console.log( round(-5.015, 2) );  // -5.01 wrong

Anche qui è una funzione che ho scritto per eseguire arrotondamenti aritmetici, puoi testarlo tu stesso.

/**
 * MidpointRounding away from zero ('arithmetic' rounding)
 * Uses a half-epsilon for correction. (This offsets IEEE-754
 * half-to-even rounding that was applied at the edge cases).
 */

function RoundCorrect(num, precision = 2) {
	// half epsilon to correct edge cases.
	var c = 0.5 * Number.EPSILON * num;
//	var p = Math.pow(10, precision); //slow
	var p = 1; while (precision--> 0) p *= 10;
	if (num < 0)
		p *= -1;
	return Math.round((num + c) * p) / p;
}

// testing some edge cases
console.log(RoundCorrect(1.005, 2));  // 1.01 correct
console.log(RoundCorrect(2.175, 2));  // 2.18 correct
console.log(RoundCorrect(5.015, 2));  // 5.02 correct

console.log(RoundCorrect(-1.005, 2));  // -1.01 correct
console.log(RoundCorrect(-2.175, 2));  // -2.18 correct
console.log(RoundCorrect(-5.015, 2));  // -5.02 correct


0

Questo sembra funzionare in modo affidabile su tutto ciò che lancio:

function round(val, multiplesOf) {
  var s = 1 / multiplesOf;
  var res = Math.ceil(val*s)/s;
  res = res < val ? res + multiplesOf: res;
  var afterZero = multiplesOf.toString().split(".")[1];
  return parseFloat(res.toFixed(afterZero ? afterZero.length : 0));
}

Arrotonda per eccesso, quindi potrebbe essere necessario modificarlo in base al caso d'uso. Questo dovrebbe funzionare:

console.log(round(10.01, 1)); //outputs 11
console.log(round(10.01, 0.1)); //outputs 10.1

0

Se ti interessa un corretto arrotondamento, allora:

function roundNumericStrings(str , numOfDecPlacesRequired){ 
     var roundFactor = Math.pow(10, numOfDecPlacesRequired);  
     return (Math.round(parseFloat(str)*roundFactor)/roundFactor).toString();  }

Altrimenti, in caso contrario, hai già una risposta dai post precedenti

str.slice(0, -1)

0

Math.round( num * 10) / 10 non funziona

Ad esempio, 1455581777.8-145558160.4ti dà 1310023617.3999999.

Quindi usa solo num.toFixed(1)


0

Ne ho creato uno che restituisce il tipo di numero e posiziona anche i decimali solo se sono necessari (nessuna imbottitura 0).

Esempi:

roundWithMaxPrecision(11.234, 2); //11.23
roundWithMaxPrecision(11.234, 1); //11.2
roundWithMaxPrecision(11.234, 4); //11.23
roundWithMaxPrecision(11.234, -1); //10

roundWithMaxPrecision(4.2, 2); //4.2
roundWithMaxPrecision(4.88, 1); //4.9

Il codice:

function roundWithMaxPrecision (n, precision) {
    return Math.round(n * Math.pow(10, precision)) / Math.pow(10, precision);
}

0

Ho trovato un modo per evitare i problemi di precisione:

function badRound (num, precision) {
    const x = 10 ** precision;
    return Math.round(num * x) / x
}
// badRound(1.005, 2) --> 1

function round (num, precision) {
    const x = 10 ** (precision + 1);
    const y = 10 ** precision;
    return Math.round(Math.round(num * x) / 10) / y
}
// round(1.005, 2) --> 1.01

0
Math.round( mul/count * 10 ) / 10

Math.round(Math.sqrt(sqD/y) * 10 ) / 10

Grazie

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.