0.0 और 1.0 के बीच कितने दोहरे नंबर हैं?


93

यह कुछ ऐसा है जो वर्षों से मेरे दिमाग में है, लेकिन मैंने पहले कभी पूछने का समय नहीं लिया।

कई (छद्म) यादृच्छिक संख्या जनरेटर 0.0 और 1.0 के बीच एक यादृच्छिक संख्या उत्पन्न करते हैं। गणितीय रूप से इस रेंज में अनंत संख्याएं हैं, लेकिन doubleएक फ्लोटिंग पॉइंट नंबर है, और इसलिए एक परिमित परिशुद्धता है।

तो सवाल ये हैं:

  1. बस कितने हैं double 0.0 और 1.0 के बीच नंबर हैं?
  2. क्या केवल 1 और 2 के बीच कई संख्याएँ हैं? 100 और 101 के बीच? 10 ^ 100 और 10 ^ 100 + 1 के बीच?

नोट: अगर इससे कोई फर्क पड़ता है, तो मुझे doubleविशेष रूप से जावा की परिभाषा में दिलचस्पी है ।

जवाबों:


68

Java doubles IEEE-754 प्रारूप में हैं, इसलिए उनके पास 52-बिट अंश है; दो में से किसी भी दो आसन्न शक्तियों के बीच (एक के एक और विशेष को मिलाकर), इसलिए 2 से 52 doubleवीं शक्ति अलग-अलग होगी (यानी, 4503599627370496)। उदाहरण के लिए, double0.5 और शामिल किए गए 1.0 के बीच अलग-अलग एस की संख्या है, और ठीक यही है कि कई भी 1.0 शामिल और 2.0 को छोड़कर, और इसके बाद के बीच झूठ बोलते हैं।

doubles0.0 और 1.0 के बीच की गणना दो की शक्तियों के बीच ऐसा करने की तुलना में कठिन है, क्योंकि उस सीमा में दो की कई शक्तियां शामिल हैं, और, यह भी, एक व्यक्ति संख्याओं के कांटेदार मुद्दों में हो जाता है। एक्सपट्र्स के 11 बिट्स में से 10 विचाराधीन रेंज को कवर करते हैं, इसलिए, जिसमें डिमनरलाइज्ड नंबर (और मुझे लगता है कि कुछ प्रकार के NaN) शामिल हैं, आपके पास 1024 गुना होगा, doubleजैसे कि दो की शक्तियों के बीच रखना - 2**62वैसे भी कुल मिलाकर इससे अधिक नहीं। । अपभ्रंश और ग को छोड़कर, मेरा मानना ​​है कि गिनती 1023 बार होगी 2**52

"100 से 100.1" जैसी मनमानी सीमा के लिए यह और भी कठिन है क्योंकि ऊपरी बाउंड को बिल्कुल एक के रूप में नहीं दिखाया जा सकता है double(दो की किसी भी शक्ति का सटीक एक से अधिक नहीं होना)। एक आसान सन्निकटन के रूप में, चूंकि दो की शक्तियों के बीच प्रगति रैखिक है, आप कह सकते हैं कि उक्त सीमा 0.1 / 64दो (64 और 128) की आसपास की शक्तियों के बीच की अवधि की है, इसलिए आप इसके बारे में अपेक्षा करेंगे

(0.1 / 64) * 2**52

विशिष्ट doubles - जो आता है 7036874417766.4004... एक या दो को लेते हैं; ;-)।


@ एलेक्स: बस ध्यान देने के लिए, जब मैंने 100 से 100.1 लिखा था तो मैंने गलत लिखा। मेरा मतलब था 100 से 101. मूल रूप से, N और N + 1 के बीच में मनमानी N के लिए
पॉलीजेनबेलिकैलेंट

4
@ एलेक्स: तो मुझे इसे सीधे प्राप्त करने दें: 2**64संभव दोहरे मानों से अधिक नहीं हो सकता है (क्योंकि यह 64 बिट प्रकार है), और जाहिर तौर पर उन मूल्यों का एक बड़ा अनुपात इसके बीच है 0..1?
पॉलीजेनैलेबुलेंट

9
@ पॉलीगीन, हाँ और हाँ - विशेष रूप से, किसी भी आधार के किसी भी आधार (संभावित "सामान्य" फ़्लोटिंग पॉइंट प्रतिनिधित्व और किसी अंश के प्रति घातांक बनाम अंश लंबाई के बारे में) का एक चौथाई 0.0 और 1.0 (1.0 और अनंत के बीच एक और तिमाही) के बीच होता है। वास्तविक अक्ष के नकारात्मक आधे पर शेष आधा)। अनिवार्य रूप से, घातांक के आधे मूल्य (एक सामान्य पूर्वाग्रह के साथ, इसकी सीमा के भीतर आधे रास्ते) आधार की नकारात्मक शक्तियों का प्रतिनिधित्व करते हैं, इसलिए संख्या <1.0।
एलेक्स मार्टेली

8
@ पॉलीऑक्सीलगैबुलेंट: कई अनुप्रयोगों के लिए, 0 और 1 के बीच की सीमा 100 और 101 के बीच की सीमा की तुलना में बहुत अधिक महत्वपूर्ण और दिलचस्प है, इसीलिए इसे मूल्यों का एक बड़ा हिस्सा मिलता है। उदाहरण के लिए, भौतिकी में, आपको अक्सर 6.67e-11 में न्यूटन के गंभीर स्थिरांक जैसे हास्यास्पद छोटे मूल्यों से निपटना पड़ता है। अच्छा परिशुद्धता के बाद वहाँ की तुलना में 100 और 101. के बीच और पढ़ें उपयोगी है floating-point-gui.de अधिक जानकारी के लिए।
माइकल बोर्गवर्ड

1
आप 0.0 से 1.0 के बीच किसी भी संख्या को स्केल कर सकते हैं, स्केल का ट्रैक अलग रख सकते हैं, गणना में कम त्रुटि पैदा कर सकते हैं। यह अच्छा है जब पूरी संख्या रेखा को दो संख्याओं के बीच मैप किया जा सकता है!
कोडकाइज़न

42

प्रत्येक doubleमूल्य जिसका प्रतिनिधित्व बीच में है 0x0000000000000000और 0x3ff0000000000000अंतराल में निहित है [0.0, 1.0]। यह (2 ^ 62 - 2 ^ 52) अलग-अलग मूल्य (प्लस या एक जोड़े को निर्भर करता है कि क्या आप समापन बिंदु की गणना करते हैं)।

अंतराल [1.0, 2.0] के बीच 0x3ff0000000000000और अभ्यावेदन के मेल से संबंधित है 0x400000000000000; यह 2 ^ 52 अलग मूल्य है।

अंतराल [100.0, 101.0] के बीच 0x4059000000000000और अभ्यावेदन से मेल खाता है0x4059400000000000 ; यह 2 ^ 46 अलग मूल्य है।

10 ^ 100 और 10 ^ 100 + 1 के बीच कोई युगल नहीं हैं । न तो उन संख्याओं में से एक दोहरी सटीकता में प्रतिनिधित्व योग्य है, और न ही कोई युगल हैं जो उनके बीच आते हैं। निकटतम दो दोहरे परिशुद्धता संख्या हैं:

99999999999999982163600188718701095...

तथा

10000000000000000159028911097599180...

+1, एक अच्छी तरह से समर्थित सटीक उत्तर के लिए। (यदि आप समापन बिंदुओं को गिनने के बारे में विचार कर रहे हैं, तो याद रखें कि +0.0 और -0.0 का अलग-अलग प्रतिनिधित्व है।)
जिम लुईस

1
+1, ऐसा मोड़ खत्म! लगा जैसे मैं एम। नाइट श्यामलन स्क्रिप्ट पढ़ रहा था!
पॉलीजेन लुब्रीकेंट

7

दूसरों ने पहले ही समझाया है कि सीमा में लगभग 2 ^ 62 युगल हैं [0.0, 1.0]।
(वास्तव में आश्चर्य की बात नहीं है: लगभग 2 ^ 64 अलग-अलग परिमित युगल हैं, उनमें से आधे सकारात्मक हैं, और लगभग आधे लोग <1.0 हैं।)

लेकिन आप यादृच्छिक संख्या जनरेटर का उल्लेख करते हैं: ध्यान दें कि 0.0 और 1.0 के बीच एक यादृच्छिक संख्या जनरेटर उत्पन्न करने वाली संख्या सामान्य रूप से इन सभी नंबरों का उत्पादन नहीं कर सकती है ; आम तौर पर यह केवल एन / 2 ^ 53 के साथ एक पूर्णांक के रूप में संख्याओं का उत्पादन करेगा (देखें जैसे कि अगले दस्तावेज़ के लिए जावा प्रलेखन )। इसलिए आमतौर पर लगभग 2 ^ 53 (+/- 1) होते हैं, जिसके आधार पर random()आउटपुट के लिए संभावित मान शामिल हैं) । इसका अर्थ है कि [0.0, 1.0] में अधिकांश युगल कभी उत्पन्न नहीं होंगे।


3

लेख जावा का नया गणित, भाग 2: आईबीएम से फ्लोटिंग-पॉइंट नंबर इसे हल करने के लिए निम्नलिखित कोड स्निपेट प्रदान करता है (फ्लोट्स में, लेकिन मुझे संदेह है कि यह डबल्स के लिए भी काम करता है):

public class FloatCounter {

    public static void main(String[] args) {
        float x = 1.0F;
        int numFloats = 0;
        while (x <= 2.0) {
            numFloats++;
            System.out.println(x);
            x = Math.nextUp(x);
        }
        System.out.println(numFloats);
    }
}

उनकी यह टिप्पणी है:

यह पता चला है कि 1.0 और 2.0 के बीच बिल्कुल 8,388,609 फ्लोट हैं; बड़ी लेकिन मुश्किल से वास्तविक संख्याओं की बेशुमार अनंतता जो इस सीमा में मौजूद है। क्रमिक संख्याएँ लगभग 0.0000001 हैं। इस दूरी को अंतिम स्थान पर कम से कम सटीक या इकाई के लिए ULP कहा जाता है।


हाँ, लेकिन उस के लिए की float, नहीं double - floatरों अंश के 23 बिट्स के मूल्य इतना है, 2**23 -> 8388608दोनों में से सटे शक्तियों के बीच अलग-अलग मान (बेशक "समावेशी" भाग आप एक और दो के अगले शक्ति गिनती करने के लिए है मतलब)। doubles में 52-बिट अंश हैं!
एलेक्स मार्टेली

1
@ एलेक्स: मुझे लगता है कि मुझे कार्यक्रम (युगल के लिए संशोधित) को ब्रह्मांड के अंत तक चलना होगा या इससे पहले कि मैं परिणाम प्राप्त कर
सकूं

1
मुझेमूक होने का अनुभव हो रहा है; मैंने सिर्फ doubleसमकक्ष लिखा और सोचा "अरे, मैं अपने प्रश्न का उत्तर लगभग 5 मिनट में दे दूंगा ..."
पॉलीजेनबेलेंसेंट

1
@polygene: एक परियोजना यूलर समस्या जहां स्पष्ट दृष्टिकोण की गणना करने के अव्यवहार्य है, लेकिन मनमाने ढंग से मामले के लिए हल करने के लिए कुछ शानदार ढंग से सरल सूत्र होना चाहिए ... की तरह यह महसूस करता
मार्क Rushakoff

2
शायद एक सुपरचार्जेड सुपरकंप्यूटर के साथ नहीं: इनर लूप को चलाने के लिए सिर्फ एक नैनोसेकंड लेने वाली मशीन पर, doubleदो की आसन्न शक्तियों के बीच की गिनती में लगभग 52 दिन लगेंगे ( printlnबेशक यह बहुत तेजी से चलने की संभावना नहीं होगी कि कोई बात नहीं, तो मान लेते हैं कि एक कथन दूर हो जाता है; ;-) मुझे लगता है कि एक शक्तिशाली या यथार्थवादी मशीन पर एक वर्ष या उससे कम समय लेना संभव है; ;-)
एलेक्स मार्टेली

2
  1. 2 ^ 53 - 64 बिट फ्लोटिंग पॉइंट नंबर के महत्व / मंटिसा का आकार जिसमें छिपे हुए बिट शामिल हैं।
  2. मोटे तौर पर हाँ, जैसा कि सिफ़निफ़ेंड तय हो गया है, लेकिन प्रतिपादक बदल जाता है।

देखें विकिपीडिया लेख और जानकारी के लिए।


2 विरोधाभासों के लिए आपका जवाब कि मैं एफपी के कामकाज को कैसे समझता हूं।
पॉलीजेन लुब्रीकेंट

मुझे लगता है कि 1गलत है हमेशा होता है क्योंकि छिपा हुआ सा एक - इसलिए 2^52, नहीं 2^53 अलग मूल्यों (दो से सटे शक्तियों, एक शामिल है और अगले एक बाहर रखा के बीच - नहीं ! 0.0 और 1.0 के बीच)।
एलेक्स मार्टेली 3

1

जावा डबल एक IEEE 754 बाइनरी 64 नंबर है।

इसका मतलब है कि हमें विचार करने की आवश्यकता है:

  1. मंटिसा 52 बिट है
  2. प्रतिपादक 1023 पूर्वाग्रह के साथ 11 बिट संख्या है (अर्थात 1023 इसे जोड़ा गया)
  3. यदि प्रतिपादक सभी 0 है और मंटिसा गैर शून्य है तो संख्या को गैर-सामान्यीकृत कहा जाता है

मूल रूप से इसका मतलब है कि संभावित दोहरे अभ्यावेदन का कुल 2 ^ 62-2 ^ 52 + 1 है जो मानक के अनुसार 0 और 1. के बीच है। ध्यान दें कि 2 ^ 52 + 1 गैर-सामान्यीकृत मामलों को हटाने के लिए है संख्या।

याद रखें कि यदि मंटिसा सकारात्मक है लेकिन प्रतिपादक ऋणात्मक संख्या धनात्मक है लेकिन 1 से कम है :-)

अन्य संख्याओं के लिए यह थोड़ा कठिन है क्योंकि धार पूर्णांक संख्याएँ IEEE 754 प्रतिनिधित्व में सटीक तरीके से प्रस्तुत करने योग्य नहीं हो सकती हैं, और क्योंकि प्रतिपादक में उपयोग किए जाने वाले अन्य बिट्स संख्याओं का प्रतिनिधित्व करने में सक्षम हैं, इसलिए संख्या जितनी कम होगी विभिन्न मूल्यों।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.