सवाल अधिकतर 2 दशमलव स्थानों पर गोल करें (केवल तभी आवश्यक हो)


मैं अधिकतर 2 दशमलव स्थानों पर गोल करना चाहता हूं, लेकिन केवल अगर आवश्यक हो

इनपुट:

10
1.7777777
9.1

आउटपुट:

10
1.78
9.1

मैं इसे कैसे कर सकता हूं JavaScript?


1845
2017-08-06 17:17


मूल


मैंने समाधान के रूप में पेश की जाने वाली कई तकनीकों के साथ एक बेवकूफ़ बना दिया ... ताकि आप तुलना कर सकें: बेला - dsdsdsdsd
किसी को भी पता नहीं है Number.EPSILON। उपयोग Math.round( num * 100 + Number.EPSILON ) / 100। - cronvel
नए पाठकों के लिए, आप यह नहीं कर सकते हैं जब तक आपके पास स्ट्रिंग प्रकार का नतीजा न हो। संख्याओं के द्विआधारी आंतरिक प्रतिनिधित्व पर फ़्लोटिंग पॉइंट गणित का अर्थ है हमेशा संख्याएं जिन्हें साफ दशमलव के रूप में प्रदर्शित नहीं किया जा सकता है। - Walf


जवाब:


उपयोग Math.round(num * 100) / 100


2292
2017-08-06 17:20



हालांकि यह ज्यादातर मामलों के लिए काम करेगा, यह 1.005 के लिए काम नहीं करेगा जो 1.01 के बजाय 1 होने वाला होगा - James
@ जेम्स वाह यह वास्तव में अजीब है- मैं क्रोम देव कंसोल में काम कर रहा हूं और मैं देख रहा हूं कि 1.005 * 100 = 100.4 99 99 99 99 99 999। Math.round (100.4 99 99 99 99 99 999) 100 का मूल्यांकन करता है, जबकि Math.round (100.5) 101 का मूल्यांकन करता है। IE9 वही काम करता है। इसका कारण है जावास्क्रिप्ट में अस्थायी बिंदु अजीबता - stinkycheeseman
एक सरल कामकाज। 2 डीपी के लिए, उपयोग करें Math.round((num + 0.00001) * 100) / 100। प्रयत्न Math.round((1.005 + 0.00001) * 100) / 100 तथा Math.round((1.0049 + 0.00001) * 100) / 100 - mrkschan
@mrkschan वह काम क्यों करता है, और यह सभी संख्याओं के लिए मूर्खतापूर्ण है? - CMCDragonkai
आप में से उन लोगों के लिए जो इसे प्राप्त नहीं करते हैं, इस तकनीक को स्केलिंग कहा जाता है। मूल रूप से यहां क्या जवाब दिया जाता है, जो दशमलव आंकड़ों में दो आंकड़े लाता है, जिससे सभी पागल फ़्लोटिंग पॉइंट मुद्दों से बचने के लिए आकृति को एक पूर्ण संख्या में बदल दिया जाता है, उसके बाद और उसके बाद इसे 100 से विभाजित करके पहले किया गया था और आपके पास 2 डीपी का जवाब। - Alex_Nabu


यदि मान एक टेक्स्ट प्रकार है:

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

यदि मान एक संख्या है:

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

एक नकारात्मक पक्ष है कि 1.5 जैसे मान आउटपुट के रूप में "1.50" देंगे। @Minitech द्वारा सुझाए गए एक फिक्स:

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.

ऐसा प्रतीत होता है जैसे Math.round एक बेहतर समाधान है। लेकिन यह नहीं है! कुछ मामलों में यह होगा नहीं सही ढंग से दौर:

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

tofixed () भी होगा नहीं कुछ मामलों में सही ढंग से दौर (क्रोम v.55.0.2883.87 में परीक्षण)!

उदाहरण:

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.

मुझे लगता है, ऐसा इसलिए है क्योंकि 1.555 वास्तव में दृश्यों के पीछे 1.5549 99 4 9 की तरह कुछ है।

समाधान 1 आवश्यक गोलिंग एल्गोरिदम के साथ एक स्क्रिप्ट का उपयोग करना है, उदाहरण के लिए:

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

समाधान 2 फ्रंट एंड गणना से बचने और बैकएंड सर्वर से गोलाकार मूल्य खींचने के लिए है।


2327
2017-10-11 00:27



यह एक (टिक्स्ड) दृष्टिकोण अच्छा है, और मेरे लिए काम किया है, लेकिन यह विशेष रूप से करता है नहीं "केवल जब आवश्यक हो" के मूल अनुरोध का पालन करें। (यह 1.5 से 1.50 के आसपास है, जो spec तोड़ता है।) - Per Lundberg
"जब आवश्यक हो" आवश्यकता के लिए, यह करें: parseFloat(number.toFixed(decimalPlaces));   @PerLundberg - Onur Yıldırım
parseFloat("55.555").toFixed(2) रिटर्न "55.55" क्रोम देव कंसोल में। - Levi Botelho
Math.round के बजाय फ़िक्स्ड का उपयोग करने का कोई फायदा नहीं है; टूफिक्स्ड काफी गोल करने वाली समस्याओं की ओर जाता है (उन्हें 5.555 और 1.005 के साथ आज़माएं), लेकिन 500x (मजाक नहीं) की तरह गणित की तुलना में धीमी है ... लगता है कि @MarkG उत्तर यहां अधिक सटीक है। - Pierre
जेएस इतना अजीब क्यों है? - D.Deriso


आप उपयोग कर सकते हैं

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

मैंने इसे खत्म कर दिया MDN। उनका तरीका 1.005 के साथ समस्या से बचाता था उल्लेख किया

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) उपयोग करने के बराबर जबरदस्ती है Number(val)। एक संख्या में "ई-2" को संगत करने के परिणामस्वरूप एक स्ट्रिंग होती है जिसे किसी संख्या में परिवर्तित करने की आवश्यकता होती है। - Jack
सावधान रहें कि बड़े और छोटे फ्लोट्स जो नाएन का उत्पादन करेंगे, उदाहरण के लिए + "1e-21 + 2" को सही ढंग से पार्स नहीं किया जाएगा। - Pierre
आपने 1.005 'समस्या' हल की है, लेकिन एक नया परिचय दिया: अब, क्रोम कंसोल में, roundToTwo(1.0049999999999999) 1.01 के रूप में बाहर आता है (अनिवार्य रूप से, के बाद से 1.0049999999999999 == 1.005)। ऐसा लगता है कि अगर आप टाइप करते हैं तो आपको फ्लोट मिलता है num = 1.005 'स्पष्ट रूप से' 'होना चाहिए' 1.00 के आसपास, क्योंकि संख्या का सटीक मान 1.005 से कम है। बेशक, यह भी मुझे लगता है कि स्ट्रिंग '1.005' 'स्पष्ट रूप से' 'होना चाहिए' को 1.01 तक गोल किया जाना चाहिए। तथ्य यह है कि विभिन्न लोगों के पास वास्तविक अंतर्ज्ञान के बारे में अलग-अलग अंतर्ज्ञान हैं, यह वास्तव में जटिल क्यों है इसका एक हिस्सा है। - Mark Amery
बीच में कोई (फ़्लोटिंग पॉइंट) संख्या नहीं है 1.0049999999999999 तथा 1.005, इसलिए परिभाषा के अनुसार, वे एक ही संख्या हैं। इसे एक dedekind कट कहा जाता है। - Azmisov
@Azmisov सही है। जबकि 1.00499 < 1.005 है true, 1.0049999999999999 < 1.005 का मूल्यांकन false। - falconepl


मार्कजी का जवाब सही है। यहां दशमलव स्थानों की किसी भी संख्या के लिए एक सामान्य विस्तार है।

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

उपयोग:

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

अध्याय परीक्षा:

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



पियरे ने मार्कजी के जवाब के साथ एक गंभीर मुद्दा उठाया। - dsjoerg
नोट: यदि आप Number.prototype को बदलना नहीं चाहते हैं - बस इसे फ़ंक्शन के रूप में लिखें: function round(number, decimals) { return +(Math.round(number + "e+" + decimals) + "e-" + decimals); } - Philipp Tsipman
मैंने बनाया Math.roundPlaces(num, places), ताकि यह तारों पर भी काम करेगा (बस मामले में)। - bradlis7
एन: 1e + 19 आज़माएं - यह NaN लौटाता है - DavidJ
यह एल्गोरिदम हमेशा गोल करता है (शून्य से दूर की बजाय)। इसलिए, नकारात्मक संख्याओं के मामले में, आउटपुट वह नहीं है जो आप उम्मीद कर सकते हैं: (-1.005).round(2) === -1 - Aleksej Komarov


कोई भी उपयोग कर सकते हैं .toFixed(NumberOfDecimalPlaces)

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

71
2017-10-21 17:02



यह शीर्ष जवाब क्यों नहीं है ??? (संपादित करें: ओह, क्योंकि यह एक स्ट्रिंग में बदल जाता है :) - Daniel
इसके अलावा क्योंकि यह पिछला शून्य जोड़ता है, जो है मूल प्रश्न के लिए क्या नहीं पूछा गया। - Alastair Maw
लेकिन पीछे की ओर शून्य को रेगेक्स के साथ आसानी से छीन लिया जाता है, यानी 'संख्या (10.10000.to फ़िक्स्ड (2)। जगह (/ 0 + $ /,' '))' => 10.1 - Chad McElligott
@ डैनियल द शीर्ष जवाब वही है (अभी तक) लेकिन यह नहीं है alsways सही ढंग से गोल करें, कोशिश करें +(1.005).toFixed(2) जो लौटता है 1 के बजाय 1.01। - Emile Bergeron
@ChadMcElligott: आपका regex पूर्णांक के साथ अच्छी तरह से काम नहीं करता है: Number(9).toFixed(2).replace(/0+$/, '') => "9।" - Jacob van Lingen


एक सटीक गोल विधि। स्रोत: मोज़िला

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

उदाहरण:

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



किसी ने इसे गिटहब और एनपीएम पर भी रखा है: github.com/jhohlfeld/round10 - Jo Liss
कूल और कामकाजी कोड। धन्यवाद @ त्रुटि। !! - Anahit DEV
नहीं, Math.round10(3544.5249, -2) 3544.53 के बजाय 3544.52 देता है - Matija
@Matija वोल्फरम अल्फा 3544.52 भी कहते हैं। आप वर्तमान संख्या और गोलाकार अनुमान के बीच त्रुटि को कम करना चाहते हैं। निकटतम अनुमान 3544.5249 2 दशमलव स्थानों पर है 3544.52 (त्रुटि = 0.0049)। अगर वह वैसा होता 3544.53, त्रुटि 0.0051 होगी। आप लगातार दौर कर रहे हैं यानी Math.round10 (Math.round10 (3544.5249, -3), -2) जो एक बड़ी गोल त्रुटि देता है और इसलिए वांछनीय नहीं है। - user
@ मतिजा, गणितीय दृष्टिकोण से, 3544.524 9 गोलाकार 3544.52 है, 3544.53 नहीं, इसलिए यह कोड सही है। यदि आप इसे 3544.53 तक गोल करना चाहते हैं और इस तरह के मामलों (यहां तक ​​कि कठिन भी गलत है), ऐसा कुछ करें: number += 0.00011 - Bozidar Sikanjic


यहां पाए गए उत्तरों में से कोई भी सही नहीं है। @stinkycheeseman से पूछा बढ़ाना, आप सभी ने संख्या को गोल किया।

गोल करने के लिए, इसका उपयोग करें:

Math.ceil(num * 100)/100;

53
2018-06-13 09:35



उदाहरण इनपुट और आउटपुट दिखाता है कि हालांकि सवाल ने कहा कि 'राउंड अप ...' वास्तव में इसे 'राउंड टू ...' होना था। - JayDM
@stinkycheeseman एक विशिष्ट मामले में एक त्रुटि को इंगित कर रहा था, वह हमेशा छत के रूप में गोल नहीं करना चाहता था, वह सिर्फ 0.005 से 0.01 तक बढ़ना चाहता था - mjaggard
परीक्षण करते समय अजीब बग मिला Math.ceil(1.1 * 100)/100; रिटर्न 1.11, क्योंकि 1.1 * 100 है 110.00000000000001 ब्रांड के नए आधुनिक ब्राउज़र फ़ायरफ़ॉक्स, क्रोम, सफारी और ओपेरा के मुताबिक ... पुराने फैशन में आईई अभी भी सोचता है 1.1*100=1100। - skobaljic
@skobaljic कोशिश करो Math.ceil(num.toFixed(4) * 100) / 100 - treeface
@treeface Math.ceil((1.1).toFixed(4) * 100) / 100 वापस आ जाएगा 1.11 फ़ायरफ़ॉक्स में, आधुनिक ब्राउज़र समस्या / बग गुणा के साथ है और लोगों को इसके बारे में पता होना चाहिए (मैंने उदाहरण के लिए उस समय लॉटरी गेम पर काम किया था)। - skobaljic


यह सवाल जटिल है।

मान लें कि हमारे पास एक कार्य है, roundTo2DP(num), जो एक तर्क के रूप में एक फ्लोट लेता है और 2 दशमलव स्थानों के लिए एक मान देता है। इन अभिव्यक्तियों में से प्रत्येक का मूल्यांकन क्या होना चाहिए?

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

'स्पष्ट' उत्तर यह है कि पहला उदाहरण 0.01 तक होना चाहिए (क्योंकि यह 0.02 से 0.02 के करीब है) जबकि अन्य दो को 0.02 तक गोल करना चाहिए (क्योंकि 0.0150000000000000001 0.01 से 0.02 के करीब है, और क्योंकि 0.015 बिल्कुल आधे रास्ते के बीच है उन्हें और एक गणितीय सम्मेलन है कि इस तरह के नंबर गोलाकार हो जाते हैं)।

पकड़, जिसे आपने अनुमान लगाया हो, वह है roundTo2DP  संभवतः नहीं कर सकता उन स्पष्ट उत्तरों को देने के लिए लागू किया जाना चाहिए, क्योंकि इन तीनों संख्याओं को पास किया गया है वही संख्या। आईईईई 754 द्विआधारी फ्लोटिंग पॉइंट नंबर (जावास्क्रिप्ट द्वारा उपयोग की जाने वाली तरह) वास्तव में अधिकांश गैर-पूर्णांक संख्याओं का प्रतिनिधित्व नहीं कर सकता है, और इसलिए उपरोक्त सभी तीन अंकीय लिपिक पास के वैध फ़्लोटिंग पॉइंट नंबर पर गोल हो जाते हैं। यह संख्या, जैसा कि होता है, है ठीक ठीक

0,01499999999999999944488848768742172978818416595458984375

जो 0.01 से 0.02 के करीब है।

आप देख सकते हैं कि सभी तीन नंबर आपके ब्राउज़र कंसोल, नोड शैल, या अन्य जावास्क्रिप्ट दुभाषिया पर समान हैं। बस उनकी तुलना करें:

> 0.0149 99 99 99 99 99 99 99 === 0.0150000000000000001
true

तो जब मैं लिखता हूँ m = 0.0150000000000000001, द का सटीक मूल्य mकि मैं खत्म होने के करीब है 0.01 इसकी तुलना में है 0.02। और फिर भी, अगर मैं कन्वर्ट करता हूं m एक स्ट्रिंग के लिए ...

> var m = 0.0150000000000000001;
> console.log (स्ट्रिंग (एम));
0.015
> var m = 0.014999999999999999;
> console.log (स्ट्रिंग (एम));
0.015

... मुझे 0.015 मिलते हैं, जो 0.02 तक गोल होना चाहिए, और जो ध्यान से है नहीं 56-दशमलव-स्थान संख्या मैंने पहले कहा था कि ये सभी संख्या बिल्कुल बराबर थीं। तो यह क्या अंधेरा जादू है?

उत्तर अनुभाग में ईसीएमएस्क्रिप्ट विनिर्देश में पाया जा सकता है 7.1.12.1: संख्या प्रकार पर लागू करने के लिए ToString। यहां कुछ संख्या बदलने के नियम हैं मीटर एक स्ट्रिंग को रखा गया है। मुख्य भाग बिंदु 5 है, जिसमें एक पूर्णांक है रों उत्पन्न होता है जिसका अंक स्ट्रिंग प्रतिनिधित्व में उपयोग किया जाएगा मीटर:

चलो n, कश्मीर, तथा रों ऐसे पूर्णांक बनें कश्मीर ≥ 1, 10कश्मीर-1 ≤ रों <10कश्मीर, के लिए संख्या मूल्य रों × 10n-कश्मीर है मीटर, तथा कश्मीर जितना संभव हो उतना छोटा है। ध्यान दें कि के दशमलव प्रतिनिधित्व में अंकों की संख्या है रों, उस रों 10 से विभाजित नहीं है, और यह कि कम से कम महत्वपूर्ण अंक है रों इन मानदंडों द्वारा अनिवार्य रूप से निर्धारित नहीं है।

यहां महत्वपूर्ण हिस्सा यह है कि "कश्मीर जितना संभव हो उतना छोटा है "। उस आवश्यकता की मात्रा क्या है, एक संख्या दी गई है m, का मूल्य String(m) होना आवश्यक है अंकों की कम से कम संभव संख्या जबकि अभी भी आवश्यकता को पूरा करते हुए Number(String(m)) === m। चूंकि हम पहले से ही जानते हैं 0.015 === 0.0150000000000000001, अब यह स्पष्ट क्यों है String(0.0150000000000000001) === '0.015' सच होना चाहिए।

बेशक, इस चर्चा में से कोई भी सीधे जवाब नहीं दिया है roundTo2DP(m)  चाहिए वापसी। अगर mका सटीक मान 0.0149 99 99 99 99 99 99 9944488848768742172978818416595458984375 है, लेकिन इसका स्ट्रिंग प्रतिनिधित्व '0.015' है, तो फिर क्या है सही बात उत्तर - गणितीय, व्यावहारिक रूप से, दार्शनिक रूप से, या जो कुछ भी - जब हम इसे दो दशमलव स्थानों पर ले जाते हैं?

इसके लिए कोई भी सही जवाब नहीं है। यह आपके उपयोग के मामले पर निर्भर करता है। आप शायद स्ट्रिंग प्रतिनिधित्व और ऊपर की ओर सम्मान करना चाहते हैं जब:

  • प्रतिनिधित्व किया जा रहा मूल्य मूल रूप से अलग है, उदा। 3-दशमलव-स्थान मुद्रा में दीनार की तरह मुद्रा की मात्रा। इस मामले में, सच 0.015 जैसी संख्या का मान है 0.015, और 0.0149 99 99 99 ... प्रतिनिधित्व यह है कि यह बाइनरी फ्लोटिंग पॉइंट में मिलता है एक गोल त्रुटि है। (बेशक, कई तर्क देंगे, तर्कसंगत है कि आपको ऐसे मूल्यों को संभालने के लिए दशमलव पुस्तकालय का उपयोग करना चाहिए और उन्हें पहले स्थान पर बाइनरी फ़्लोटिंग पॉइंट नंबर के रूप में कभी भी प्रस्तुत नहीं करना चाहिए।)
  • मान उपयोगकर्ता द्वारा टाइप किया गया था। इस मामले में, फिर से, सही दशमलव संख्या दर्ज की गई निकटतम बाइनरी फ़्लोटिंग पॉइंट प्रस्तुति से अधिक 'सत्य' है।

दूसरी तरफ, आप संभवतः बाइनरी फ़्लोटिंग पॉइंट वैल्यू का सम्मान करना चाहते हैं और नीचे की ओर जब आपका मान एक अंतर्निहित निरंतर पैमाने से है - उदाहरण के लिए, यदि यह सेंसर से पढ़ रहा है।

इन दो दृष्टिकोणों के लिए अलग-अलग कोड की आवश्यकता होती है। संख्या के स्ट्रिंग प्रतिनिधित्व का सम्मान करने के लिए, हम अपने स्वयं के राउंडिंग को लागू कर सकते हैं जो स्ट्रिंग प्रस्तुति पर सीधे कार्य करता है, अंकों द्वारा अंक, उसी एल्गोरिदम का उपयोग करके, जब आप स्कूल में उपयोग करते थे संख्याओं को गोल करने के लिए सिखाया गया था। नीचे एक उदाहरण है जो दशमलव बिंदु के बाद पिछली ज़ीरो को अलग करके "केवल जब आवश्यक हो" की संख्या को 2 दशमलव स्थानों का प्रतिनिधित्व करने की ओपी की आवश्यकता का सम्मान करता है; आप निश्चित रूप से, इसे अपनी सटीक आवश्यकताओं के साथ बदलने की जरूरत हो सकती है।

/**
 * 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+$/, '')
}

उदाहरण का उपयोग:

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

उपरोक्त कार्य है शायद आप उपयोगकर्ताओं को उन संख्याओं को देखने से बचने के लिए क्या उपयोग करना चाहते हैं, जिन्हें उन्होंने गलत तरीके से गोल किया है।

(एक विकल्प के रूप में, आप भी कोशिश कर सकते हैं round10 लाइब्रेरी जो एक समान रूप से भिन्न कार्यान्वयन के साथ समान व्यवहार कार्य प्रदान करती है।)

लेकिन क्या होगा यदि आपके पास दूसरी तरह की संख्या है - एक निरंतर पैमाने से लिया गया मूल्य, जहां ऐसा सोचने का कोई कारण नहीं है कि कम दशमलव स्थानों के साथ अनुमानित दशमलव प्रतिनिधित्व अधिक हैं शुद्ध अधिक से अधिक की तुलना में? उस मामले में, हम नहीं स्ट्रिंग प्रतिनिधित्व का सम्मान करना चाहते हैं, क्योंकि उस प्रतिनिधित्व (जैसा कि spec में बताया गया है) पहले से ही गोलाकार है; हम "0.0149 99 999 ... 375 राउंड 0.015 तक की गलती नहीं करना चाहते हैं, जो 0.02 तक है, इसलिए 0.0149 99 999 ... 375 राउंड 0.02 तक"।

यहां हम बस अंतर्निहित उपयोग कर सकते हैं toFixed तरीका। ध्यान दें कि कॉल करके Number() स्ट्रिंग पर लौट आया toFixed, हमें एक संख्या मिलती है जिसका स्ट्रिंग प्रतिनिधित्व में कोई पिछला शून्य नहीं है (जावास्क्रिप्ट जिस तरह से इस नंबर में पहले चर्चा की गई संख्या के स्ट्रिंग प्रतिनिधित्व की गणना करता है)।

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



यह कुछ किनारे के मामलों में काम नहीं करता है: कोशिश करें (jsfiddle) साथ में roundStringNumberWithoutTrailingZeroes(362.42499999999995, 2)। अपेक्षित परिणाम (जैसा कि PHP में है echo round(362.42499999999995, 2)): 362.43। वास्तविक परिणाम: 362.42 - Dr. Gianluigi Zane Zanettini
@ डॉ गियानुल्गीज़ेन जेननेटिनी हू। अजीब। मुझे यकीन नहीं है कि क्यों PHP है round 362.43 देता है। यह सहजता से गलत लगता है, क्योंकि 362.424 99 99 99 99 995 362.425 से कम है (गणित में और कोड में - 362.42499999999995 < 362.425 जेएस और PHP दोनों में सच है)। न ही PHP का उत्तर मूल और गोलाकार फ़्लोटिंग पॉइंट नंबरों के बीच की दूरी को कम करता है 362.43 - 362.42499999999995 > 362.42499999999995 - 362.42। इसके अनुसार php.net/manual/en/function.round.php, PHP है round सी 99 मानक का पालन करता है; क्या हो रहा है यह समझने के लिए मुझे सी की भूमि में प्रवेश करना होगा। - Mark Amery
देखने के बाद PHP के स्रोत में गोल करने के कार्यान्वयन, मुझे कोई डर नहीं है कि यह क्या कर रहा है। यह मैक्रोज़ और शाखाओं और स्ट्रिंग रूपांतरणों से भरा एक जटिल जटिल कार्यान्वयन है और हार्ड-कोडित जादू परिशुद्धता मानों पर ब्रांचिंग है। मुझे यकीन नहीं है कि "PHP का जवाब स्पष्ट रूप से गलत है, और हमें एक बग रिपोर्ट दर्ज करनी चाहिए" से परे क्या कहना है। आपको 362.424 99 99 99 99 99 5 नंबर कैसे मिला? - Mark Amery
@ डॉ। गियानुल्गीज़ेन जेननेटिनी मैंने एक बग रिपोर्ट बनाई है: bugs.php.net/bug.php?id=75644 - Mark Amery
मैंने वास्तव में सोचा कि PHP सही था, क्योंकि 362.424 99 99 99 99 995 "5" से समाप्त होता है, इसलिए संख्या "ऊपर", "डाउन" नहीं होनी चाहिए। क्या मुझे कोई समझ है? वैसे भी आपके प्रयासों के लिए धन्यवाद! मुझे मूल्य पर% छूट लागू करने वाला नंबर मिला। - Dr. Gianluigi Zane Zanettini


विचार करें .toFixed() तथा .toPrecision():

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


51
2017-08-06 17:21



toFixed दशमलव मान को हर मूल्य पर जोड़ता है चाहे कोई फर्क नहीं पड़ता। - stinkycheeseman
दोनों यहाँ बेकार हैं - Esailija
दुर्भाग्यवश, दोनों फ़ंक्शन अतिरिक्त दशमलव स्थान जोड़ देंगे जो @stinkycheeseman नहीं चाहते हैं। - jackwanders
stackoverflow.com/questions/566564/... - Shreedhar
वे तारों को वापस करते हैं और संख्या नहीं, इसलिए वे स्वरूपण कर रहे हैं और गणना नहीं कर रहे हैं .. - saimiris_devel


इसे करने का एक आसान तरीका यहां दिया गया है:

Math.round(value * 100) / 100

आप आगे बढ़ना चाहते हैं और यह आपके लिए ऐसा करने के लिए एक अलग कार्य कर सकते हैं हालांकि:

function roundToTwo(value) {
    return(Math.round(value * 100) / 100);
}

तो आप बस मूल्य में गुजरेंगे।

आप इसे दूसरे पैरामीटर जोड़कर किसी भी मनमानी संख्या के दशमलव तक पहुंचने के लिए बढ़ा सकते हैं।

function myRound(value, places) {
    var multiplier = Math.pow(10, places);

    return (Math.round(value * multiplier) / multiplier);
}

42
2017-08-06 17:27



यह होना चाहिए सबसे अधिक वोट दिया जवाब। - jose.angel.jimenez
यह समाधान गलत है, देखें stackoverflow.com/questions/38322372/... यदि आप 156893.145 इनपुट करते हैं और उपरोक्त फ़ंक्शन के साथ इसे गोल करते हैं तो आपको 156893.15 के बजाय 156893.14 मिलते हैं !!! - saimiris_devel