आईईई 754 में डबल्स में 52 बिट्स की सटीकता है जिसका अर्थ है कि वे संख्याओं को कम से कम (0 कम से कम) 2 तक स्टोर कर सकते हैं।
यदि आपकी लम्बाई 32-बिट है, तो उनके पास केवल (सकारात्मक) रेंज 0 से 2 होगी, इसलिए 32-बिट लंबा नहीं है जिसे बिल्कुल डबल के रूप में प्रदर्शित नहीं किया जा सकता है। 64-बिट लंबे के लिए, यह (लगभग) 2 होगा, इसलिए मैं शून्य पर नहीं, वहां चारों ओर शुरू कर रहा हूं।
आप निम्न प्रोग्राम का उपयोग यह पता लगाने के लिए कर सकते हैं कि विफलता कहां शुरू होती है। एक पूर्व संस्करण मैंने इस तथ्य पर भरोसा किया था कि एक संख्या में अंतिम अंक जो लगातार युगल होता है अनुक्रम {2,4,8,6} का पालन करता है। हालांकि, मैंने आखिरकार अंतिम अंक की जांच करने के लिए अंततः एक ज्ञात विश्वसनीय उपकरण (bc)
का उपयोग करने का विकल्प चुना।
ध्यान रखें कि इस युगल की असली सटीकता sprintf()
की कार्रवाई के बजाय से प्रभावित हो सकता (मैं तो व्यक्तिगत रूप से, क्योंकि यह 2 अप करने के लिए निश्चित संख्या के साथ कोई मुसीबतों था नहीं लगता कि)।
2^51 - 1 = 2251799813685247
2^52 - 1 = 4503599627370495
2^53 - 1 = 9007199254740991
2^54 - 1 <-- bc failure
got [18014398509481984]
expected [18014398509481983]
जहां मैं इसे विफल करने की उम्मीद के बारे में है जो:
#include <stdio.h>
#include <string.h>
int main() {
FILE *fin;
double d = 1.0; // 2^n-1 to avoid exact powers of 2.
int i = 1;
char ds[1000];
char tst[1000];
// Loop forever, rely on break to finish.
while (1) {
// Get C version of the double.
sprintf (ds, "%.0f", d);
// Get bc version of the double.
sprintf (tst, "echo '2^%d - 1' | bc >tmpfile", i);
system(tst);
fin = fopen ("tmpfile", "r");
fgets (tst, sizeof (tst), fin);
fclose (fin);
tst[strlen (tst) - 1] = '\0';
// Check them.
if (strcmp (ds, tst) != 0) {
printf("2^%d - 1 <-- bc failure\n", i);
printf(" got [%s]\n", ds);
printf(" expected [%s]\n", tst);
break;
}
// Output for status then move to next.
printf("2^%d - 1 = %s\n", i, ds);
d = (d + 1) * 2 - 1; // Again, 2^n - 1.
i++;
}
}
यह जब तक चलती है:
इस कार्यक्रम है।
एक के रूप में अलग रूप में, मैं मूल रूप से संख्या प्रपत्र 2 n का इस्तेमाल किया लेकिन यह है कि अप करने के लिए मुझे मिल गया: एक डबल 8 बाइट्स होने का आकार (sizeof
के साथ की जाँच) के साथ
2^136 = 87112285931760246646623899502532662132736
2^137 = 174224571863520493293247799005065324265472
2^138 = 348449143727040986586495598010130648530944
2^139 = 696898287454081973172991196020261297061888
2^140 = 1393796574908163946345982392040522594123776
2^141 = 2787593149816327892691964784081045188247552
2^142 = 5575186299632655785383929568162090376495104
2^143 <-- bc failure
got [11150372599265311570767859136324180752990210]
expected [11150372599265311570767859136324180752990208]
। यह पता चला कि ये संख्या द्विआधारी रूप "1000..."
थीं जिन्हें अब तक डबल्स के साथ प्रदर्शित किया जा सकता है। यह तब होता है जब मैंने बेहतर बिट पैटर्न प्राप्त करने के लिए 2 n -1 का उपयोग करने के लिए स्विच किया: सभी एक बिट्स।
उपरोक्त कोड प्रत्येक पूर्णांक के माध्यम से व्यापक हो रहा है। मैं इसके बजाए एक बाइनरी खोज पर विचार करूंगा। इसे 2^53 के बजाय 53 या तो पुनरावृत्तियों के साथ अभिसरण करना चाहिए। –
प्रतिनिधित्व के कुछ पूर्व ज्ञान के बिना बाइनरी खोज काम नहीं करेगा। ** सभी की ** ** शक्तियां बिल्कुल दोगुनी हैं, इसलिए यदि आपकी द्विआधारी खोज दो की शक्तियों को चलने के लिए होती है, तो यह वांछित बिंदु को पूरी तरह से याद कर सकता है ... :-) –
संभावित डुप्लिकेट [जो पहला पूर्णांक है कि एक आईईईई 754 फ्लोट बिल्कुल प्रतिनिधित्व करने में असमर्थ है?] (http://stackoverflow.com/questions/3793838/which-is-the-first-integer-that-an-ieee-754-float-is-incapable-of -representing-e) –