2017-02-15 4 views
5

मैं numpy सरणीक्यों numpy 20000001 int 20000000 के रूप में float32 करने के लिए परिवर्तित करता है।

>>> np.array([20000001]).astype('float32') 
array([ 20000000.], dtype=float32) 

में कुछ संख्या डाल करने के लिए जहां 1 चली गई कोशिश कर रहा हूँ?

+0

संभावित डुप्लिकेट http://stackoverflow.com/ प्रश्न/588004/is-floating-point-math-broken) – NobodyNada

उत्तर

7

आप बस पर्याप्त सटीक नहीं है। जबकि float64 सटीकता का लगभग 16 अंक float32, सटीकता की केवल लगभग 7 अंक हैं। इस प्रकार, जब भी आप float32 में कनवर्ट करते हैं, तो यह केवल 10^7 में किसी हिस्से के भीतर "सही" होने की गारंटी है। तो, उदाहरण के लिए, आप इसे आजमा सकते हैं:

>>> np.array([20000001]).astype('float64') 
array([ 20000001.]) 

यह अपेक्षित उत्तर है। (dtype=float64 स्वचालित रूप से छोड़ दिया जाता है, क्योंकि वह डिफ़ॉल्ट है।) वास्तव में, आप आगे कोई बात नहीं जा सकते हैं और पाते हैं, कुछ समय

>>> np.array([2000000000000001]).astype('float64')[0] 
2000000000000001.0 

लेकिन

>>> np.array([20000000000000001]).astype('float64')[0] 
20000000000000000.0 

कैसे उच्च अपने सटीक, आप ' हमेशा उस बिंदु पर पहुंच जाएगा जहां float एस कम से कम महत्वपूर्ण अंक छोड़ देगा। float एस पर अधिक जानकारी के लिए here देखें।

दूसरी ओर, अजगर के int वस्तुओं कई और अधिक अंक वे का ट्रैक रख सकते है। पायथन 3 में, यह व्यावहारिक रूप से असीमित है। तो int एस मूल रूप से अनंत परिशुद्धता है। int एस पर अधिक जानकारी के लिए here देखें।

2
float32 साथ

आप को हल नहीं कर सकता यह

>>> np.finfo(np.float32).eps 
1.1920929e-07 

eps यहाँ आप "छोटी से छोटी प्रदर्शनीय धनात्मक संख्या 1 ऐसी है कि 1 + eps! =" जो float32 सटीकता के लिए एक उपाय है देता है। 20,000,000 के साथ गुणा करें और यह बहुत बड़ा है।

कम अनौपचारिक रूप से, अगर एक कंप्यूटिंग n के द्विआधारी प्रतिनिधित्व से बचने के लिए चाहता है तो eps * n/आधार एक सुविधाजनक कम n चारों ओर समाधान के लिए बाध्य है। जबकि @ हॉब्स बताते हैं कि ईपीएस * एन ऊपरी बाउंड है।

भी ध्यान रखें कि उदाहरण के लिए 1 + 0.6 * ईपीएस वास्तव में कुछ वापस आ सकते हैं! = 1, इस, तथापि, गोलाई की वजह से। परिणाम से 1 घटाना ईपीएस, 0.6 * ईपीएस नहीं देता है।

+0

यह गणना करने का बिल्कुल सही तरीका नहीं है ... हालांकि यह सही मान के 2 कारक के भीतर है। 20,000,000 के आसपास के 32-बिट फ्लोट की वास्तविक सटीकता बिल्कुल 2 है (क्योंकि यह 2^24 + 1 और 2^25 के बीच किसी भी मूल्य के लिए है)। – hobbs

+0

@ हॉब्स अच्छी तरह से, जब तक कि मैं पूरी तरह गलत नहीं हूं, ईपीएस एक्स एन/बेस आपको उस छोटे से नंबर के लिए निचला बाध्य देता है जिसे आप एन में जोड़ सकते हैं। –

+0

ऊपरी, बल्कि। 1.99 पर सटीकता वही है जैसा कि 1 पर है, 1.99 गुना बदतर नहीं; यह 2. – hobbs

2

सबसे पहले, इस मामले में float64 काम करता है:

>>> np.array([20000001]).astype('float32') 
array([ 20000000.], dtype=float32) 
>>> np.array([20000001]).astype('float64') 
array([ 20000001.]) 


कैसे हुड के नीचे एक float काम:

enter image description here


क्या बीच का अंतर है float32 और float64?:

  • 32 बिट (एकल परिशुद्धता नाव): 24 बिट significand
  • 64 बिट (डबल परिशुद्धता नाव): 53 बिट significand


float32 साथ , आप 23 बिट अंक का प्रतिनिधित्व करने के लिए मिल साइन का प्रतिनिधित्व करने के लिए प्लस 1 बिट। दृश्य 20000001 चलें बाइनरी में:

0b 1 0011 0001 0010 1101 0000 0001 ----> 
0b 1 0011 0001 0010 1101 0000 00 

तो पिछले दो बिट्स "01" जब int से float32 को बदलने काट मिल जाएगा।

दिलचस्प बात यह है परिवर्तित 20000003 आप 20000004 मिल जाएगा:

>>> np.array([20000003]).astype('float32') 
array([ 20000004.], dtype=float32) 

और वह है: [? चल रहा है बिंदु गणित टूट]

0b 1 0011 0001 0010 1101 0000 0011 ----> 
0b 1 0011 0001 0010 1101 0000 01 
की (
+1

बहुत अच्छी व्याख्या। कृपया मुझे एक छोटी गलतता को इंगित करने दें। यद्यपि महत्व के लिए 23 बिट्स हैं और वास्तविक परिशुद्धता 24 बिट्स है क्योंकि अंतर्निहित अग्रणी 1 जिसे संग्रहीत करने की आवश्यकता नहीं है। आप इसे 'np.float32 (20_000_002)' के साथ देख सकते हैं, जिसका बिल्कुल प्रतिनिधित्व किया गया है। –

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