Javascript'te bir sayı nasıl yuvarlanır?


159

Bir sayıyı yuvarlamak için Javascript kullanmak istiyorum. Sayı para birimi olduğundan, bu örneklerde olduğu gibi yuvarlanmasını istiyorum (2 ondalık sayı):

  • 192.168 => 192.20
  • 192.11 => 192.20
  • 192.21 => 192.30
  • 192.26 => 192.30
  • 192.20 => 192.20

Javascript kullanarak bunu nasıl başarabilirim? Yerleşik Javascript işlevi, sayıyı standart mantığa göre yuvarlar (yuvarlamak için 5'ten az ve daha fazla).

Yanıtlar:


313
/**
 * @param num The number to round
 * @param precision The number of decimal places to preserve
 */
function roundUp(num, precision) {
  precision = Math.pow(10, precision)
  return Math.ceil(num * precision) / precision
}

roundUp(192.168, 1) //=> 192.2

2
@AndrewMarshall çarpma, sonra bölme 10 nedir?
codecowboy

6
@codecowboy Eğer yapmazsanız, o ceil()zaman size verecektir 193, bu yüzden tutmak istediğimiz tüm hassasiyetlerin ondalık noktadan önce olduğundan emin olmalıyız. Ardından, “orijinal” değeri geri yüklemek için ters işlemi yaparız.
Andrew Marshall

1
Gibi bir sayı 192.19999999999997alırsanız .toFixed(1),num
flamer.ohr

4
Ve burada en yakın TÜM numaraya nasıl yuvarlanacağını merak edenler için sadece Math.ceil () 'e ihtiyacınız var. Gerisi sadece ondalıklarla uğraşmaktır. Başkalarını kurtarmak için beynimin buna ulaşması zaman aldı!
Nigel

Bu çözümde hata var: Math.ceil (0.0159 * 1000000000) / duyarlık. 0.015900001 oranını alacaksınız. Hassasiyet için bir aralık doğrulaması eklemeniz gerekir.
Frank

26

Biraz geç ama, bu amaçla yeniden kullanılabilir bir javascript işlevi oluşturabilirsiniz:

// Arguments: number to round, number of decimal places
function roundNumber(rnum, rlength) { 
    var newnumber = Math.round(rnum * Math.pow(10, rlength)) / Math.pow(10, rlength);
    return newnumber;
}

İşlevi şu şekilde çağır:

alert(roundNumber(192.168,2));

2
Bu harika çalışıyor, ancak OP bir sayının nasıl yuvarlanacağını sordu, bu yüzden burada Math.round yerine Math.ceil kullanılmalıdır.
kloddant

Hedeflediğiniz ondalık yere rağmen düzgün bir şekilde yuvarlanmak istiyorsanız, bu cevap kabul edilen cevaptan daha iyidir. Örn: 1.054 -> 1.05 1.055 -> 1.06 ANCAK burada bir kenar durum: 1.005 -> 1 1.006 -> 1.01 VE 1.015 -> 1.01 1.016 -> 1.02 Dikkatli olun.
Jay K

21

Normal yuvarlama küçük bir değişiklikle çalışır:

Math.round(price * 10)/10

ve para birimi biçimini korumak istiyorsanız Sayı yöntemini kullanabilirsiniz .toFixed()

(Math.round(price * 10)/10).toFixed(2)

Rağmen bu bir String =) yapacak


Math.round (192.11 * 100) / 100 -> 192.11
krtek

1
İkincisinin yuvarlamaya ihtiyacı yok, daha çokprice.toFixed(2)
Michael Krelin - hacker

@Krtek ooops, Bunu yakaladığınız için teşekkürler. Soruyu yanlış okudum. Yanıt güncellendi.
Shad

2
OP bir sayının nasıl yuvarlanacağını sordu, bu yüzden burada Math.round yerine Math.ceil kullanılmalıdır.
kloddant

10

TheEye cevabına çok yakın , ama çalışmasını sağlamak için küçük bir şey değiştiriyorum:

var num = 192.16;
    
console.log(    Math.ceil(num * 10) / 10    );


2

OP iki şey bekliyor:
A. daha yüksek ondalık sayılara yuvarlamak ve
B. yüzüncü yerde sıfır göstermek için (para birimi ile tipik bir ihtiyaç).

Her iki gereksinimin karşılanması, yukarıdakilerin her biri için ayrı bir yöntem gerektiriyor gibi görünmektedir. Suryakiran'ın önerdiği cevabı temel alan bir yaklaşım:

//Arguments: number to round, number of decimal places.

function roundPrice(rnum, rlength) {
    var newnumber = Math.ceil(rnum * Math.pow(10, rlength-1)) / Math.pow(10, rlength-1);
    var toTenths = newnumber.toFixed(rlength);
    return toTenths;
}

alert(roundPrice(678.91011,2)); // returns 679.00
alert(roundPrice(876.54321,2)); // returns 876.60

Önemli not: bu çözüm negatif ve üstel sayılarla çok farklı bir sonuç üretir.

Bu cevap ile çok benzer iki cevap arasında karşılaştırma yapmak için aşağıdaki 2 yaklaşıma bakınız. Birincisi her zamanki en yakın yüzüncü yüzyıla yuvarlar ve ikincisi sadece en yakın yüzüncü yüzeye (daha büyük) yuvarlar.

function roundNumber(rnum, rlength) { 
    var newnumber = Math.round(rnum * Math.pow(10, rlength)) / Math.pow(10, rlength);
    return newnumber;
}

alert(roundNumber(678.91011,2)); // returns 678.91

function ceilNumber(rnum, rlength) { 
    var newnumber = Math.ceil(rnum * Math.pow(10, rlength)) / Math.pow(10, rlength);
    return newnumber;
}

alert(ceilNumber(678.91011,2)); // returns 678.92

2

tamam, bu cevaplandı, ama bir kere math.pow () işlevini çağıran cevabımı görmek isteyebileceğinizi düşündüm. Sanırım şeyleri KURU tutmayı seviyorum.

function roundIt(num, precision) {
    var rounder = Math.pow(10, precision);
    return (Math.round(num * rounder) / rounder).toFixed(precision)
};

Her şeyi bir araya getiriyor. OP'nin istediği yuvarlama yerine yuvarlamak için Math.round () yerine Math.ceil () kullanın.


1

bu fonksiyon, ondalık sayı olmadan ondalık sınırı

function limitDecimal(num,decimal){
     return num.toString().substring(0, num.toString().indexOf('.')) + (num.toString().substr(num.toString().indexOf('.'), decimal+1));
}

Daha kısa bir alternatif olarak: dönüş ('' + num) .split ('.'). Shift ()
Roberto

teşekkürler Roberto bu kod çalışması, ancak tüm ondalık kaldırmak
Behnam Mohammadi

0

@AndrewMarshall cevabını uzun süredir kullanıyorum, ancak bazı uç durumlar buldum. Aşağıdaki testler geçmez:

equals(roundUp(9.69545, 4), 9.6955);
equals(roundUp(37.760000000000005, 4), 37.76);
equals(roundUp(5.83333333, 4), 5.8333);

İşte şimdi yukarı doğru davranmak için kullandığım şey:

// Closure
(function() {
  /**
   * Decimal adjustment of a number.
   *
   * @param {String}  type  The type of adjustment.
   * @param {Number}  value The number.
   * @param {Integer} exp   The exponent (the 10 logarithm of the adjustment base).
   * @returns {Number} The adjusted value.
   */
  function decimalAdjust(type, value, exp) {
    // If the exp is undefined or zero...
    if (typeof exp === 'undefined' || +exp === 0) {
      return Math[type](value);
    }
    value = +value;
    exp = +exp;
    // If the value is not a number or the exp is not an integer...
    if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
      return NaN;
    }
    // If the value is negative...
    if (value < 0) {
      return -decimalAdjust(type, -value, exp);
    }
    // Shift
    value = value.toString().split('e');
    value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
    // Shift back
    value = value.toString().split('e');
    return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
  }

  // Decimal round
  if (!Math.round10) {
    Math.round10 = function(value, exp) {
      return decimalAdjust('round', value, exp);
    };
  }
  // Decimal floor
  if (!Math.floor10) {
    Math.floor10 = function(value, exp) {
      return decimalAdjust('floor', value, exp);
    };
  }
  // Decimal ceil
  if (!Math.ceil10) {
    Math.ceil10 = function(value, exp) {
      return decimalAdjust('ceil', value, exp);
    };
  }
})();

// Round
Math.round10(55.55, -1);   // 55.6
Math.round10(55.549, -1);  // 55.5
Math.round10(55, 1);       // 60
Math.round10(54.9, 1);     // 50
Math.round10(-55.55, -1);  // -55.5
Math.round10(-55.551, -1); // -55.6
Math.round10(-55, 1);      // -50
Math.round10(-55.1, 1);    // -60
Math.round10(1.005, -2);   // 1.01 -- compare this with Math.round(1.005*100)/100 above
Math.round10(-1.005, -2);  // -1.01
// Floor
Math.floor10(55.59, -1);   // 55.5
Math.floor10(59, 1);       // 50
Math.floor10(-55.51, -1);  // -55.6
Math.floor10(-51, 1);      // -60
// Ceil
Math.ceil10(55.51, -1);    // 55.6
Math.ceil10(51, 1);        // 60
Math.ceil10(-55.59, -1);   // -55.5
Math.ceil10(-59, 1);       // -50

Kaynak: https://developer.mozilla.org/tr-TR/docs/Web/JavaScript/Reference/Global_Objects/Math/round


1
Test durumlarınız yanlış görünüyor. roundUp(37.760000000000005, 4)olmalı 37.7601ve roundUp(5.83333333, 4)olmalı 5.8334. Bu iki (ve ilk) tüm sağladığım fn için geçerlidir.
Andrew Marshall

@AndrewMarshall'ın bir nedeni var, durum 2 ve 3 için beklenen değerleriniz yanlış
Amn

-3

parseInt her zaman soo aşağı yuvarlar .....

console.log(parseInt(5.8)+1);

parseInt () + 1 yap

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.