Soru En fazla 2 ondalık basamağa yuvarlanır (yalnızca gerekirse)


En fazla 2 ondalık basamağı yuvarlamak istiyorum ama sadece gerekirse.

Giriş:

10
1.7777777
9.1

Çıktı:

10
1.78
9.1

Bunu nasıl yapabilirim JavaScript?


1845
2017-08-06 17:17


Menşei


Burada çözümler olarak sunulan birçok teknikle bir keman yaptım ... böylece karşılaştırma yapabilirsiniz: keman - dsdsdsdsd
Hiç kimse farkında değil gibi görünüyor Number.EPSILON. kullanım Math.round( num * 100 + Number.EPSILON ) / 100. - cronvel
Yeni okuyucular için bunu yapamazsınız string tipi bir sonuç olmadıkça. Sayıların ikili iç gösterimleri üzerine kayan nokta matematikleri, her zaman temiz ondalık olarak temsil edilemeyen sayılar. - Walf


Cevaplar:


kullanım Math.round(num * 100) / 100


2292
2017-08-06 17:20



Bu çoğu durumda işe yarayacak olsa da, 1.005 için çalışmayacak, sonuçta 1.01 yerine 1 olacak. - James
@James Wow bu gerçekten garip-Chrome dev konsolunda çalışıyorum ve 1.005 * 100 = 100.49999999999999 olduğunu farkettim. Math.round (100.49999999999999) 100'e, Math.round (100.5) ise 101'e kadar değerlendirir. IE9 aynı şeyi yapar. Bunun nedeni javascript içinde kayan nokta tuhaflığı - stinkycheeseman
Basit bir çözüm. 2 d.p. için Math.round((num + 0.00001) * 100) / 100. Deneyin Math.round((1.005 + 0.00001) * 100) / 100 ve Math.round((1.0049 + 0.00001) * 100) / 100 - mrkschan
@mrkschan Neden bu çalışıyor ve tüm numaralar için bu kadar kusursuz mu? - CMCDragonkai
Bunu almayanlarınız için bu teknik, ölçeklendirme olarak adlandırılır. Temel olarak, burada cevap ne demek, ondalık noktanın iki rakamını, tüm çılgın kayan nokta sorunlarından kaçınmak için rakamı tam sayıya çevirmek ve daha sonra 100'e bölerek daha önce olduğu gibi geri çevirmektir. 2dp'ye cevap ver. - Alex_Nabu


Değer bir metin türüyse:

parseFloat("123.456").toFixed(2);

Değer bir sayıysa:

var numb = 123.23454;
numb = numb.toFixed(2);

1.5 gibi değerlerin çıktı olarak "1.50" değerini verecek bir dezavantajı var. @Minitech tarafından önerilen bir düzeltme:

var numb = 1.5;
numb = +numb.toFixed(2);
// Note the plus sign that drops any "extra" zeroes at the end.
// It changes the result (which is a string) into a number again (think "0 + foo"),
// which means that it uses only as many digits as necessary.

Benziyor Math.round daha iyi bir çözümdür. Ama öyle değil! Bazı durumlarda olacak DEĞİL doğru yuvarlak:

Math.round(1.005 * 1000)/1000 // Returns 1 instead of expected 1.01!

toFixed () de olacak DEĞİL Bazı durumlarda doğru şekilde yuvarlak (Chrome v.55.0.2883.87'de test edilmiştir)!

Örnekler:

parseFloat("1.555").toFixed(2); // Returns 1.55 instead of 1.56.
parseFloat("1.5550").toFixed(2); // Returns 1.55 instead of 1.56.
// However, it will return correct result if you round 1.5551.
parseFloat("1.5551").toFixed(2); // Returns 1.56 as expected.

1.3555.toFixed(3) // Returns 1.355 instead of expected 1.356.
// However, it will return correct result if you round 1.35551.
1.35551.toFixed(2); // Returns 1.36 as expected.

Sanırım, çünkü 1.555 aslında sahnelerin arkasında 1.55499994 gibi bir şey.

Çözüm 1 gerekli yuvarlama algoritmasına sahip bir komut dosyası kullanmaktır, örneğin:

function roundNumber(num, scale) {
  if(!("" + num).includes("e")) {
    return +(Math.round(num + "e+" + scale)  + "e-" + scale);
  } else {
    var arr = ("" + num).split("e");
    var sig = ""
    if(+arr[1] + scale > 0) {
      sig = "+";
    }
    return +(Math.round(+arr[0] + "e" + sig + (+arr[1] + scale)) + "e-" + scale);
  }
}

https://plnkr.co/edit/uau8BlS1cqbvWPCHJeOy?p=preview

Çözüm 2 ön uç hesaplarından kaçınmak ve arka uç sunucusundan yuvarlak değerleri almaktır.


2327
2017-10-11 00:27



Bu (toFixed) yaklaşım iyi ve benim için çalıştı, ama özellikle değil "sadece gerektiğinde" orijinal isteğine uymak. (Spesifikasyonu bozan 1.5 ile 1.50 arasındadır.) - Per Lundberg
"Gerektiğinde" gereksinimi için şunu yapın: parseFloat(number.toFixed(decimalPlaces));   @PerLundberg - Onur Yıldırım
parseFloat("55.555").toFixed(2) döner "55.55" Chrome dev konsolunda. - Levi Botelho
Math.round yerine toFixed kullanmanın avantajı yoktur; toFixed, aynı yuvarlama sorunlarına yol açar (bunları 5.555 ve 1.005 ile deneyin), ancak Math.round'den daha yavaş 500x (şaka yapmaz) gibidir ... @MarkG cevabı burada daha doğru gibi görünüyor. - Pierre
Js neden bu kadar garip? - D.Deriso


Kullanabilirsiniz

function roundToTwo(num) {    
    return +(Math.round(num + "e+2")  + "e-2");
}

Bunu buldum MDN. Onların yolu 1.005 ile olan problemi ortadan kaldırıyor. adı geçen.

roundToTwo(1.005)
1.01
roundToTwo(10)
10
roundToTwo(1.7777777)
1.78
roundToTwo(9.1)
9.1
roundToTwo(1234.5678)
1234.57

324
2017-08-21 12:56



@Redsandro, +(val) kullanmanın zorlayıcı karşılığıdır Number(val). "E-2" yi bir sayıya birleştirmek, bir sayıya dönüştürülmesi gereken bir dizeyle sonuçlandı. - Jack
NaN üretecek büyük ve küçük yüzdürmeler için, örn. + "1e-21 + 2" nin doğru şekilde ayrıştırılmamasına dikkat edin. - Pierre
'1.005' sorununu 'çözdünüz', ancak yeni bir tane sundunuz: şimdi, Chrome konsolunda, roundToTwo(1.0049999999999999) 1.01 olarak geliyor (kaçınılmaz olarak, 1.0049999999999999 == 1.005). Bana yazarsak alacağın şamandıra num = 1.005 'Açıkça' '1.00'a yuvarlanmalı, çünkü num'in tam değeri 1.005'ten az. Tabii ki, '1.005' 'açıkçası' '1,01'e yuvarlanmalı. Farklı insanların gerçek doğru davranışların burada ne olduğu konusunda farklı sezgilere sahip olduğu gerçeği, bunun neden karmaşık olduğunun bir parçasıdır. - Mark Amery
Arasında hiçbir (kayan nokta) numarası yoktur 1.0049999999999999 ve 1.005Yani tanım gereği, aynı sayıdalar. Buna dedekind kesmesi denir. - Azmisov
@ Izmisov haklı. Süre 1.00499 < 1.005 olduğu true, 1.0049999999999999 < 1.005 değerlendirir false. - falconepl


MarkG'nin cevabı doğru olanıdır. Burada herhangi bir sayıdaki ondalık basamak için genel bir uzantı var.

Number.prototype.round = function(places) {
  return +(Math.round(this + "e+" + places)  + "e-" + places);
}

Kullanımı:

var n = 1.7777;    
n.round(2); // 1.78

Ünite testi:

it.only('should round floats to 2 places', function() {

  var cases = [
    { n: 10,      e: 10,    p:2 },
    { n: 1.7777,  e: 1.78,  p:2 },
    { n: 1.005,   e: 1.01,  p:2 },
    { n: 1.005,   e: 1,     p:0 },
    { n: 1.77777, e: 1.8,   p:1 }
  ]

  cases.forEach(function(testCase) {
    var r = testCase.n.round(testCase.p);
    assert.equal(r, testCase.e, 'didn\'t get right number');
  });
})

115
2017-11-01 07:40



Pierre MarkG'nin cevabıyla ciddi bir sorun çıkardı. - dsjoerg
Not: Number.prototype'ı değiştirmek istemiyorsanız, bunu bir işlev olarak yazın: function round(number, decimals) { return +(Math.round(number + "e+" + decimals) + "e-" + decimals); } - Philipp Tsipman
ben YARATTIM Math.roundPlaces(num, places)Böylece dizeler üzerinde de çalışacaktır (sadece durumda). - bradlis7
N: 1e + 19'u dene - NaN döndürür - DavidJ
Bu algoritma her zaman yuvarlanır (sıfırdan ziyade). Yani, negatif sayılar söz konusu olduğunda, çıktı beklediğiniz gibi değildir: (-1.005).round(2) === -1 - Aleksej Komarov


Bir kullanabilirsiniz .toFixed(NumberOfDecimalPlaces).

var str = 10.234.toFixed(2); // => '10.23'
var number = Number(str); // => 10.23

71
2017-10-21 17:02



Neden bu en iyi cevap değil mi ??? (DÜZENLEME: oh, çünkü bir String'e dönüştüğü için :) - Daniel
Ayrıca, takip eden sıfırları eklediğinden, orijinal soru sorulmadı. - Alastair Maw
Ancak takip eden sıfırlar bir normal ifadeyle kolayca sıyrılır, yani 'Number (10.10000.toFixed (2) .replace (/ 0 + $ /,' ')) `=> 10.1 - Chad McElligott
@daniel en iyi cevap aynı (şimdiki gibi) ama değil alsways doğru yuvarlak, deneyin +(1.005).toFixed(2) hangi döndürür 1 yerine 1.01. - Emile Bergeron
@ChadMcElligott: İntikamınız tamsayılarla iyi çalışmaz: Number(9).toFixed(2).replace(/0+$/, '') => "9." - Jacob van Lingen


Kesin bir yuvarlama yöntemi. Kaynak: Mozilla

(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;
        }
        // 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);
        };
    }
})();

Örnekler:

// 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
// 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

54
2017-08-01 08:02



Birisi bunu GitHub ve npm'e koydu: github.com/jhohlfeld/round10 - Jo Liss
Serin ve çalışma kodu. teşekkür ederim @Error. !! - Anahit DEV
Hayır, Math.round10(3544.5249, -2) 3544.52 yerine 3544.53 değerini döndürür - Matija
@Matija Wolfram alfa 3544.52 de diyor. Geçerli sayı ve yuvarlanmış yaklaşık arasındaki hatayı en aza indirmek istersiniz. En yakın yakınlaştırma 3544.5249 2 ondalık basamağa 3544.52 (hata = 0.0049). Olsaydı 3544.53, hata 0.0051 olur. Ardışık yuvarlama yapıyorsunuz, yani daha büyük bir yuvarlama hatası veren ve bu nedenle arzu edilmeyen Math.round10 (Math.round10 (3544.5249, -3), -2). - user
@Matija, matematiksel bakış açısından, 3544.5249 yuvarlanmış 3544.52 değil 3544.52, yani bu kod doğrudur. Eğer bunu 3544.53'e ve bunun gibi durumlara (zor olsa bile) yuvarlatmak isterseniz, bunun gibi bir şey yapın: number += 0.00011 - Bozidar Sikanjic


Burada bulunan cevapların hiçbiri doğru değil. @stinkycheeseman sordu hesabı yuvarlamak, hepiniz numarayı yuvarladınız.

Yuvarlamak için şunu kullanın:

Math.ceil(num * 100)/100;

53
2018-06-13 09:35



Örnek girdi ve çıktı, “yuvarlak…” sorusunun söylense de aslında “yuvarlak…” olması gerektiğini gösterdi. - JayDM
@stinkycheeseman, belirli bir durumda bir hatayı işaret ediyordu, her zaman tavanı yapmak istemiyordu, o sadece 0.005'i 0,01'e yükseltmek istedi - mjaggard
Test ederken garip bir hata buldum Math.ceil(1.1 * 100)/100; -it dönüşler 1.11çünkü 1.1 * 100 110.00000000000001 yeni modern tarayıcılara göre Firefox, Chrome, Safari ve Opera ... IE, eski moda, hala düşünüyor 1.1*100=1100. - skobaljic
@skobaljic deneyin Math.ceil(num.toFixed(4) * 100) / 100 - treeface
@treeface Math.ceil((1.1).toFixed(4) * 100) / 100 ayrıca dönecek 1.11 Firefox'ta, modern tarayıcılar problemi / hatası çarpma ile ilgilidir ve insanlar bunu bilmelidir (örneğin bir piyango oyunu üzerinde çalıştım). - skobaljic


Bu soru karmaşıktır.

Bir fonksiyonumuz olduğunu varsayalım roundTo2DP(num)Bir argüman olarak bir float alır ve 2 ondalık basamağa yuvarlanmış bir değer döndürür. Bu ifadelerin her biri ne değerlendirmeli?

  • roundTo2DP(0.014999999999999999)
  • roundTo2DP(0.0150000000000000001)
  • roundTo2DP(0.015)

'Açık' cevabı, ilk örneğin 0.01'e (çünkü 0,02'den 0,02'ye daha yakın olduğu), diğer ikisi de 0,02'ye yuvarlanması gerektiğidir (çünkü 0.0150000000000000000001, 0,02'ye 0,02'ye daha yakındır ve çünkü 0.015 tam olarak yarıya doğrudur. Onları ve bu sayılar toparlanmış bir matematiksel kongre var.

Tahmin edebileceğiniz av miktarı roundTo2DP  muhtemelen Bu açık cevapları vermek için uygulanmalı, çünkü her üç sayıya geçtiği için aynı numara. IEEE 754 ikili kayan nokta sayıları (JavaScript tarafından kullanılan tür) tamsayı olmayan sayıların çoğunu tam olarak temsil edemez ve bu nedenle yukarıdaki üç sayısal yazının tümü, geçerli bir geçerli kayan nokta sayısına yuvarlanır. Bu sayı, olduğu gibi, kesinlikle

0,01499999999999999944488848768742172978818416595458984375

0,01 ila 0,02'ye daha yakındır.

Üç sayının da tarayıcı konsolunuzda, Düğüm kabuğunda veya başka bir JavaScript yorumlayıcısında aynı olduğunu görebilirsiniz. Sadece onları karşılaştır:

> 0,014999999999999999 === 0,0150000000000000001
true

Ben yazdığımda m = 0.0150000000000000001, kesin değeri mile sonuçlandığım daha yakın 0.01 göre daha 0.02. Ve yine eğer dönüştürürsem m bir String ...

> var m = 0.0150000000000000001;
> console.log (String (m));
0.015
> var m = 0.014999999999999999;
> console.log (String (m));
0.015

... 0.015 aldım, 0,02'ye kadar çıkmalı ve farkedilir bir şekilde değil Daha önce belirttiğim 56 ondalık sayı, bu sayıların hepsinin tam olarak eşit olduğunu söyledi. Peki bu karanlık büyü nedir?

Cevap, bölümdeki ECMAScript spesifikasyonunda bulunabilir. 7.1.12.1: Sayı türüne uygulanan ToString. İşte bazı Sayıları dönüştürme kuralları m bir String atılmıştır. Anahtar bölüm, bir tam sayı olduğu 5 noktasıdır. s basamakları String gösterimi içinde kullanılacak olan üretilir m:

let n, k, ve s tamsayı olmak k , 1, 10k-1 ≤ s <10kiçin sayı değeri s × 10n-k olduğu m, ve k mümkün olduğunca küçüktür. K'nin ondalık gösterimdeki basamak sayısı olduğunu unutmayın. s, bu s 10 ile bölünemez ve en az önemli olan s Bu kriterler mutlaka ayrı olarak belirlenemez.

Buradaki anahtar bölüm, "k Mümkün olduğu kadar küçüktür. Bu şartın ne olduğu bir sayıdır. m, değeri String(m) olmalı mümkün olan en az sayı hala ihtiyacı karşılarken Number(String(m)) === m. Bunu zaten biliyoruz 0.015 === 0.0150000000000000001şimdi neden belli oldu String(0.0150000000000000001) === '0.015' doğru olmalı.

Elbette, bu tartışmanın hiçbiri doğrudan roundTo2DP(m)  meli dönüş. Eğer mTam değeri 0.01499999999999999944488848768742172978818416595458984375, ancak onun dize gösterimi '0.015', sonra ne doğru - matematiksel olarak, pratik olarak, felsefi olarak, ya da her neyse - onu iki ondalık basamağa yuvarlarken mi?

Buna tek bir doğru cevap yoktur. Kullanım durumunuza göre değişir. Muhtemelen String temsiline saygı duymak ve aşağıdaki durumlarda yukarı doğru ilerlemek istersiniz:

  • Temsil edilen değer, doğası gereği ayrık, örn. dinar gibi 3 ondalık para biriminde bir para birimi. Bu durumda doğru 0,015 gibi bir sayının değeri olduğu 0.015 ve ikili kayan noktaya aldığı 0,0149999999 ... temsili bir yuvarlama hatasıdır. (Elbette, birçoğu, bu değerleri işlemek için ondalık bir kütüphane kullanmanız gerektiğini ve hiçbir zaman bunları ilk önce ikili kayan nokta Sayıları olarak temsil etmeyeceğinizi tartışacaktır.)
  • Değer bir kullanıcı tarafından yazılmıştır. Bu durumda, tekrar girilen tam ondalık sayı, en yakın ikili kayan nokta temsilinden daha 'doğru' sayılır.

Öte yandan, muhtemelen ikili kayan nokta değerine saygı duymak ve değeriniz doğal olarak sürekli bir ölçekte olduğunda aşağı doğru yuvarlamak istersiniz - örneğin, eğer bir sensörden bir okuma ise.

Bu iki yaklaşım farklı kod gerektirir. Sayıların String temsiline saygı duymak için, (oldukça makul derecede ince bir kodla), doğrudan doğruya String gösterimi üzerinde hareket eden kendi yuvarlağımızı uygulayabiliriz. sayıların nasıl yuvarlaklaştırılacağı öğretildi. Aşağıda, OP'nin ondalık noktadan sonraki sıfırlama sırasını sıyırtarak sayıyı 2 ondalık basamağa "yalnızca gerektiğinde" temsil etme gereksinimini dikkate alan bir örnek verilmiştir; Tabi ki, kesin ihtiyaçlarınız için onu düzeltmeniz gerekebilir.

/**
 * Converts num to a decimal string (if it isn't one already) and then rounds it
 * to at most dp decimal places.
 *
 * For explanation of why you'd want to perform rounding operations on a String
 * rather than a Number, see http://stackoverflow.com/a/38676273/1709587
 *
 * @param {(number|string)} num
 * @param {number} dp
 * @return {string}
 */
function roundStringNumberWithoutTrailingZeroes (num, dp) {
    if (arguments.length != 2) throw new Error("2 arguments required");

    num = String(num);
    if (num.indexOf('e+') != -1) {
        // Can't round numbers this large because their string representation
        // contains an exponent, like 9.99e+37
        throw new Error("num too large");
    }
    if (num.indexOf('.') == -1) {
        // Nothing to do
        return num;
    }

    var parts = num.split('.'),
        beforePoint = parts[0],
        afterPoint = parts[1],
        shouldRoundUp = afterPoint[dp] >= 5,
        finalNumber;

    afterPoint = afterPoint.slice(0, dp);
    if (!shouldRoundUp) {
        finalNumber = beforePoint + '.' + afterPoint;
    } else if (/^9+$/.test(afterPoint)) {
        // If we need to round up a number like 1.9999, increment the integer
        // before the decimal point and discard the fractional part.
        finalNumber = Number(beforePoint)+1;
    } else {
        // Starting from the last digit, increment digits until we find one
        // that is not 9, then stop
        var i = dp-1;
        while (true) {
            if (afterPoint[i] == '9') {
                afterPoint = afterPoint.substr(0, i) +
                             '0' +
                             afterPoint.substr(i+1);
                i--;
            } else {
                afterPoint = afterPoint.substr(0, i) +
                             (Number(afterPoint[i]) + 1) +
                             afterPoint.substr(i+1);
                break;
            }
        }

        finalNumber = beforePoint + '.' + afterPoint;
    }

    // Remove trailing zeroes from fractional part before returning
    return finalNumber.replace(/0+$/, '')
}

Örnek kullanım:

> roundStringNumberWithoutTrailingZeroes (1.6, 2)
'1.6'
> roundStringNumberWithoutTrailingZeroes (10000, 2)
'10000'
> roundStringNumberWithoutTrailingZeroes (0.015, 2)
'0.02'
> roundStringNumberWithoutTrailingZeroes ('0.015000', 2)
'0.02'
> roundStringNumberWithoutTrailingZeroes (1, 1)
'1'
> roundStringNumberWithoutTrailingZeroes ('0.015', 2)
'0.02'
> roundStringNumberWithoutTrailingZeroes (0.01499999999999999944488848768742172978818416595458984375, 2)
'0.02'
> roundStringNumberWithoutTrailingZeroes ('0.01499999999999999944488848768742172978818416595458984375', 2)
'0.01'

Yukarıdaki işlev muhtemelen Kullanıcıların girmiş oldukları numaralara yanlış bir şekilde yuvarlanmasından kaçınmak için ne kullanmak istiyorsunuz?

(Alternatif olarak, aynı zamanda round10 çılgınca farklı bir uygulama ile benzer bir davranış işlevi sağlayan kütüphane.)

Ama ya ikinci tür Sayıya sahipseniz - sürekli bir ölçekden alınan bir değer, daha az ondalık basamaklı yaklaşık ondalık gösterimlerin daha fazla olduğunu düşünmek için hiçbir neden yoktur. doğru daha fazlası olanlardan daha mı? Bu durumda biz yapamaz String temsiline saygı duymak istersiniz, çünkü bu temsil (spesifikasyonda açıklandığı gibi) zaten yuvarlak olup; "0.014999999 ... 0.015'e kadar 375 mermi, 0.02'ye yuvarlayan 0.014999999 ... 375'e kadar 0.02 mermi" demek istemiyoruz.

Burada sadece yerleşik olanı kullanabiliriz toFixed yöntem. Arayarak unutmayın Number() tarafından döndürülen dize toFixeddize temsili sıfırın sonuna sahip olmayan bir Sayı alırız (bu sayının başında daha önce tartışılan, bir Sayı'nın String gösterimini hesaplama şekli sayesinde).

/**
 * Takes a float and rounds it to at most dp decimal places. For example
 *
 *     roundFloatNumberWithoutTrailingZeroes(1.2345, 3)
 *
 * returns 1.234
 *
 * Note that since this treats the value passed to it as a floating point
 * number, it will have counterintuitive results in some cases. For instance,
 * 
 *     roundFloatNumberWithoutTrailingZeroes(0.015, 2)
 *
 * gives 0.01 where 0.02 might be expected. For an explanation of why, see
 * http://stackoverflow.com/a/38676273/1709587. You may want to consider using the
 * roundStringNumberWithoutTrailingZeroes function there instead.
 *
 * @param {number} num
 * @param {number} dp
 * @return {number}
 */
function roundFloatNumberWithoutTrailingZeroes (num, dp) {
    var numToFixedDp = Number(num).toFixed(dp);
    return Number(numToFixedDp);
}

53
2017-07-30 16:47



Bu bazı durumlarda işe yaramıyor:jsfiddle) ile roundStringNumberWithoutTrailingZeroes(362.42499999999995, 2). Beklenen sonuç (PHP’de olduğu gibi echo round(362.42499999999995, 2)): 362.43. Gerçek sonuç: 362.42 - Dr. Gianluigi Zane Zanettini
@ Dr.GianluigiZaneZanettini Huh. Tuhaf. Eminim neden PHP'nin round 362.43 verir. Bu sezgisel olarak yanlış görünüyor, çünkü 362.42499999999995, 362.425'den daha az (matematik ve kod içinde) 362.42499999999995 < 362.425 hem JS hem de PHP'de geçerlidir. PHP'nin cevabı, orijinal ve yuvarlak kayan nokta sayıları arasındaki mesafeyi en aza indirir. 362.43 - 362.42499999999995 > 362.42499999999995 - 362.42. Göre php.net/manual/en/function.round.php, PHP round C99 standardını takip eder; Neler olduğunu anlamak için C topraklarına girmem gerekecek. - Mark Amery
Baktıktan sonra PHP'nin kaynağında yuvarlamanın uygulanmasıNe yaptığı hakkında hiçbir fikrim yok. Makrolar ve dallar ve dizi dönüşümleri ile dolu ve zor kodlanmış sihirli hassasiyet değerlerinde dallanma ile korkunç derecede karmaşık bir uygulama. "PHP'nin cevabı bariz bir şekilde yanlıştır ve bir hata raporu vermeliyiz" diyebileceğinden emin değilim. Bu arada, 362.42499999999995 numarasını nasıl buldunuz? - Mark Amery
@ Dr.GianluigiZaneZanettini Bir hata raporu oluşturdum: bugs.php.net/bug.php?id=75644 - Mark Amery
Aslında PHP'nin doğru olduğunu düşündüm, çünkü 362.42499999999995 "5" ile biter, bu yüzden sayı "aşağı" değil "yukarı" gitmelidir. Hiç mantıklı mıyım? Çabalarınız için şimdiden teşekkürler! Bir fiyata% indirim uygulayan numarayı buldum. - Dr. Gianluigi Zane Zanettini


Düşünmek .toFixed() ve .toPrecision():

http://www.javascriptkit.com/javatutors/formatnumber.shtml


51
2017-08-06 17:21



toFixed, ondalık noktaları ne olursa olsun her değere ekler. - stinkycheeseman
Her ikisi de burada işe yaramaz - Esailija
Ne yazık ki, her iki işlev de @stinkycheeseman'ın istemediği görünen fazladan ondalık basamaklar ekleyecektir. - jackwanders
stackoverflow.com/questions/566564/... - Shreedhar
dizeleri döndürürler ve sayıları değil, yani biçimlendiriyorlar ve hesaplamıyorlar. - saimiris_devel