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


2756

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

इनपुट:

10
1.7777777
9.1

आउटपुट:

10
1.78
9.1

मैं जावास्क्रिप्ट में यह कैसे कर सकता हूं?


22
मैंने कई तकनीकों के साथ एक फिडल बनाया, जो यहां समाधान के रूप में प्रस्तुत किया गया है ... इसलिए आप तुलना कर सकते हैं: फिडल
dsdsdsdsd

37
किसी को भनक तक नहीं लगती है Number.EPSILON। का उपयोग करें Math.round( num * 100 + Number.EPSILON ) / 100
cronvel

3
नए पाठकों के लिए, आप ऐसा नहीं कर सकते जब तक कि आपके पास एक स्ट्रिंग प्रकार का परिणाम न हो । संख्याओं के द्विआधारी आंतरिक अभ्यावेदन पर फ्लोटिंग पॉइंट मैथ्स का मतलब है कि हमेशा संख्याएँ होती हैं जिन्हें स्वच्छ दशमलव के रूप में प्रस्तुत नहीं किया जा सकता है।
वॉल्फ

9
@ क्रोनवेल क्या आप Number.EPSILONयहाँ उपयोग करने का कारण बता सकते हैं?
ब्रूस सन

5
मैं खरगोश के छेद के नीचे गिर गया और इस पृष्ठ (पहले पृष्ठ पर) पर कुछ और दिलचस्प जवाबों का परीक्षण किया। यहाँ एक कोडपेन है । संकेत: उत्तर में जितना अधिक उत्थान होता है, उतने कम होते हैं कि यह ठीक से काम करता है।
एडम जगोस

जवाबों:


3488

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

संपादित करें: 1.005 राउंड जैसी चीजों को सही ढंग से सुनिश्चित करने के लिए, हम उपयोग करते हैं

Math.round((num + Number.EPSILON) * 100) / 100


395
जबकि यह ज्यादातर मामलों के लिए काम करेगा, यह 1.005 के लिए काम नहीं करेगा जो कि अंत में 1.01 के बजाय 1 हो जाएगा
जेम्स

83
@ जेम्स वॉव यह वास्तव में अजीब है- मैं क्रोम देव कंसोल में काम कर रहा हूं और मैं 1.005 * 100 = 100.49999999999999 पर ध्यान दे रहा हूं। Math.round (100.49999999999999) 100 का मूल्यांकन करता है, जबकि Math.round (100.5) 101 का मूल्यांकन करता है। IE9 एक ही काम करता है। यह जावास्क्रिप्ट में फ्लोटिंग पॉइंट विचित्रता के
स्टिंकसाइज़मैन

153
एक साधारण वर्कअराउंड। 2 डीपी के लिए, का उपयोग करें Math.round((num + 0.00001) * 100) / 100। कोशिश करो Math.round((1.005 + 0.00001) * 100) / 100औरMath.round((1.0049 + 0.00001) * 100) / 100
श्री

31
@mrkschan वह काम क्यों करता है, और क्या वह सभी संख्याओं के लिए मूर्ख है?
CMCDragonkai

86
आप में से जो इसे प्राप्त नहीं करते उनके लिए यह तकनीक स्केलिंग कहलाती है। मूल रूप से यहाँ क्या उत्तर देता है, दशमलव बिंदु के पार दो आंकड़े ला रहा है, सभी पागल फ़्लोटिंग पॉइंट मुद्दों से बचने के लिए एक पूरी संख्या में आंकड़ा बदल रहा है, उस दौर में और फिर इसे वापस अनुवाद करें कि यह 100 से विभाजित होने से पहले क्या था और आपके पास है 2dp का जवाब।
Alex_Nabu

3060

यदि मान एक पाठ प्रकार है:

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.55499994 पर्दे के पीछे।

समाधान 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

नोट: यह सभी के लिए एक सार्वभौमिक समाधान नहीं है। कई अलग-अलग राउंडिंग एल्गोरिदम हैं, आपका कार्यान्वयन अलग हो सकता है, आपकी आवश्यकताओं पर निर्भर करता है। https://en.wikipedia.org/wiki/Rounding

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


81
यह एक (toFixed) दृष्टिकोण अच्छा है, और मेरे लिए काम किया है, लेकिन यह विशेष रूप से "केवल आवश्यक होने पर" के मूल अनुरोध का अनुपालन नहीं करता है । (यह 1.5 से 1.50 तक गोल होता है, जो कल्पना को तोड़ता है।)
प्रति लुंडबर्ग

29
: "जब आवश्यक" आवश्यकता के लिए, यह करने के parseFloat(number.toFixed(decimalPlaces)); @PerLundberg
ओनुर Yıldırım

36
parseFloat("55.555").toFixed(2)"55.55"क्रोम देव कंसोल में रिटर्न ।
लेवी मोटेलो

22
Math.round की जगह ofFixed का उपयोग करने का कोई फायदा नहीं है; TheFixed काफी समान समस्याओं की ओर जाता है (उन्हें 5.555 और 1.005 के साथ आज़माएं), लेकिन Math.round की तुलना में 500x (कोई मजाक नहीं) धीमा है ... @MarkG उत्तर की तरह लगता है कि यहां अधिक सटीक है।
पियरे

17
.Fixed स्ट्रिंग को "कभी-कभी" वापस नहीं करता है, यह हमेशा एक स्ट्रिंग लौटाता है।
McGuireV10

464

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

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

मुझे एमडीएन पर यह मिला । उनका रास्ता उस समस्या से बचा हुआ था जिसका उल्लेख 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

13
@Redsandro, +(val)उपयोग के समतुल्य समान है Number(val)। "ई -2" को एक संख्या से जोड़ने पर एक स्ट्रिंग उत्पन्न हुई जिसे वापस एक संख्या में परिवर्तित करने की आवश्यकता थी।
जैक

41
खबरदार कि बड़े और छोटे झंडे के लिए जो NaN का उत्पादन करेगा, जैसे कि + "1e-21 + 2" सही ढंग से पार्स नहीं होगा।
पियरे

16
आपने '1.005' समस्या का 'हल' कर लिया है, लेकिन एक नया परिचय दिया: अब, क्रोम कंसोल में, roundToTwo(1.0049999999999999)1.01 (अनिवार्य रूप से, तब 1.0049999999999999 == 1.005) के रूप में सामने आता है । यह मुझे प्रतीत होता है कि यदि आप num = 1.005'जाहिर है' टाइप करते हैं तो आपको मिलने वाला फ्लोट 1.00 पर होना चाहिए, क्योंकि संख्या का सही मान 1.005 से कम है। निश्चित रूप से, यह मुझे भी लगता है कि स्ट्रिंग '1.005' 'जाहिर है' को 1.01 पर गोल किया जाना चाहिए। यह तथ्य कि अलग-अलग लोगों को यह प्रतीत होता है कि वास्तविक सही व्यवहार क्या है, इसके बारे में अलग-अलग अंतर्ज्ञान हैं, यह जटिल क्यों है।
मार्क अमेरी

35
बीच में 1.0049999999999999और (कोई फ्लोटिंग पॉइंट) संख्या नहीं है 1.005, इसलिए परिभाषा के अनुसार, वे एक ही संख्या हैं। इसे डिडेकइंड कट कहा जाता है।
अज्मिसोव

6
@Azmisov सही है। जबकि 1.00499 < 1.005यह है true, 1.0049999999999999 < 1.005के लिए मूल्यांकन करता है false
बाज़

146

मार्कग का उत्तर सही है। यहां किसी भी दशमलव स्थान के लिए एक सामान्य एक्सटेंशन दिया गया है।

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

20
पियरे ने मार्कग के जवाब के साथ एक गंभीर मुद्दा उठाया।
dsjoerg

9
नोट: यदि आप संख्या को बदलना नहीं चाहते हैं। प्रोटोटाइप - बस इसे एक फ़ंक्शन के रूप में लिखें:function round(number, decimals) { return +(Math.round(number + "e+" + decimals) + "e-" + decimals); }
फिलिप सिपमैन

2
इसका विस्तार करने का एक अच्छा तरीका। आप देख सकते हैं कि यदि दशमलव नकारात्मक है तो e + और e- को उल्टा कर दें। फिर एन = 115; n.round (-2); 100 उत्पादन करेगा
ली लौविरे

3
N की कोशिश करें: 1e + 19 - यह NaN
DavidJ

3
यह एल्गोरिथ्म हमेशा गोल होता है (बजाय शून्य से दूर)। तो, नकारात्मक संख्या के मामले में, आउटपुट वह नहीं है जो आप उम्मीद कर सकते हैं:(-1.005).round(2) === -1
Aleksej Komarov

123

आपको उपयोग करना चाहिए:

Math.round( num * 100 + Number.EPSILON ) / 100

किसी को भनक तक नहीं लगती है Number.EPSILON

यह भी ध्यान देने योग्य है कि यह जावास्क्रिप्ट विचित्रता नहीं है जैसा कि कुछ लोगों ने कहा है।

यह बस एक कंप्यूटर में फ्लोटिंग पॉइंट नंबर काम करने का तरीका है। 99% प्रोग्रामिंग लैंग्वेज की तरह, जावास्क्रिप्ट में होम मेड फ़्लोटिंग पॉइंट नंबर नहीं हैं; यह उसके लिए सीपीयू / एफपीयू पर निर्भर करता है। एक कंप्यूटर बाइनरी का उपयोग करता है, और बाइनरी में, कोई संख्या पसंद नहीं है 0.1, लेकिन उसके लिए एक मात्र बाइनरी सन्निकटन है। क्यों? उसी कारण से 1/3 को दशमलव में नहीं लिखा जा सकता है: इसका मूल्य 0.33333333 है ... जो अनंत के साथ है।

यहाँ आते हैं Number.EPSILON। वह संख्या 1 और अगले के बीच का अंतर है डबल सटीक फ़्लोटिंग पॉइंट संख्या में मौजूद नंबर के । वह यह है: 11 और + के बीच कोई संख्या नहीं है Number.EPSILON

संपादित करें:

जैसा कि टिप्पणियों में पूछा गया है, चलो एक बात स्पष्ट करें: जोड़ना Number.EPSILONकेवल तभी प्रासंगिक है जब गोल करने का मूल्य एक अंकगणितीय ऑपरेशन का परिणाम है, क्योंकि यह कुछ अस्थायी बिंदु त्रुटि डेल्टा को निगल सकता है।

यह तब उपयोगी नहीं है जब मूल्य एक प्रत्यक्ष स्रोत (जैसे: शाब्दिक, उपयोगकर्ता इनपुट या सेंसर) से आता है।

EDIT (2019):

जैसे @ मगनप और कुछ लोगों ने बताया है, इसे जोड़ना सबसे अच्छा है Number.EPSILON गुणा से पहले :

Math.round( ( num + Number.EPSILON ) * 100 ) / 100

EDIT (दिसंबर 2019):

हाल ही में, मैं एप्सिलॉन-अवेयर की संख्या की तुलना करने के लिए इसके समान एक फ़ंक्शन का उपयोग करता हूं:

const ESPILON_RATE = 1 + Number.EPSILON ;
const ESPILON_ZERO = Number.MIN_VALUE ;

function epsilonEquals( a , b ) {
  if ( Number.isNaN( a ) || Number.isNaN( b ) ) {
    return false ;
  }
  if ( a === 0 || b === 0 ) {
    return a <= b + EPSILON_ZERO && b <= a + EPSILON_ZERO ;
  }
  return a <= b * EPSILON_RATE && b <= a * EPSILON_RATE ;
}

मेरा उपयोग-मामला है एक जोर + डेटा सत्यापन कार्य है मैं कई वर्षों से विकसित कर रहा हूं।

वास्तव में, मैं जिस कोड का उपयोग कर रहा हूं ESPILON_RATE = 1 + 4 * Number.EPSILON और EPSILON_ZERO = 4 * Number.MIN_VALUE(एप्सिलॉन का चार गुना), क्योंकि मैं चाहता हूं कि समता चेकर फ्लोटिंग प्वाइंट एरर को कम करने के लिए पर्याप्त ढीला हो।

अब तक, यह मेरे लिए एकदम सही है। मुझे उम्मीद है इससे मदद मिलेगी।


1
@ तलोटा आप वास्तव में एक बड़ी संख्या को परिभाषित कर सकते हैं जैसे कि EPSILON क्रोनवेल उल्लेख कर रहे हैं
डैनियल सैन

3
यह सही जवाब है! समस्या स्वयं से जुड़ी है कि फ्लोट संख्या आंतरिक रूप से कैसे काम करती है, जावास्क्रिप्ट के बारे में नहीं
डैनियल सैन

22
दरअसल, आपको एप्सिलॉन BEFORE को 100 से गुणा करना होगा Math.round( (num + Number.EPSILON) * 100) / 100। मैं मानता हूं कि यह सही तरीके से गोलाई के लिए सही तरीका है (हालांकि यह बिल्कुल ऐसा नहीं है जो इस प्रश्न में पूछा गया था)।
मगनप

2
@ क्रोनवेल हम्म। आप सही हे; दिशा की पसंद करता है मेकअप भावना। इसलिए मुझे लगता है कि मेरी शेष आपत्ति सिर्फ इतनी है कि ऐसा करने से ही समझ में आता है यदि आप एक ऐसे डोमेन में काम कर रहे हैं जहाँ आपको यह सोचने के लिए एक राजसी कारण मिल गया है कि आपका मान एक "गोल संख्या" है। यदि आप जानते हैं कि आपका इनपुट दशमलव स्थानों की छोटी संख्या के साथ संख्याओं पर सरल अंकगणितीय परिचालनों का परिणाम है, तो निश्चित रूप से, आपके पास केवल 0.004999999999999999यौगिक फ्लोटिंग पॉइंट त्रुटि का परिणाम है और गणितीय रूप से सही परिणाम संभवतः 0.005 था। यदि यह सेंसर से रीडिंग है? इतना नहीं।
मार्क एमी

1
@marchaos यह विफल नहीं होता है: हाफ़वेज़ हमेशा गोल होते हैं । जैसे Math.round(1.5)= 2, लेकिन Math.round(-1.5)= -1। तो यह पूरी तरह से सुसंगत है। यहाँ -1 -2 से अधिक है, जैसे -1000, -1000.01 से अधिक है। अधिक से अधिक पूर्ण संख्याओं के साथ भ्रमित होने की नहीं ।
क्रोनवेल

84

एक का उपयोग कर सकते हैं .toFixed(NumberOfDecimalPlaces)

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

4
इसके अलावा, क्योंकि यह पीछे चल रहे शून्य को जोड़ता है, जो कि मूल प्रश्न के लिए नहीं पूछा गया है
एलिस्टेयर माव

2
लेकिन अनुगामी शून्य आसानी से एक रेगीक्स के साथ छीन लिया जाता है, यानी `नंबर (10.10000.toFixed (2) .replace (/ 0 + $ /, ''))` => 10.1
चाड

1
@daniel शीर्ष उत्तर एक ही है (अब के रूप में) लेकिन यह सही तरीके से राउंड अलाउ नहीं करता है, कोशिश करें +(1.005).toFixed(2)कि कौन सा 1बदले 1.01
एमिल बर्जरॉन

3
@ChadMcElligott: आपका रेगेक्स पूर्णांक के साथ अच्छी तरह से काम नहीं करता है: Number(9).toFixed(2).replace(/0+$/, '')=> "9."
जैकब वैन लिंगेन

ऐसा लगता है कि यह गोल नहीं है। यह सिर्फ मूल रूप से छोटा है। कुछ मामलों में, काफी अच्छी तरह से! धन्यवाद।
iedmrc

78

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

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

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

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

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

0,01499999999999999944488848768742172978818416595458984375

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

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

> 0.014999999999999999 === 0.0150000000000000001
true

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

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

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

इसका जवाब ECMAScript विनिर्देशन में पाया जा सकता है, जो 7.1 7.1.1 खंड में है : संख्या प्रकार पर लागू किया गया । यहां कुछ नंबर मी को एक स्ट्रिंग में बदलने के नियम निर्धारित किए गए हैं। प्रमुख भाग बिंदु 5 है, जिसमें एक पूर्णांक s उत्पन्न होता है, जिसका अंक m के स्ट्रिंग प्रतिनिधित्व में उपयोग किया जाएगा :

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

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

बेशक, इस चर्चा में से किसी ने भी सीधे जवाब नहीं दिया कि क्या लौटना roundTo2DP(m) चाहिए । यदि इसका mसटीक मान 0.01499999999999999444888487687421729788184165958984375 है, लेकिन इसका स्ट्रिंग प्रतिनिधित्व '0.015' है, तो सही क्या है उत्तर - गणितीय, व्यावहारिक रूप से, दार्शनिक रूप से, या जो भी - जब हम इसे दो दशमलव स्थानों पर गोल करते हैं।

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

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

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

इन दो दृष्टिकोणों को अलग-अलग कोड की आवश्यकता होती है। संख्या के स्ट्रिंग प्रतिनिधित्व का सम्मान करने के लिए, हम अपने स्वयं के गोलाई को काफी हद तक लागू कर सकते हैं (जो कि हमारे अपने राउंडिंग को लागू करते हैं, जो सीधे स्ट्रिंग प्रतिनिधित्व, अंकों के आधार पर कार्य करता है, उसी एल्गोरिदम का उपयोग करके जब आप स्कूल में उपयोग करते थे। संख्याओं को गोल करने का तरीका सिखाया गया। नीचे एक उदाहरण दिया गया है, जो ओपी को दशमलव बिंदु के बाद ट्रेलिंग जीरो को छीनकर "केवल आवश्यक होने पर" 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'

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

(एक विकल्प के रूप में, आप राउंड 10 लाइब्रेरी की भी कोशिश कर सकते हैं जो एक समान रूप से अलग-अलग कार्यान्वयन के साथ व्यवहार करने वाला फ़ंक्शन प्रदान करता है।)

लेकिन क्या होगा यदि आपके पास दूसरे प्रकार की संख्या है - एक निरंतर पैमाने से लिया गया मूल्य, जहां यह सोचने का कोई कारण नहीं है कि कम दशमलव स्थानों के साथ अनुमानित दशमलव अभ्यावेदन उन लोगों की तुलना में अधिक सटीक हैं जो अधिक हैं? उस स्थिति में, हम स्ट्रिंग प्रतिनिधित्व का सम्मान नहीं करना चाहते हैं, क्योंकि यह प्रतिनिधित्व (जैसा कि समझाया गया है) पहले से ही क्रमबद्ध है; हम "0.014999999 ... 375 राउंड 0.015 तक, जो 0.02 तक राउंड करते हैं, इसलिए 0.014999999 ... 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);
}

यह कुछ बढ़त के मामलों में काम नहीं करता है: ( jsfiddle ) के साथ प्रयास करें roundStringNumberWithoutTrailingZeroes(362.42499999999995, 2)। अपेक्षित परिणाम (PHP में echo round(362.42499999999995, 2)) 362.43:। वास्तविक परिणाम:362.42
डॉ। जियानलुइगी ज़ैन ज़ैनेटिनी

1
@ डॉ.गियानलुइगीज़ेनज़ानेटिनी हु। अजीब। मुझे यकीन नहीं है कि PHP round362.43 क्यों देता है। यह सहज रूप से गलत लगता है, क्योंकि 362.42499999999995 362.425 से कम है (गणित में और कोड में - 362.42499999999995 < 362.425जेएस और पीएचपी दोनों में सच है)। न ही PHP का उत्तर मूल और गोल अस्थायी बिंदु संख्याओं के बीच की दूरी को कम करता है 362.43 - 362.42499999999995 > 362.42499999999995 - 362.42Php.net/manual/en/function.round.php के अनुसार , PHP roundC99 मानक का अनुसरण करता है; मुझे यह समझने के लिए सी की भूमि में उद्यम करना होगा कि क्या हो रहा है।
मार्क अमेरी

1
PHP के स्रोत में गोलाई के कार्यान्वयन को देखने के बाद , मुझे कोई लानत सुराग नहीं है कि यह क्या कर रहा है। यह मैक्रोज़ और शाखाओं और स्ट्रिंग रूपांतरणों से भरा एक भयानक जटिल कार्यान्वयन है और हार्ड-कोडित जादू सटीक मूल्यों पर शाखा है। मुझे यकीन नहीं है कि "PHP के उत्तर को गलत तरीके से गलत बताया गया है, उससे आगे क्या कहना है, और हमें एक बग रिपोर्ट दर्ज करनी चाहिए"। वैसे आप 362.42499999999995 नंबर कैसे पाएंगे?
मार्क एमी

1
@ Dr.GianluigiZaneZanettini मैंने बग रिपोर्ट बनाई है: bugs.php.net/bug.php?id=75644
मार्क एमी

2
@ Dr.GianluigiZaneZanettini "क्या मुझे कोई मतलब है?" - नहीं; यह नहीं है कि गोलाई कैसे काम करती है। 1.000005 पाँच में समाप्त होता है, लेकिन अगर निकटतम पूर्णांक तक गोल किया जाए तो उत्तर 1 होना चाहिए। इसी तरह, पांच में 1499995 समाप्त होता है, लेकिन यदि निकटतम मिलियन में गोल किया जाता है, तो परिणाम 1000000 होना चाहिए, 2000000 नहीं। 362.42499999999995 के मामले में। 2 डीपी के लिए गोल किया जा रहा है, जिसे गोलाई दिशा का निर्धारण करना चाहिए तीसरा दशमलव स्थान है, जो कि 4 है।
मार्क एमी

76

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

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


1
TheFixed दशमलव बिंदुओं को हर मूल्य में जोड़ता है चाहे कोई भी हो।
stinkycheeseman

13
यहां दोनों बेकार हैं
एज़ेलिजा

दुर्भाग्य से, दोनों फ़ंक्शन अतिरिक्त दशमलव स्थानों को जोड़ देंगे जो @stinkycheeseman नहीं चाहते हैं।
जैकवंडर्स


2
वे तार वापस आते हैं और संख्या नहीं, इसलिए वे स्वरूपण कर रहे हैं और गणना नहीं कर रहे हैं ..
saimiris_devel

63

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

(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

किसी ने इसे GitHub और npm पर भी डाला: github.com/jhohlfeld/round10
Jo Liss

नहीं, Math.round10(3544.5249, -2)रिटर्न 3544.52 बजाय 3544.53
माटिजा

2
@ मतीजा वोल्फ्राम अल्फा 3544.52 भी कहती है। आप वर्तमान संख्या और गोलाकार सन्निकटन के बीच की त्रुटि को कम करना चाहते हैं। 3544.52492 दशमलव स्थानों का निकटतम सन्निकटन 3544.52(त्रुटि = 0.0049) है। यदि यह 3544.53होता है, तो त्रुटि 0.0051 होगी। आप लगातार राउंडिंग कर रहे हैं अर्थात Math.round10 (Math.round10 (3544.5249, -3), -2) जो एक बड़ी राउंडिंग त्रुटि देता है और इसलिए वांछनीय नहीं है।
उपयोगकर्ता

3
@ माटीजा, गणितीय दृष्टिकोण से, 3544.5249 गोल 3544.52 है, न कि 3544.53, इसलिए यह कोड सही है। यदि आप इसे इस में 3544.53 के लिए गोल करना चाहते हैं और इस तरह के मामले (यहां तक ​​कि कठिन भी गलत है), कुछ इस तरह से करें:number += 0.00011
Bozidar Sikanjic

@ मतिजा: मुझे लगता है कि फंक्शन उसी तरह काम करता है, जैसा उसे करना चाहिए। हो सकता है कि आप गोलाई को पुनरावृत्त करना चाहते हैं:Math.round10( Math.round10(3544.5249, -3) , -2)
जम्क्सोज़िज़ी

60

यहां पाया गया कोई भी उत्तर सही नहीं है । @stinkycheeseman ने राउंड अप करने के लिए कहा , आप सभी ने नंबर राउंड किया।

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

Math.ceil(num * 100)/100;

15
उदाहरण इनपुट और आउटपुट से पता चलता है कि हालांकि सवाल ने कहा कि 'राउंड अप ...' यह वास्तव में 'राउंड टू ...' होने का इरादा था।
JayDM

2
@stinkycheeseman एक विशिष्ट मामले में एक त्रुटि की ओर इशारा कर रहा था, वह हमेशा
छत के

9
अजीब बग मिला परीक्षण करते हुए Math.ceil(1.1 * 100)/100;इसे 'रिटर्न 1.11, क्योंकि 1.1 * 100 है 110.00000000000001ब्रांड के अनुसार नए आधुनिक ब्राउज़रों फ़ायरफ़ॉक्स, क्रोम, सफारी और ओपेरा ... आईई, पुराने फैशन में, अभी भी सोचता है 1.1*100=1100
skobaljic

1
@skobaljic कोशिशMath.ceil(num.toFixed(4) * 100) / 100
ट्रीफेस

1
@treeface फ़ायरफ़ॉक्स में Math.ceil((1.1).toFixed(4) * 100) / 100भी वापस आ जाएगा 1.11, आधुनिक ब्राउज़र समस्या / बग गुणा के साथ है और लोगों को इसके बारे में पता होना चाहिए (मैंने उदाहरण के लिए उस समय लॉटरी गेम पर काम किया था)।
स्कबलजिक

47

यहाँ यह करने के लिए एक सरल तरीका है:

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

2
यह समाधान गलत है, देखें stackoverflow.com/questions/38322372/… यदि आप 156893.145 इनपुट करते हैं और इसे उपरोक्त फ़ंक्शन के साथ राउंड करते हैं तो आपको 156893.15 के बजाय 156893.14 मिलता है !!!
सेमीरिस_डेवेल

2
@saimiris_devel, आप एक उदाहरण खोजने में कामयाब रहे हैं जहाँ जावास्क्रिप्ट में संख्याओं का संख्यात्मक निरूपण विफल रहता है। आप सही हैं कि यह गलत तरीके से राउंड करता है। लेकिन - ऐसा इसलिए है क्योंकि जब 100 से गुणा किया जाता है तो आपका नमूना नंबर पहले से ही टूट जाता है (15689314.499999998)। वास्तव में, एक पूरी तरह से चित्रित जवाब के लिए एक पुस्तकालय की आवश्यकता होगी जिसे विशेष रूप से वास्तविक संख्याओं के जावास्क्रिप्ट से निपटने में विसंगतियों को ध्यान में रखने के लिए विकसित किया गया है। अन्यथा, आप संभवतः इस प्रश्न के लिए दिए गए किसी भी उत्तर को अमान्य कर सकते हैं।
JayDM

36
+(10).toFixed(2); // = 10
+(10.12345).toFixed(2); // = 10.12

(10).toFixed(2); // = 10.00
(10.12345).toFixed(2); // = 10.12

1
यह हमेशा वही परिणाम नहीं देगा जो आपको मिलेगा अगर आपने अपने नंबर का स्ट्रिंग प्रतिनिधित्व लिया और इसे गोल किया। उदाहरण के लिए, +(0.015).toFixed(2) == 0.01
मार्क ऐमी

35

मेरे लिए Math.round () सही उत्तर नहीं दे रहा था। मैंने पाया कि बेहतर (2) बेहतर काम करता है। नीचे दोनों के उदाहरण दिए गए हैं:

console.log(Math.round(43000 / 80000) * 100); // wrong answer

console.log(((43000 / 80000) * 100).toFixed(2)); // correct answer


यह ध्यान रखना महत्वपूर्ण है कि toFixed एक राउंडिंग प्रदर्शन नहीं करता है, और यह कि Math.round केवल निकटतम पूर्ण संख्या में राउंड करता है। इसलिए दशमलव को संरक्षित करने के लिए हमें मूल संख्याओं को दस की शक्तियों की संख्या से गुणा करना होगा जिनके शून्य आपके वांछित संख्या को दशमलव का प्रतिनिधित्व करते हैं, और फिर परिणाम को उसी संख्या से विभाजित करते हैं। आपके मामले में: Math.round (43000/80000 * 100 * 100) / 100. अंतिम बार में (2) लागू किया जा सकता है ताकि यह सुनिश्चित किया जा सके कि परिणाम में हमेशा दो दशमलव (पीछे चल रहे शून्य के साथ) जहां जरूरत हो - सही दाएं-संरेखित करने के लिए संख्याओं की एक श्रृंखला खड़ी प्रस्तुत की गई :)
टर्बो

7
यह भी नोट करना महत्वपूर्ण है कि .toFIxed () एक स्ट्रिंग को आउटपुट करता है, न कि एक संख्या को।
कारपिडिएम

2
यह अभी भी के लिए गोलाई को हल नहीं करता है 1.005(1.005).toFixed(2)अभी भी परिणाम है 1.00
डीपीएसी

34

इस फ़ंक्शन का उपयोग करें Number(x).toFixed(2);


8
यह सब Numberफिर से लपेटें , यदि आप नहीं चाहते हैं कि यह एक स्ट्रिंग के रूप में लौटे:Number(Number(x).toFixed(2));

5
Numberकॉल आवश्यक नहीं है, x.toFixed(2)काम करता है।
16

3
@bgusach नंबर कॉल की आवश्यकता है, क्योंकि कथन x.toFixed (2) रिटर्न स्ट्रिंग और नंबर नहीं है। नंबर को फिर से बदलने के लिए हमें नंबर
मोहन राम

2
इस विधि का उपयोग करते समय (1).toFixed(2)रिटर्न 1.00, लेकिन प्रश्नकर्ता जरूरत 1इस मामले में।
यूजीन माला

1
यह काम नहीं करता है, जब यह होना चाहिए 1.005.toFixed(2)पैदावार । "1""1.01"
एडम जगोस

33

2017
बस देशी कोड का उपयोग करें.toFixed()

number = 1.2345;
number.toFixed(2) // "1.23"

अगर आपको सख्त होने की जरूरत है और जरूरत पड़ने पर अंकों को जोड़ सकते हैं replace

number = 1; // "1"
number.toFixed(5).replace(/\.?0*$/g,'');

3
TheFixed विधि एक स्ट्रिंग लौटाती है। यदि आप एक संख्या परिणाम चाहते हैं, तो आपको parFFloat को theFixed का परिणाम भेजना होगा।
ज़ाम्बोनिली

यदि आवश्यक हो तो @Zambonilli या सिर्फ 1 से गुणा करें। लेकिन क्योंकि निश्चित संख्या अधिकांश मामले प्रदर्शन के लिए हैं और गणना स्ट्रिंग के लिए नहीं सही प्रारूप है
पेरी मिमोन

2
-1; न केवल आपके toFixedद्वारा कई वर्षों पहले सुझाव दिया गया था , बल्कि यह प्रश्न में "केवल यदि आवश्यक हो" स्थिति को संतुष्ट करने में विफल रहता है; जहां वांछित वांछित (1).toFixed(2)दे देता है । "1.00""1"
मार्क ऐमी

ठीक मिल गया। मैं उस मामले के लिए कुछ समाधान भी
जोड़ता हूं

यदि आप लॉश का उपयोग कर रहे हैं, तो यह और भी आसान है: _.round (संख्या, दशमलव) मेरी अंतिम टिप्पणी हटा दी गई है, यह एक समस्या है। Lodash _.round DOES काम करता है, हालाँकि। 2 के दशमलव स्थान के साथ 1.005 1.01 में परिवर्तित होता है।
डेविन फील्ड्स

32

इस हल्के वजन समाधान का प्रयास करें :

function round(x, digits){
  return parseFloat(x.toFixed(digits))
}

 round(1.222,  2) ;
 // 1.22
 round(1.222, 10) ;
 // 1.222

किसी को पता है कि क्या इस और के बीच कोई अंतर है return Number(x.toFixed(digits))?

1
@JoeRocc ... कोई फर्क नहीं पड़ना चाहिए जहां तक ​​मैं देख सकता हूं क्योंकि .toFixed()केवल नंबर के लिए अनुमति देता है।
पीटरमेरिस

4
इस उत्तर में वही समस्या है जो इस पृष्ठ पर कई बार उल्लिखित है। प्रयास करें round(1.005, 2)और का एक परिणाम को देखने 1के बजाय 1.01
MilConDoin

गोलाई की समस्या अधिक लगती है? - एक से अधिक कल्पनाएं होंगी: en.wikipedia.org/wiki/Rounding ... round(0.995, 2) => 0.99; round(1.006, 2) => 1.01; round(1.005, 2) => 1
पेटीमिसर

31

ऐसा करने के कुछ तरीके हैं। मेरे जैसे लोगों के लिए, लोदाश का वैरिएंट

function round(number, precision) {
    var pair = (number + 'e').split('e')
    var value = Math.round(pair[0] + 'e' + (+pair[1] + precision))
    pair = (value + 'e').split('e')
    return +(pair[0] + 'e' + (+pair[1] - precision))
}

उपयोग:

round(0.015, 2) // 0.02
round(1.005, 2) // 1.01

यदि आपका प्रोजेक्ट jQuery या लॉश का उपयोग करता है, तो आप उचित भी पा सकते हैं round पुस्तकालयों में विधि ।

अपडेट १

मैंने वेरिएंट को हटा दिया n.toFixed(2), क्योंकि यह सही नहीं है। शुक्रिया @ avalanche1


दूसरा विकल्प ठीक दो दशमलव बिंदुओं के साथ एक स्ट्रिंग लौटाएगा। यदि आवश्यक हो तो प्रश्न केवल दशमलव अंक के लिए पूछता है। इस मामले में पहला विकल्प बेहतर है।
मार्कोस लीमा

@MarcosLima Number.toFixed()एक स्ट्रिंग लौटाएगा लेकिन इसके पहले एक प्लस प्रतीक के साथ, जेएस दुभाषिया स्ट्रिंग को एक संख्या में बदल देगा। यह एक वाक्य रचना चीनी है।
stanleyxu2005

फ़ायरफ़ॉक्स पर, alert((+1234).toFixed(2))"1234.00" दिखाता है।
मार्कोस लीमा

फ़ायरफ़ॉक्स पर, alert(+1234.toFixed(2))फेंकता है SyntaxError: identifier starts immediately after numeric literal। मैं 1 विकल्प के साथ रहना।
मार्कोस लीमा

यह कुछ बढ़त के मामलों में काम नहीं करता है: ( jsfiddle ) के साथ प्रयास करें 362.42499999999995। अपेक्षित परिणाम (PHP में echo round(362.42499999999995, 2)) 362.43:। वास्तविक परिणाम:362.42
डॉ। जियानलुइगी ज़ैन ज़ैनेटिनी

26

यदि आप लॉश लाइब्रेरी का उपयोग कर रहे हैं, तो आप निम्न की तरह राउंडैश की राउंड विधि का उपयोग कर सकते हैं।

_.round(number, precision)

उदाहरण के लिए:

_.round(1.7777777, 2) = 1.78

@Peter कार्यात्मकता का वह सेट जो लोदाश प्रदान करता है, मानक जावास्क्रिप्ट की तुलना में वास्तव में अच्छा है। हालाँकि, मैंने सुना है कि मानक JS की तुलना में Lodash के पास कुछ प्रदर्शन समस्या है। codeburst.io/…
मदुरा प्रदीप

1
मैं आपकी बात स्वीकार करता हूं कि लॉश का उपयोग करने के साथ प्रदर्शन कमियां हैं। मुझे लगता है कि वे मुद्दे बहुत से अमूर्त हैं। लेकिन जरा देखें कि इस धागे पर कितने उत्तर हैं और किनारे के मामलों के लिए सहज समाधान कैसे विफल हो जाते हैं। हमने इस पैटर्न को jQuery के साथ देखा है और जब ब्राउज़र ने एक सामान्य मानक अपनाया जो हमारे उपयोग के अधिकांश मामलों को हल करता है, तो रूट समस्या को हल किया गया था। प्रदर्शन बाधाओं को तब ब्राउज़र इंजन में स्थानांतरित कर दिया गया था। मुझे लगता है कि ऐसा ही होना चाहिए। :)
पीटर

26

ES6 के बाद से 'उचित' तरीका है (स्टैटिक्स को ओवरराइड किए बिना और वर्कअराउंड बनाए बिना)

var x = 1.49999999999;
console.log(x.toPrecision(4));
console.log(x.toPrecision(3));
console.log(x.toPrecision(2));

var y = Math.PI;
console.log(y.toPrecision(6));
console.log(y.toPrecision(5));
console.log(y.toPrecision(4));

var z = 222.987654
console.log(z.toPrecision(6));
console.log(z.toPrecision(5));
console.log(z.toPrecision(4));

तब आप बस parseFloatऔर शून्य 'दूर चले जाएंगे'।

console.log(parseFloat((1.4999).toPrecision(3)));
console.log(parseFloat((1.005).toPrecision(3)));
console.log(parseFloat((1.0051).toPrecision(3)));

हालांकि, यह '1.005 राउंडिंग समस्या' को हल नहीं करता है - क्योंकि यह आंतरिक है कि फ्लोट अंशों को कैसे संसाधित किया जा रहा है

console.log(1.005 - 0.005);

यदि आप पुस्तकालयों के लिए खुले हैं तो आप bignumber.js का उपयोग कर सकते हैं

console.log(1.005 - 0.005);
console.log(new BigNumber(1.005).minus(0.005));

console.log(new BigNumber(1.005).round(4));
console.log(new BigNumber(1.005).round(3));
console.log(new BigNumber(1.005).round(2));
console.log(new BigNumber(1.005).round(1));
<script src="https://cdnjs.cloudflare.com/ajax/libs/bignumber.js/2.3.0/bignumber.min.js"></script>


3
(1.005).toPrecision(3)अभी भी वास्तव में के 1.00बजाय रिटर्न 1.01
गियाकोमो

toPrecisionएक स्ट्रिंग देता है जो वांछित आउटपुट प्रकार को बदलता है।
adamduren

@ गियाकोमो यह .toPrecisionविधि का दोष नहीं है , यह फ्लोटिंग-पॉइंट नंबरों की एक विशिष्टता है (जेएस में कौन से नंबर हैं) - कोशिश करें 1.005 - 0.005, यह वापस आ जाएगी 0.9999999999999999
शौ-कोटे

1
(1).toPrecision(3)'1.00' देता है, लेकिन प्रश्नकर्ता 1इस मामले में आना चाहता था ।
यूजीन माला

1
जैसा कि @ गियाकोमो ने कहा, यह उत्तर "महत्वपूर्ण अंकों" को "दशमलव स्थानों की एक संख्या के लिए गोल" के साथ भ्रमित करने के लिए लगता है। toPrecisionप्रारूप, उत्तरार्द्ध नहीं, और ओपी के सवाल का जवाब नहीं है, हालांकि यह पहले प्रासंगिक लग सकता है यह बहुत गलत हो जाता है। En.wikipedia.org/wiki/Significant_figures देखें । उदाहरण के लिए Number(123.4).toPrecision(2)रिटर्न "1.2e+2"और Number(12.345).toPrecision(2)रिटर्न "12"। मैं @ adamduren की बात से भी सहमत हूँ कि यह एक स्ट्रिंग देता है जो वांछनीय नहीं है (एक बड़ी समस्या नहीं है लेकिन वांछनीय नहीं है)।
नेक जूल

23

MarkG और Lavamantis ने जो स्वीकार किया है, उससे कहीं बेहतर समाधान पेश किया। यह शर्म की बात है कि वे अधिक upvotes नहीं मिलता है!

यहाँ वह फ़ंक्शन है जिसका उपयोग मैं एमडीएन पर आधारित फ्लोटिंग पॉइंट डेसीमल के मुद्दों को हल करने के लिए करता हूँ । यह लैवमांटिस के समाधान की तुलना में अधिक सामान्य (लेकिन कम संक्षिप्त) है:

function round(value, exp) {
  if (typeof exp === 'undefined' || +exp === 0)
    return Math.round(value);

  value = +value;
  exp  = +exp;

  if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
    return NaN;

  // Shift
  value = value.toString().split('e');
  value = Math.round(+(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));
}

इसके साथ प्रयोग करें:

round(10.8034, 2);      // Returns 10.8
round(1.275, 2);        // Returns 1.28
round(1.27499, 2);      // Returns 1.27
round(1.2345678e+2, 2); // Returns 123.46

Lavamantis के समाधान की तुलना में, हम कर सकते हैं ...

round(1234.5678, -2); // Returns 1200
round("123.45");      // Returns 123

2
आपका समाधान MDN के समाधान के विपरीत कुछ मामलों को कवर नहीं करता है। जबकि यह छोटा हो सकता है, यह सटीक नहीं है ...
astorije

1
राउंड (-1835.665,2) => -1835.66
जॉर्ज सम्पैय जुएल

21

यह आपकी मदद कर सकता है:

var result = Math.round(input*100)/100;

अधिक जानकारी के लिए, आप इस लिंक पर एक नज़र डाल सकते हैं

Math.round (num) बनाम num.toFixed (0) और ब्राउज़र असंगतताएँ


1
दुनिया में क्यों स्वीकार किए गए उत्तर में इतने अधिक वोट हैं, क्योंकि वे व्यावहारिक रूप से एक ही चीज हैं, लेकिन इस एक को स्वीकृत एक मिनट बाद पोस्ट किया गया था?
Quote डेव

17

सबसे आसान तरीका नंबर फ़ंक्शन का उपयोग करके फ़िक्स्ड और फिर स्ट्रिप ट्रेलिंग शून्य का उपयोग करना होगा:

const number = 15.5;
Number(number.toFixed(2)); // 15.5
const number = 1.7777777;
Number(number.toFixed(2)); // 1.78

यह सभी मामलों के लिए काम नहीं करता है। उत्तर पोस्ट करने से पहले व्यापक परीक्षण करें।
बाबूराव

@ बाबूराव कृपया एक मामला पोस्ट करें जिसमें उपरोक्त समाधान काम नहीं करता है
Marcin Wanago

const संख्या = 15; संख्या (number.toFixed (2)); 15 के बजाय //15.00
केविन झंगियानी

1
@KevinJhangiani कास्ट संख्या = 15; संख्या (number.toFixed (2)); // 15 - मैंने इसे नवीनतम क्रोम और फ़ायरफ़ॉक्स
Marcin Wanago

@KevinJhangiani आपको कैसे मिला 15.00? जेएस में नंबर दशमलव स्थानों को संग्रहीत नहीं करते हैं और कोई भी प्रदर्शन स्वचालित रूप से अतिरिक्त दशमलव स्थानों (अंत में किसी भी शून्य) को काट देता है।
वीएलएजी

16
var roundUpto = function(number, upto){
    return Number(number.toFixed(upto));
}
roundUpto(0.1464676, 2);

toFixed(2) यहाँ 2 अंकों की संख्या है, जिसे हम इस संख्या को पूर्ण करना चाहते हैं।


यह .toFixed () लागू करने के लिए अधिक सरल है। बस एक बार इसके माध्यम से जाओ।
रितेश धूरी


14

सबसे आसान तरीका:

+num.toFixed(2)

यह इसे एक स्ट्रिंग में परिवर्तित करता है, और फिर एक पूर्णांक / फ्लोट में वापस आ जाता है।


इस सरल उत्तर के लिए धन्यवाद। हालांकि, + संख्या में '+' क्या है? यह मेरे लिए काम नहीं किया जहां दशमलव वैल स्ट्रिंग में आया था। मैंने किया: (संख्या * 1) .toFixed (2)।
एथन

@ मैमो ने तर्क को केवल 3 में बदल दिया toFixed()। इसलिए यह होगा +num.toFixed(3)। जिस तरह से यह माना जाता है, वह काम कर रहा है, 1.005 से 1.00 तक गोल है, जो 1 के बराबर है
बड़ा पोटा

1
@Edmund यह 1.01, 1.00 नहीं लौटने के लिए चाहिए था
mmm

13

यहाँ एक प्रोटोटाइप विधि है:

Number.prototype.round = function(places){
    places = Math.pow(10, places); 
    return Math.round(this * places)/places;
}

var yournum = 10.55555;
yournum = yournum.round(2);

13

कुछ इस तरह का उपयोग करें "parseFloat (parseFloat (मान)) .toFixed (2))"

parseFloat(parseFloat("1.7777777").toFixed(2))-->1.78 
parseFloat(parseFloat("10").toFixed(2))-->10 
parseFloat(parseFloat("9.1").toFixed(2))-->9.1

1
यदि अशुद्धि फ्लोट प्रतिनिधित्व के लिए आंतरिक नहीं है। आप बस इसे हटा देंगे और फिर से फ़्लोट में फिर से परिवर्तित करके उसी त्रुटि को फिर से प्रस्तुत करेंगे!
बेन मैकइंटायर

12

एक तरह से इस तरह के एक गोलाई प्राप्त करने के लिए केवल आवश्यक है, तो उपयोग करने के लिए है Number.prototype.toLocaleString () :

myNumber.toLocaleString('en', {maximumFractionDigits:2, useGrouping:false})

यह आपके द्वारा अपेक्षित उत्पादन प्रदान करेगा, लेकिन तार के रूप में। यदि आप डेटा प्रकार की अपेक्षा नहीं करते हैं, तो आप उन्हें वापस संख्या में बदल सकते हैं।


यह अब तक का सबसे साफ समाधान है और सभी जटिल फ़्लोटिंग पॉइंट मुद्दों को दरकिनार करता है, लेकिन एमडीएन समर्थन प्रति अभी भी अधूरा है - सफारी toLocaleStringअभी तक गुजरती तर्कों का समर्थन नहीं करता है।
मार्क एमी

@MarkAmery अभी के लिए, केवल Android ब्राउज़र में कुछ समस्याएँ हैं: caniuse.com/#search=toLocaleString
ptyskju

12

सही सटीक दशमलव गोलाई सटीकता प्राप्त करने के लिए सभी संभव तरीकों के विभिन्न पुनरावृत्तियों के माध्यम से चलने के बाद, यह स्पष्ट है कि नंबर का उपयोग करने के लिए सबसे सटीक और कुशल समाधान है। यह फ्लोटिंग पॉइंट गणित सटीक की समस्या का एक सही गणितीय समाधान प्रदान करता है। जैसा कि यहाँ दिखाया गया है, इसे आसानी से पॉलीफ़िल किया जा सकता है: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/EPSILON सभी शेष बचे IE उपयोगकर्ताओं का समर्थन करने के लिए (तब शायद हम फिर से करें। ऐसा करना बंद करना चाहिए)।

यहां दिए गए समाधान से अनुकूलित: https://stackoverflow.com/a/48850944/6910392

समाधान में एक सरल गिरावट जो सटीक लकीर के फ़र्श, फर्श और छत को प्रदान करती है, जिसमें पूरे पुस्तकालय को जोड़े बिना एक वैकल्पिक सटीक चर होता है।

अद्यतन: जैसा कि सर्गेई ने टिप्पणी में उल्लेख किया है, इस (या कोई) विधि के लिए एक सीमा है जो इंगित करने के लायक है। 0.014999999999999999 जैसे नंबरों के मामले में, आप अभी भी अशुद्धि का अनुभव करेंगे जो फ्लोटिंग पॉइंट वैल्यू स्टोरेज के लिए सटीकता सीमाओं के निरपेक्ष किनारे से टकराने का परिणाम है। कोई गणित या अन्य समाधान नहीं है जो उस के लिए खाते में लागू किया जा सकता है, क्योंकि मूल्य का तुरंत 0.015 के रूप में मूल्यांकन किया जाता है। आप केवल कंसोल में उस मान को लागू करके इसकी पुष्टि कर सकते हैं। इस सीमा के कारण, इस मूल्य को कम करने के लिए स्ट्रिंग हेरफेर का उपयोग करना भी संभव नहीं होगा, क्योंकि इसका स्ट्रिंग प्रतिनिधित्व केवल "0.015" है। इसके लिए किसी भी समाधान के लिए किसी स्क्रिप्ट में मूल्य को स्वीकार करने से पहले डेटा के स्रोत पर तार्किक रूप से लागू करने की आवश्यकता होगी,

var DecimalPrecision = (function(){
        if (Number.EPSILON === undefined) {
            Number.EPSILON = Math.pow(2, -52);
        }
        this.round = function(n, p=2){
            let r = 0.5 * Number.EPSILON * n;
            let o = 1; while(p-- > 0) o *= 10;
            if(n < 0)
                o *= -1;
            return Math.round((n + r) * o) / o;
        }
        this.ceil = function(n, p=2){
            let r = 0.5 * Number.EPSILON * n;
            let o = 1; while(p-- > 0) o *= 10;
            if(n < 0)
                o *= -1;
            return Math.ceil((n + r) * o) / o;
        }
        this.floor = function(n, p=2){
            let r = 0.5 * Number.EPSILON * n;
            let o = 1; while(p-- > 0) o *= 10;
            if(n < 0)
                o *= -1;
            return Math.floor((n + r) * o) / o;
        }
        return this;
    })();
    console.log(DecimalPrecision.round(1.005));
    console.log(DecimalPrecision.ceil(1.005));
    console.log(DecimalPrecision.floor(1.005));
    console.log(DecimalPrecision.round(1.0049999));
    console.log(DecimalPrecision.ceil(1.0049999));
    console.log(DecimalPrecision.floor(1.0049999));
    console.log(DecimalPrecision.round(2.175495134384,7));
    console.log(DecimalPrecision.round(2.1753543549,8));
    console.log(DecimalPrecision.round(2.1755465135353,4));


1
(दशमूलारिष्ट। घेर (0.014999999999999999, 2)) // रिटर्न 0.02
सर्गेई

अच्छी पकड़! समस्या जेएस में फ्लोटिंग पॉइंट स्टोरेज के साथ है, हमेशा कुछ एज केस होने वाले हैं। अच्छी खबर यह है कि जिस गणित को आप Number.EPSILON पर लागू करते हैं, पहले उन किनारे के मामलों को किनारे पर आगे बढ़ाने के लिए अधिक सूक्ष्मता से ट्यून किया जा सकता है। यदि आप किनारे के मामलों की कोई संभावना नहीं रखना चाहते हैं तो आपका एकमात्र वास्तविक समाधान स्ट्रिंग हेरफेर होने वाला है, और फिर गणित। जिस क्षण आप मूल्य पर कोई गणितीय गणना करते हैं (यहां तक ​​कि दशमलव को स्थानांतरित करने की कोशिश में), तो आप पहले ही बग का उत्पादन कर चुके हैं।
KFish

दरअसल, आगे के निरीक्षण पर, यह शामिल गणित के किसी भी कारण से नहीं है, बल्कि समस्या निर्दिष्ट मूल्य को लागू करने पर तुरंत प्रकट होती है। आप बस उस नंबर को कंसोल में लिखकर इसकी पुष्टि कर सकते हैं और देख सकते हैं कि यह तुरंत 0.015 का मूल्यांकन करता है। इसलिए, यह JS में किसी भी फ्लोटिंग पॉइंट नंबर के लिए सटीकता के निरपेक्ष किनारे का प्रतिनिधित्व करेगा। इस मामले में आप भी स्ट्रिंग के लिए परिवर्तित कर सकते हैं नहीं और हेरफेर के रूप में स्ट्रिंग मान "0.015" होगा
KFish

11

यह सबसे सरल, अधिक सुरुचिपूर्ण समाधान है (और मैं दुनिया में सबसे अच्छा हूं;):

function roundToX(num, X) {    
    return +(Math.round(num + "e+"+X)  + "e-"+X);
}
//roundToX(66.66666666,2) => 66.67
//roundToX(10,2) => 10
//roundToX(10.904,2) => 10.9

4
यह Eनोटेशन का उपयोग करके तर्क को स्वीकार करने के लिए स्वीकृत उत्तर को फिर से लिखने का एक अच्छा तरीका है।
एक्सलह

1
यह कुछ बढ़त के मामलों में काम नहीं करता है: कोशिश ( jsfiddle ) roundToX(362.42499999999995, 2)। अपेक्षित परिणाम (PHP में echo round(362.42499999999995, 2)) 362.43:। वास्तविक परिणाम:362.42
डॉ। Gianluigi Zane Zanettini

6
IMHO, आपका PHP परिणाम गलत है। तीसरे दशमलव के बाद कोई फर्क नहीं पड़ता है, यदि तीसरा दशमलव 5 से कम है, तो दूसरा दशमलव समान रहना चाहिए। यही गणितीय परिभाषा है।
सोल्डप्लाटा साकेतोस

1
अधिक संक्षिप्त होने के लिए "ई +" के बजाय केवल "ई" हो सकता है।
लोनी बेस्ट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.