2017-01-03 10 views
5

मैं कार्यों dyst और dystryb बनाया:अनुक्रमण, कुछ बातों के साथ समस्याओं

dyst<- function(t,x) 
{ 
    f<-1 
    return(f) 
} 
dystryb<- function(x) 
{ 
    x<-sort(x) 
    s<- numeric(101) 
    u<-seq(0,1, by = 0.01) 
    for (t in u) 
    { 
    s[t*100+1]<-dyst(t,x) 
    } 
    return(s) 
} 

समारोह dystryb कॉल करने के बाद मैं इस मिल:

> x<-c(1,2,3,4,5,6,7) 
> dystryb(x) 
    [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
[51] 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
[101] 1 

क्यों इस समारोह तर्क 30 के लिए काम नहीं कर रहा और 5 9? बेशक यह एक कार्य करने के बारे में नहीं है, जो "1" का वेक्टर बनाता है, लेकिन मैं इसे स्पष्ट करना चाहता था, जहां समस्या है।

+0

मेरा मानना ​​है कि इसे आंतरिक रूप से 0.3 कैसे संग्रहीत किया जा रहा है इसके साथ यह करना है। चूंकि यह संख्या आवर्ती है, 100 से गुणा एक छोटे से यह बदलता रहता है। शायद। सिर्फ एक विचार –

उत्तर

1

मूल कारण संख्यात्मक परिशुद्धता है। आर-संबंधित चर्चा के लिए यह SO post देखें। @ Dirk-eddelbuettel के लिंक में आर और दोनों को सामान्य रूप से कंप्यूटिंग में संख्यात्मक परिशुद्धता को कवर करने वाले सबसे प्रासंगिक कागजात में से एक पृष्ठभूमि प्रदान की जाती है। This post इस मुद्दे के पीछे कंप्यूटर विज्ञान से संबंधित SO पर अधिक विस्तृत सामान्य उत्तर प्रदान करता है।

यह दिखाने के लिए कि मूल कारण संख्यात्मक परिशुद्धता है, आपके द्वारा बनाए गए अनुक्रम पर विचार करें। सबसे पहले, अनुक्रम का डिफ़ॉल्ट प्रिंट आउट।

print(seq(0,1, by = 0.01) * 100 + 1) 
    [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 
[20] 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 
[39] 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 
[58] 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 
[77] 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 
[96] 96 97 98 99 100 101 

सबकुछ अच्छा दिखता है। अब, 16 अंकों को दिखाने के लिए अपने अनुक्रम आर को प्रिंट करें।

print(seq(0,1, by = 0.01) * 100 + 1, digits=16) 
    [1] 1.000000000000000 2.000000000000000 3.000000000000000 
    [4] 4.000000000000000 5.000000000000000 6.000000000000000 
            ... 
[25] 25.000000000000000 26.000000000000000 27.000000000000000 
[28] 28.000000000000000 29.000000000000004 29.999999999999996 
[31] 31.000000000000000 32.000000000000000 33.000000000000000 
[34] 34.000000000000000 35.000000000000000 36.000000000000000 
[37] 37.000000000000000 38.000000000000000 39.000000000000000 
[40] 40.000000000000000 41.000000000000000 42.000000000000000 
[43] 43.000000000000000 44.000000000000000 45.000000000000000 
[46] 46.000000000000000 47.000000000000000 48.000000000000000 
[49] 49.000000000000000 50.000000000000000 51.000000000000000 
[52] 52.000000000000000 53.000000000000000 54.000000000000000 
[55] 55.000000000000000 56.000000000000007 57.000000000000007 
[58] 58.000000000000007 58.999999999999993 60.000000000000000 
           ... 
[100] 100.000000000000000 101.000000000000000 

आप देखते हैं कि '30' 29.999999999999996 का मूल्य जमा हो जाती है और '59' भंडार 58.999999999999993 का मूल्य। अब, अगर हम इस अनुक्रम को पूर्णांक के रूप में डालते हैं, तो हमें निम्न आउटपुट मिलता है।

print(as.integer(seq(0,1, by = 0.01) * 100 + 1)) 
    [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 
[20] 20 21 22 23 24 25 26 27 28 29 29 31 32 33 34 35 36 37 38 
[39] 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 
[58] 58 58 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 
[77] 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 
[96] 96 97 98 99 100 101 

यह बलात्कार समारोह 58 करने के लिए 29 और 58,999999999999993 करने के लिए 29,999999999999996 अनुवाद, अनिवार्य रूप से एक काट-छांट प्रदर्शन। तो, आपके कोड में, 2 9वीं और 58 वें तत्वों को दो बार संदर्भित किया जाता है, जबकि 30 वें और 59 वें तत्वों का संदर्भ नहीं दिया जाता है।

इस स्थिति में, उत्पादन floor समारोह का उपयोग कर के समान है। अपने विशेष समस्या के लिए

identical(trunc(seq(0,1, by = 0.01) * 100 + 1), floor(seq(0,1, by = 0.01) * 100 + 1)) 
[1] TRUE 

एक समाधान अनुक्रम पूर्णांक कास्टिंग से पहले round उपयोग करने के लिए है।

identical(1:101, as.integer(round(seq(0,1, by = 0.01) * 100 + 1))) 
[1] TRUE 
+0

यह समाधान वास्तव में मददगार था। मैं संख्यात्मक परिशुद्धता के बारे में सोचा है, लेकिन मैं समझ नहीं कर सकता है, यह कैसे सुधार करने के लिए। आपका बहुत बहुत धन्यवाद! – Aga

+0

ज़रूर बात, संख्यात्मक परिशुद्धता मुद्दों अप्रत्याशित तरीके से दिखा सकते हैं। – lmo

1

निम्नलिखित दिखाता है कि वास्तव में क्या हुआ, आपके पास फ्लोटिंग पॉइंट परिशुद्धता त्रुटि के कारण 15, 2 9 स्थानों पर शून्य होगा।

which(seq(0,1, by = 0.01)*100+1 != 1:101) 
# [1] 15 29 30 56 57 58 59 
संबंधित मुद्दे