फ्लोटिंग पॉइंट राउंडिंग


13

क्या IEEE-754 फ्लोटिंग पॉइंट नंबर <1 (यानी एक यादृच्छिक संख्या जनरेटर के साथ उत्पन्न होता है जो एक नंबर उत्पन्न करता है> = 0.0 और <1.0) कभी भी किसी पूर्णांक (फ्लोटिंग पॉइंट फॉर्म में) को एक संख्या के बराबर या उससे अधिक प्राप्त करने के लिए गुणा किया जा सकता है गोलाई के कारण पूर्णांक?

अर्थात

double r = random() ; // generates a floating point number in [0, 1)
double n = some_int ;
if (n * r >= n) {
    print 'Rounding Happened' ;
}

यह कहने के समतुल्य हो सकता है कि क्या कोई N और R मौजूद है जैसे कि यदि R 1 से कम की सबसे बड़ी संख्या है जिसे IEEE-754 में दर्शाया जा सकता है तो N * R> = N (जहाँ * और> = उपयुक्त IEEE- हैं 754 ऑपरेटर)

यह इस दस्तावेज और पोस्टग्रैस्कल यादृच्छिक फ़ंक्शन के आधार पर इस प्रश्न से आता है


क्या आप N की सीमा के बारे में कुछ भी कह सकते हैं, यानी IEEE-754 डबल-सटीक में इसका प्रतिनिधित्व किया जाना काफी छोटा है?
— पेड्रो

@Proro इस विशेष मामले में, हाँ, यह एक छोटा पूर्णांक होगा - यानी 10. मैं मानता हूँ कि यदि आप एक बहुत बड़े पूर्णांक के साथ एक बहुत बड़ी संख्या है, तो संभवत: इसका प्रतिनिधित्व नहीं किया जा सकता है?
— कैड रूक्स

वास्तव में, अगर , तो f l ( R × f l ( N ) ) R N से बड़ा हो सकता है । fl(N)>Nfl(R×fl(N))RN
— पेड्रो

जवाबों:


8

यह मानते हुए दौर-टू-पास और है कि , तो एन * आर < एन हमेशा। (सावधान रहें कि एक पूर्णांक को परिवर्तित न करें जो बहुत बड़ा है।)N>0N∗R<N

चलो , जहां ग ∈ [ 1 , 2 ) significand है और क्ष पूर्णांक प्रतिपादक है। चलो 1 - 2 - रों = आर और बाध्य निकाले जाते हैंc2−q=Nc∈[1,2)q1−2−s=R

NR=c2−q(1−2−s)≤c2−q−2−q−s,

समानता के साथ अगर और केवल अगर । दाएँ हाथ की ओर N से कम है और, चूंकि 2 - q - s , N के अंतिम स्थान पर ठीक 0.5 इकाई है , या तो c = 1 और 2 - q - 2 - q - s बिल्कुल प्रतिनिधित्व योग्य है ( N के सामान्य होने के बाद से और सबसे छोटा सामान्य नहीं), या सी > 1 , और निकटतम गोलाई नीचे है। दोनों मामलों में, एन * आर से भी कम है एनc=1N2−q−s0.5Nc=12−q−2−q−sNc>1N∗RN।


अपवर्ड राउंडिंग एक समस्या पैदा कर सकता है, यह नहीं कि इसे कभी-कभी बिना सोचे-समझे उपयोगकर्ताओं की उपस्थिति में चुना जाना चाहिए। यहाँ कुछ C99 है जो "0\n1\n"मेरी मशीन पर प्रिंट करता है।

#include <fenv.h>
#include <math.h>
#include <stdio.h>

int main(void) {
    double n = 10;
    double r = nextafter(1, 0);
    printf("%d\n", n == (n * r));
    fesetround(FE_UPWARD);
    printf("%d\n", n == (n * r));
}

−c2−q2−s≤−2−qs

2−q−s

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