2010-06-21 9 views
9

PHP में, हमारे पास number_format() है।जावास्क्रिप्ट सही ढंग से दो दशमलव तक गोल कर रहा है, असंभव?

number_format(3.00 * 0.175, 2); 

रिटर्न 0.53, जो है मैं क्या उम्मीद करेंगे: यह इस तरह के रूप में एक मूल्य पासिंग।

हालांकि, जावास्क्रिप्ट में toFixed()

var num = 3.00 * 0.175; 
num.toFixed(2); 

रिटर्न 0.52 का उपयोग कर।

ठीक है, तो शायद toFixed नहीं, यह या तो काम नहीं करता नहीं है जो मैं चाहता ... हो सकता है कि कुछ इस तरह ...

var num = 3.17 * 0.175; 
var dec = 2; 
Math.round(Math.round(num * Math.pow(10, dec + 1))/Math.pow(10, 1))/Math.pow(10,dec); 

। यह 0.56 वापस आ जाएगा।

मैं जावास्क्रिप्ट में एक number_format समारोह है कि एक गलत जवाब नहीं दे करता है कैसे मिल सकता है?

वास्तव में मुझे जेएस, http://phpjs.org/functions/number_format के लिए संख्या_format का कार्यान्वयन मिला, लेकिन यह एक ही समस्या से पीड़ित है।

क्या गोलाई जावास्क्रिप्ट के साथ यहां चल रहा है? मैं क्या खो रहा हूँ?

+1

PHP में, आप 3.00 * 0.175 कर रहे हैं, अपनी जावास्क्रिप्ट 3.17 * 0.175 .. –

+0

लॉरी: 3.17 * 0.175 0.55 नहीं, 0.56 नहीं, जो समस्या है। – Gabe

+0

स्टैक ओवरफ्लो में आपका स्वागत है, महान पहला सवाल। –

उत्तर

12

जावास्क्रिप्ट चल बिन्दु संख्या (कई अन्य भाषाओं करते हैं) के साथ बुरी तरह से करता है।

जब मैं

3.000 * 0.175 

अपने ब्राउज़र में चलाने के लिए, मैं

0.5249999999999999 

कौन सा Math.round साथ 0.525 में इसे राउंड नहीं होगा मिलता है। इसे रोकने के लिए, आपको दोनों पक्षों को गुणा करना है जबतक कि आप उन्हें पूर्णांक नहीं प्राप्त करते (अपेक्षाकृत आसान, कुछ चाल जानने में मदद करते हैं)।

तो यह करने के लिए हम कह सकते हैं कुछ इस तरह:

function money_multiply (a, b) { 
    var log_10 = function (c) { return Math.log(c)/Math.log(10); }, 
     ten_e = function (d) { return Math.pow(10, d); }, 
     pow_10 = -Math.floor(Math.min(log_10(a), log_10(b))) + 1; 
    return ((a * ten_e(pow_10)) * (b * ten_e(pow_10)))/ten_e(pow_10 * 2); 
} 

इस तरह की अजीब लग सकता है, लेकिन यहाँ कुछ छद्म कोड है:

get the lowest power of 10 of the arguments (with log(base 10)) 
add 1 to make positive powers of ten (covert to integers) 
multiply 
divide by conversion factor (to get original quantities) 

इस आशा है कि तुम क्या देख रहे है के लिये। यहां एक नमूना चलाया गया है:

3.000 * 0.175 
0.5249999999999999 

money_multiply(3.000, 0.175); 
0.525 
+0

धन्यवाद, हाँ यह वही है जो मैं याद कर रहा था। फ्लोटिंग प्वाइंट गणित ने मुझे उलझन में डाल दिया :) – Bob

+0

हाँ, मुझे इस के लिए हाई स्कूल/कॉलेज ज्ञान को बाहर करना पड़ा, हाहाहा। –

+0

बीटीडब्ल्यू, पता लगाया गया है कि Math.log ई का आधार है, 10 नहीं, भविष्य के संदर्भ के लिए समायोजित –

0

आप क्यों नहीं बस Math.round(num * Math.pow(10, dec))/Math.pow(10, dec)) का उपयोग नहीं किया?

संपादित करें: मैं देख रहा हूँ, समस्या यह है कि 3 * 0.175 आप .52499999999999991 अग्रणी आप एक अतिरिक्त राउंडिंग कदम चाहते हैं देता है, है। हो सकता है कि सिर्फ एक छोटी राशि काम करेगा जोड़ने:

Math.round(num * Math.pow(10, dec) + 0.000000001)/Math.pow(10, dec))

+0

मैंने वास्तव में कोशिश की, लेकिन यह भी गलत परिणाम लौटा। उदा 3.00 * 0.175 = 0.52। मैंने जो अभिव्यक्ति का उपयोग किया वह सही जवाब देने के लिए मजबूर करने की कोशिश करने का एक निराला प्रयास था, लेकिन यह काम नहीं किया :) – Bob

3

toFixed समारोह सही ढंग से काम कर रहा है। यह अंश अंकों की निर्दिष्ट मात्रा से पहले truncates।

1

मुझे लगता है कि समस्या आप का सामना कर रहे रूप में खुद को गोलाई के लिए विरोध चल बिन्दु गणित के साथ है।

परीक्षण के लिए फ़ायरबग कंसोल का उपयोग करना, 3.00 * 0.175 का परिणाम 0.524999... दिया प्रवेश करने। तो इस संख्या को गोल करना वास्तव में सही है।

अगर वहाँ आपकी समस्या का एक अच्छा समाधान है मैं नहीं जानता, लेकिन मेरे अनुभव में जब मुद्रा के साथ काम: यह आसान है सबसे छोटी इकाई (सेंट) में काम करने के लिए और उसके बाद प्रदर्शन के लिए कनवर्ट करें।

0

मुझे पता है कि यह पुराना है, लेकिन इस तरह मैं आमतौर पर एक गोल समस्या को हल करता हूं। इसे आसानी से एक फ़ंक्शन में रखा जा सकता है लेकिन अभी के लिए मैंने अभी के लिए सरल वर्र्स डाले हैं। यदि यह काम नहीं करता है तो आप php.js (नीचे अधिक जानकारी) से शुरू के रूप में money_format() या number_format() का उपयोग कर सकते हैं।

var n = (3.00 * 0.175); 
n = Math.round(n * Math.pow(10, 3))/Math.pow(10, 3); 
Math.round(n*100)/100; 

आता है बाहर करने के लिए 0,53 (0,5249999999999999)

var n = (3.00 * 0.175); 
n = Math.round(n * Math.pow(10, 3))/Math.pow(10, 3); 
Math.round(n*100)/100; 

को 0.56 (0.५५,४७५)

बाहर आता है

यह भी php.js रेपो तरह लग रहा है, इसलिए यदि GitHub https://github.com/kvz/phpjs पर रखा जा रहा है ऐसा कोई फ़ंक्शन नहीं है जो सही तरीके से प्रदर्शन नहीं कर रहा हो, कोई समस्या सबमिट की जा सके।

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

3

क्यों सभी शक्तियां ?? क्यों नहीं बस थोड़ा सा less than 1/2 a cent और round जोड़ें:

(3.00 * 0.175 + 0.0049).toFixed(2)

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

+0

आधा पैसा दृष्टिकोण हमेशा दौर में लगता है। चूंकि मैं आधे से भी कम करना चाहता हूं, आधा से भी कम, मैंने [मोज़िला] के खिलाफ संख्याओं की तुलना की तुलना की है (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/गणित/दौर)। यहां परिणामों की तुलना है। [बेला] (https://jsfiddle.net/ledlogic/24a9tkrz/)। – ledlogic

संबंधित मुद्दे