2012-12-08 13 views
7

क्यों tan 45 (.7853981633974483 रेडियन में) मेरे 0.9999 देता है? निम्नलिखित कोड में क्या गलत है?तन 45 मुझे देता है 0.9999

System.out.println(Math.tan(Math.toRadians(45.0))); 

मैं यहाँ किसी भी टाइपो है नहीं लगता।

तो यहां समाधान क्या है?

+0

संभवतः गोल-बंद त्रुटि। लेकिन यह * किसी भी तरह से गोल होना चाहिए यदि यह केवल 4 अंक प्रदर्शित कर रहा है। – Mysticial

+2

पाइथन मुझे '0.9 99 99 99 99 99 99 99 8 9' देता है, भले ही मैं इसमें अंकों की संख्या की परवाह करता हूं। यह शायद फ़्लोटिंग पॉइंट और सन्निकटन त्रुटि है। – Blender

+0

क्या आपने कोई अंक छोड़ा था? –

उत्तर

16

फ़्लोटिंग पॉइंट गणना अक्सर ऐसी त्रुटियों का कारण बनती है। समस्या यह है कि संख्याओं को निश्चित संख्या में बिट्स के भीतर सटीक रूप से प्रदर्शित नहीं किया जा सकता है।

आपको एक और उदाहरण (दशमलव में) देने के लिए, हम सभी सहमत हैं कि 3 * (1/3) = 1। हालांकि, यदि आपके कैलकुलेटर में केवल 4 दशमलव स्थान हैं, 1/3 को 0.3333 के रूप में दर्शाया जाएगा। जब यह के साथ गुणा किया जाता है, तो आपको 0.99991 नहीं मिलेगा।

अधिक जानकारी के रूप में, अधिकांश सिस्टम पर फ़्लोटिंग पॉइंट आमतौर पर IEEE754 मानक का उपयोग करके दर्शाए जाते हैं। आप इसके लिए खोज सकते हैं, या अधिक जानकारी के लिए विकिपीडिया पेज देखें। IEEE floating point

+0

तब समाधान क्या है? – siaooo

+1

@siaooo आपको 'tan (45) 'के लिए आवश्यक दशमलव स्थानों की प्रासंगिक संख्या में गोल करें। यह 0 तक बढ़ जाएगा। –

+0

@ScottChamberlain ठीक है – siaooo

2

उपयोग इस

double radians = Math.toRadians(45.0); 

System.out.format("The tangent of 45.0 degrees is %.4f%n", Math.tan(radians)); 
+1

-1 यह उत्तर यह समझने में विफल रहता है कि अस्थायी बिंदु अंकगणित मुद्दा है। रेडियंस को डिग्री में परिवर्तित करना नहीं है। –

+2

@woodchips मुझे नहीं लगता कि यह जवाब दावा कर रहा है कि रेडियंस को डिग्री में बदलना मुद्दा है। हालांकि, मुझे लगता है कि ** रेडियंस को डिग्री में बदलना मुद्दा है ** कुछ हद तक: यदि हमने सही ढंग से गोल किए गए अनुवांशिक कार्यों (हमारे पास नहीं) पर मानकीकृत किया है, तो यदि हमारे पास एक स्पर्शपूर्ण कार्य था जो डिग्री स्वीकार करता है (हम हेवन टी), तो 45 पर लागू इस फ़ंक्शन का नतीजा 1 होगा। हालांकि हमारे पास रेडियन टेंगेंट फ़ंक्शन को सही ढंग से गोल किया गया है, हम इसे π/4 पर लागू नहीं कर रहे हैं, लेकिन निकटतम 'डबल' पर लागू कर रहे हैं, और इसलिए हम शायद ही कभी बदले में 1 पाने की उम्मीद है। –

+0

@woodchips इसके अलावा, यह उत्तर आउटपुट ** के लिए दशमलव में कनवर्ट करने के समय decimals ** को छोटा कर रहा है। यह अभी भी स्टैक ओवरव्लो पर "कुछ कथित बाइनरी फ़्लोटिंग-पॉइंट नंबरों के साथ एक निश्चित संख्या में दशमलव" के ऊपर एक सिर रखता है, जिसमें आप कुछ प्रश्नों और उत्तरों को देख सकते हैं। –

0

क्योंकि tan(45) 1 है, और बाकी एक गोलाई त्रुटि है शायद इसलिए है कि। फ्लोटिंग पॉइंट की गणना कैसे काम करती है, इस वजह से फ़्लोटिंग पॉइंट की गणना आपको सटीक परिणाम देने की संभावना नहीं है।

+3

ऐसा इसलिए है क्योंकि आप * निकटतम डबल * से pi/4 के स्पर्शक ले रहे हैं। गणित पुस्तकालय में 'tan' सही ढंग से गोलाकार है। फ़्लोटिंग-पॉइंट गणनाओं का बिंदु यह है कि वे तेज़ी से जाते हैं और यदि आप जो भी कर रहे हैं उस पर ध्यान देते हैं तो वे आपको सटीक परिणाम देते हैं। – tmyklebu

10

निकटतम doublepi/4 को बिल्कुल0x1.921fb54442d18p-1 है। इस डबल की टेंगेंट, आपको जितनी अधिक बिट्स की आवश्यकता है, 0x1.fffffffffffff72cece67p-1 है। निकटतम double पर गोल करने से आपको बिल्कुल0x1.fffffffffffffp-1 देता है क्योंकि 0x1.fffffffffffff72cece67p-10x1.fffffffffffff8p-1 से कम है।

+0

हां! एक ध्वनि जवाब! क्या जावा सही ढंग से गोल किए गए अनुवांशिक कार्यों को निर्दिष्ट करता है? –

+1

@ पास्कल क्यूक: जावा सही गोल करने के लिए नहीं पूछता है। यह निर्दिष्ट करता है (एपीआई दस्तावेज को देखकर, जो मुझे लगता है कि कैनोलिक है) कि उत्तर सही परिणाम के 1 उल के भीतर होना चाहिए और जब तक कि तन का ध्रुव 'x' और' y' 'के बीच नहीं है,' Math.tan (x) - Math.tan (y) 'के विपरीत विपरीत चिह्न नहीं है (x) -tan (y)। – tmyklebu

+0

एक त्वरित Google खोज ने मुझे क्लासिक http://www.cs.berkeley.edu/~wkahan/LOG10HAF.TXT पर वापस ले लिया। एक फिर से पढ़ने के लायक है। –

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