2010-01-16 20 views
8

हाल ही में, एक संवाददाता ने float.as_integer_ratio() का उल्लेख किया, जो कि पायथन 2.6 में नया है, यह नोट करते हुए कि सामान्य फ़्लोटिंग पॉइंट कार्यान्वयन वास्तविक संख्याओं के अनिवार्य रूप से तर्कसंगत अनुमान हैं। ,float.as_integer_ratio की कार्यान्वयन सीमाएं()

>>> float.as_integer_ratio(math.pi); 
(884279719003555L, 281474976710656L) 

मैं हल्का अधिक accurate परिणाम कारण Arima को देखने के लिए नहीं हैरान था: intrigued, मैं कोशिश करने के लिए π था

(428224593349304L, 136308121570117L) 

उदाहरण के लिए, इस कोड:

#! /usr/bin/env python 
from decimal import * 
getcontext().prec = 36 
print "python: ",Decimal(884279719003555)/Decimal(281474976710656) 
print "Arima: ",Decimal(428224593349304)/Decimal(136308121570117) 
print "Wiki: 3.14159265358979323846264338327950288" 

इस आउटपुट का उत्पादन करता है:

 
python: 3.14159265358979311599796346854418516 
Arima: 3.14159265358979323846264338327569743 
Wiki: 3.14159265358979323846264338327950288 

निश्चित रूप से, परिणाम 64-बिट फ्लोटिंग-पॉइंट नंबरों द्वारा प्रदान की जाने वाली सटीकता को सही है, लेकिन यह मुझे पूछने के लिए प्रेरित करता है: as_integer_ratio() की कार्यान्वयन सीमाओं के बारे में मैं और कैसे जान सकता हूं? किसी भी मार्गदर्शन के लिए धन्यवाद।

अतिरिक्त लिंक: Stern-Brocot tree और Python source

+2

स्वीकृत उत्तर भ्रामक है। 'As_integer_ratio' विधि उस अंश के अंश और denominator को लौटाती है जिसका मूल्य _exactly_ फ़्लोटिंग-पॉइंट नंबर के मान से मेल खाता है। यदि आप एक अंश के रूप में अपने फ्लोट का पूर्ण सटीक प्रतिनिधित्व चाहते हैं, तो 'as_integer_ratio' का उपयोग करें। यदि आप छोटे denominator और numerator के साथ एक सरलीकृत _approximation_ चाहते हैं, तो 'fractions.Fraction.limit_denominator' में देखें। IOW, 'math.pi' π के अनुमान है। लेकिन '884279719003555/281474976710656' _not_' math.pi' का अनुमान है; यह _exactly_ इसके बराबर है। –

+0

@ मार्क डिकिंसन: आपका बिंदु अच्छी तरह से लिया गया है; यह इस [संबंधित उत्तर] को स्पष्ट करता है (https://stackoverflow.com/a/2076903/230513)। हालांकि [स्वीकृत उत्तर] (https://stackoverflow.com/a/2076296/230513) कुछ रखरखाव का उपयोग कर सकता है, इससे मुझे यह देखने में मदद मिली कि मेरी सोच कहाँ से घबरा गई थी। – trashgod

उत्तर

3

एल्गोरिदम as_integer_ratio द्वारा उपयोग किया गया केवल considers powers of 2 in the denominator। यहां एक (शायद) better algorithm है।

+0

आह, '281474976710656 = 2^48'। अब मैं देखता हूं कि मूल्य कहां से आए थे। कार्यान्वयन की तुलना करने में दिलचस्प: http: //svn.python।संगठन/दृश्य/पायथन/ट्रंक/ऑब्जेक्ट्स/floatobject.c? संशोधन = 77139 और देखें = मार्कअप – trashgod

+6

एल्गोरिदम का कहना सही नहीं है एक दोषपूर्ण स्पष्टीकरण है। 'float.as_integer_ratio() 'आपको केवल एक (संख्यात्मक, denominator) जोड़ी देता है जो प्रश्न में फ्लोटिंग-पॉइंट नंबर पर * कठोर रूप से बराबर * है (यही कारण है कि denominator दो की शक्ति है, क्योंकि मानक फ़्लोटिंग-पॉइंट संख्याओं में एक है आधार -2 एक्सपोनेंट)। सटीकता में नुकसान फ्लोटिंग-पॉइंट प्रस्तुति से आता है, * नहीं * float.as_integer_ratio() से जो वास्तव में हानि रहित है। –

+0

IIUC, एल्गोरिदम एक दिए गए फ़्लोटिंग-पॉइंट परिशुद्धता के लिए पर्याप्त सटीक है। Denominator की उत्पत्ति मुझे परेशान कर रहा है। एल्गोरिदम कभी भी अमिमा के अनूठे नतीजे का उत्पादन नहीं करेगा, और आवश्यक परिशुद्धता को कोई बिंदु नहीं दिया जाएगा। – trashgod

1

पायथन के लिए स्रोत भंडार के माध्यम से जाएं, पता लगाएं कि किसने ब्याज कोड किया है, और उन्हें एक ईमेल भेज दें।

3

मैं Stern-Brocot tree की gmpy के कार्यान्वयन की सिफारिश कर सकते हैं:

>>> import gmpy 
>>> import math 
>>> gmpy.mpq(math.pi) 
mpq(245850922,78256779) 
>>> x=_ 
>>> float(x) 
3.1415926535897931 
>>> 

फिर से, परिणाम (53-बिट "तथाकथित" mantissas "64-बिट तैरता की शुद्धता के भीतर सही" है, -), लेकिन:

>>> 245850922 + 78256779 
324107701 
>>> 884279719003555 + 281474976710656 
1165754695714211L 
>>> 428224593349304L + 136308121570117 
564532714919421L 

... gmpy की परिशुद्धता इतना सस्ता (Arima की तुलना में अंश और हर मानों का योग), बहुत कम करने के मामले अजगर 2.6 के दशक में प्राप्त किया जाता है -)

! 363,210
+0

मुझे लाभ दिखाई देता है। मैंने पहले एडी से जीएमपी का इस्तेमाल किया है, इसलिए 'gmpy' आसान होगा। http://code.google.com/p/adabindinggmpmpfr/ – trashgod

3

आप

fractions.Fraction.from_float(math.pi).limit_denominator() 

भिन्न का उपयोग कर शायद संस्करण 3.0 के बाद से शामिल किए गए हैं बेहतर अनुमान मिलता है। हालांकि, गणित में 30 अंकों के अनुमान को वापस करने के लिए पर्याप्त सटीकता नहीं है।

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