2010-03-23 11 views
11

लड़का, यह वास्तव में अजीब है। मैं उम्मीद करता हूं कि निम्नलिखित कोड 1 99 0 को प्रिंट करेगा, लेकिन यह 1 9 8 9 प्रिंट करता है!`अंतराल (1 9.9 * 100)` बराबर `1989` क्यों है?

$val = '$19.9'; 

$val = preg_replace('/[^\d.]/','',$val); 
$val = intval($val * 100); 

echo $val; 

पृथ्वी पर ऐसा क्यों हो रहा है?

संपादित करें: और इस कोड:

$val = '$19.9'; 
$val = preg_replace('/[^\d.]/','',$val); 
echo $val . "<br>"; 
$val = $val * 100; 
echo $val . "<br>"; 
$val = intval($val); 
echo $val; 

प्रिंटों:

19.9 
1990 
1989 

क्यों intval(1990) बराबर 1989 करता है ???

+0

'अंतराल ('1 99 0') 'मुझे 1 99 0 देता है। मैं आपके मामले की जांच करने की कोशिश करूंगा। थोड़ी देर में, कृपया अपने प्रश्न के लिए एक और प्रासंगिक शीर्षक देने का प्रयास करें। – zneak

+0

नहीं, नहीं। 'अंतराल (' 1 99 0 ')' 1 99 0 देता है, जो मैं कह रहा हूं वह यह है कि उदाहरण अप्रत्यक्ष रूप से सुझाव देता है कि 'अंतराल (1 99 0) '1 9 8 9' –

+1

के बराबर है इस मुद्दे पर इस साइट पर मनुष्य को ज्ञात हर दूसरी भाषा में चर्चा की गई है ... – animuson

उत्तर

17

यह PHP में फ़्लोटिंग पॉइंट नंबरों और अन्य कई भाषाओं में अंतर्निहित एक सटीक मुद्दा है। इस बग रिपोर्ट यह थोड़ा चर्चा करता है, एक पूर्णांक के रूप में कास्टिंग के संदर्भ में:

http://bugs.php.net/bug.php?id=33731

बजाय round($val * 100) की कोशिश करो।

+0

हाँ, आपको मिल गया। – zneak

+0

ठीक है, 'राउंड' अपेक्षित उत्तर देता है। 'अंतराल' के बजाय 'राउंड' का उपयोग करने से क्या प्रभाव पड़ता है? –

+0

जैसा कि मैं इसे समझता हूं, 'intval()' का उपयोग करके एक int को मान कास्टिंग करना अनिवार्य रूप से इसे गोल करने के बजाय दशमलव के बाद फ्लोट मान को चॉप करता है। – Funkatron

0

$val एक फ़्लोटिंग पॉइंट नंबर है - "19.9" * 100 का परिणाम। फ़्लोटिंग पॉइंट नंबर किसी भी भाषा में 100% सटीक नहीं हैं (यह डिज़ाइन द्वारा है)। यदि आपको डॉलर मूल्यों के लिए 100% दशमलव सटीकता की आवश्यकता है, तो आपको पूर्णांक का उपयोग करना चाहिए और सेंट का उपयोग करके सभी गणनाएं करना चाहिए (उदा। "$19.90"1990 होना चाहिए)।

+0

तो फिर ... आप क्या कह रहे हैं? –

+0

पूर्णांक का उपयोग करना वास्तव में एक अच्छा समाधान नहीं है। 20 मिलियन से अधिक की राशि के साथ सौदा करना है? उफ़। विभिन्न मुद्राएं, जिनमें से सभी में 100 उप-इकाइयां नहीं हैं? कोई नहीं कर सकता। –

+0

@ माइकल - PHP में 64-बिट पूर्णांक नहीं हैं? मुझे लगता है कि विभिन्न मुद्राएं एक गैर-मुद्दे हैं, क्योंकि आप उन्हें एक-दूसरे से सीधे तुलना नहीं कर सकते हैं। –

4

इस प्रकार के प्रश्न का सामान्य उत्तर What Every Computer Scientist Should Know About Floating-Point Arithmetic पढ़ना है।

+1

... दुर्भाग्य से इस तरह के बुनियादी प्रश्न पूछने वाले लोगों के लिए कोई मदद नहीं है। –

+1

और उन लोगों में से कोई भी सहायता नहीं जो बहुत सारे कोड उत्पन्न करते हैं, लेकिन गणितज्ञ नहीं हैं। – wadesworld

+0

मैंने एक और जवाब में देखा कि किसी ने इस दस्तावेज़ का सरलीकृत संस्करण लिखा था, लेकिन मुझे याद नहीं है कि यह कौन सा प्रश्न या कौन था। – Powerlord

2

अंतराल (1 99 0) बराबर 1989 क्यों ???

क्योंकि आप नहीं रहे intval(1990) लेने। आप intval($val * 100) ले रहे हैं जहां $val एक नजदीक है, लेकिन 1 9.9 से थोड़ा छोटा है।

The Floating-Point Guide पढ़ें यह समझने के लिए कि ऐसा क्यों है।

इसे ठीक करने के तरीके के रूप में: पैसे के लिए फ़्लोटिंग-पॉइंट मानों का कभी भी उपयोग न करें। PHP में, आपको इसके बजाय BCMath का उपयोग करना चाहिए।

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