2013-06-05 9 views
8

में पूर्णांक एक्सपोनेंटिएशन क्या ओकैम में पूर्णांक एक्सपोनेंटिएशन के लिए कोई फ़ंक्शन है? ** केवल फ्लोट के लिए है। यद्यपि यह अधिक सटीक प्रतीत होता है, फिर भी सटीक त्रुटियों की संभावना नहीं है, जैसे कि ** ** 3. = 8. कभी-कभी झूठी वापसी? क्या पूर्णांक एक्सपोनेंटिएशन के लिए कोई लाइब्रेरी फ़ंक्शन है? मैं अपना खुद का लिख ​​सकता हूं, लेकिन दक्षता की चिंताएं उसमें आती हैं, और अगर मैं पहले से ऐसा कोई काम नहीं कर रहा हूं तो मुझे आश्चर्य होगा।ओकैम

उत्तर

10

के बारे में आपके प्रश्न का फ़्लोटिंग-पॉइंट हिस्सा: ओकैमल अंतर्निहित सिस्टम के pow() फ़ंक्शन को कॉल करता है। फ्लोटिंग प्वाइंट घातांक (जो है एक Unit in the Last Place करने के लिए सही,) 2. ** 3. = 8.true का मूल्यांकन करने के लिए है, क्योंकि 8.0 गणितीय सही परिणाम 8 में से एक ULP भीतर केवल float है लागू करने के लिए एक मुश्किल कार्य है, लेकिन यह केवल वफादार होने की जरूरत है।

सभी गणित पुस्तकालयों को (*) वफादार होना चाहिए, इसलिए आपको इस विशेष उदाहरण के बारे में चिंता करने की ज़रूरत नहीं है। लेकिन not all of them actually are, तो आप चिंता करने का अधिकार हैं।


में चिंता करने की, हो सकता है अगर आप 63-बिट पूर्णांक या व्यापक उपयोग कर रहे हैं, कि बहस या घातांक का परिणाम ठीक वैसे ही प्रदर्शित नहीं किया जा सकता के रूप में OCaml (वास्तव में आईईईई 754 डबल-परिशुद्धता संख्या तैरता एक बेहतर कारण जो 9_007_199_254_740_993 या 2 + 1 का प्रतिनिधित्व नहीं कर सकता)। इस मामले में, फ्लोटिंग-पॉइंट एक्सपोनेंटिएशन पूर्ण कार्यान्वयन में कमजोरी के कारण पूर्णांक एक्सपोनेंटिएशन के लिए एक खराब विकल्प है, लेकिन क्योंकि यह बिल्कुल बड़े पूर्णांक का प्रतिनिधित्व करने के लिए डिज़ाइन नहीं किया गया है।


(*) एक और मजेदार संदर्भ इस विषय पर पढ़ने के लिए "A Logarithm Too Clever by Half" विलियम कहाँ से है।

+0

क्या फ्लोटिंग-पॉइंट एक्सपोनेंटिएशन जितना तेज़ है उतना तेज़ है कि तर्क समान हैं? साथ ही, यह स्पष्ट करने के लिए, क्या आपका बयान है कि फ़्लोटिंग-पॉइंट एक्सपोनेंटिएशन सभी इंटीग्रियों के लिए वफादार सच होना चाहिए, बी जिसके लिए -2^30 ≤ ए^बी <2^30, या सिर्फ 2 3 के मेरे विशेष उदाहरण के लिए और 8? – user2258552

+0

@ user2258552 गति के बारे में: फ़्लोटिंग-पॉइंट एक्सपोनेंटिएशन शायद एक अच्छी तरह लिखित पूर्णांक से धीमा है। "चाहिए" के अर्थ के बारे में: एक वफादार प्राथमिक कार्य एक परिभाषा डोमेन में एक यूएलपी के लिए सटीक है। सभी libms वफादार होना चाहिए क्योंकि यह कम्प्यूटेशनल लागत और सटीकता के बीच एक उचित समझौता है जो हर किसी को खुश कर देगा। तालिका-निर्माता की दुविधा के कारण 0.5 यूएलपी की शुद्धता सभी libms की अपेक्षा करने के लिए बहुत अधिक है, लेकिन 1 यूएलपी की सटीकता उचित लागत पर प्राप्त की जा सकती है। (लेकिन, फिर से, पाउ() सबसे कठिन प्राथमिक कार्यों में से एक है) –

+0

गति के संबंध में: इसके प्रकाश में, यह वास्तव में मानक पुस्तकालय में एक पूर्णांक एक्सपोनेंटिएशन फ़ंक्शन शामिल करने के लिए बहुत कम समझ में आता है ... – user2258552

19

मानक पुस्तकालय में नहीं। लेकिन आप आसानी से खुद को लिख सकते हैं (तेजी से होने के लिए exponentiation by squaring का उपयोग करके), या एक विस्तारित लाइब्रेरी का पुन: उपयोग करें जो इसे प्रदान करता है। Batteries में, यह Int.pow है।

let rec pow a = function 
    | 0 -> 1 
    | 1 -> a 
    | n -> 
    let b = pow a (n/2) in 
    b * b * (if n mod 2 = 0 then 1 else a) 

अगर वहाँ अतिप्रवाह का खतरा है क्योंकि आप बहुत बड़ी संख्या जोड़ तोड़ कर रहे हैं, तो आप शायद इस तरह के रूप Zarith एक बड़े पूर्णांक पुस्तकालय है, जो सभी प्रकार प्रदान करता है का उपयोग करना चाहिए:

नीचे एक प्रस्तावित कार्यान्वयन है एक्सपोनिएशन फ़ंक्शन का।

(आप "मॉड्यूलर घातांक" आवश्यकता हो सकती है, कंप्यूटिंग (a^n) mod p, यह एक तरीका है कि आधुनिक मध्यस्थ संगणना में ऊपर समारोह pow में उदाहरण के लिए, लगाने से अतिप्रवाह से बचा जाता है में किया जा सकता है।)

+3

महान जवाब है। दुर्भाग्य से, मैं केवल एक अच्छा जवाब चुन सकता हूं: /। साथ ही, मुझे विश्वास नहीं है कि यह पूर्णांक एक्सपोनेंटिएशन को लागू करने का सबसे तेज़ तरीका है। वास्तव में, मुझे लगता है कि इन लाइनों के साथ एक परियोजना यूलर प्रश्न (जिसे मैंने अभी तक हल नहीं किया है) है। मुझे सच में लगता है कि मानक लाइब्रेरी में पूर्णांक एक्सपोनिएशन जोड़ा जाना चाहिए। यहां तक ​​कि यदि यह कोई और अधिक कुशल नहीं है (जो मुझे यकीन नहीं है), तो फ्लोट से कनवर्ट करने और रद्द करने की आवश्यकता के लिए यह एक बहुत ही आम बात है, जो परेशान है। बेशक लाइब्रेरी आयात करना मुश्किल नहीं है, लेकिन ऐसा कोई कारण नहीं है कि यह मानक नहीं होना चाहिए। – user2258552

+2

ठीक है, अगर आपके पास सामान्य मामले में पूर्णांक कार्यान्वयन को कार्यान्वित करने के बेहतर विचार हैं, तो कार्यान्वयन का सुझाव देने के लिए स्वतंत्र महसूस करें। – gasche

+0

@ user2258552 मैं आपके आधार से सहमत नहीं हूं कि पूर्णांक एक्सपोनेंटिएशन इतना आम है। अभ्यास में, आप लगभग हमेशा छोटे फिक्स्ड एक्सपोनेंट्स के साथ काम करते हैं, या आपको * मनमाने ढंग से सटीक अंकगणित की आवश्यकता होती है जैसा कि गैसचे द्वारा सुझाया गया है। टीएल; डीआर: विश्वास करना बंद करें कि आपको निश्चित परिशुद्धता इन्सट्स पर पूर्णांक एक्सपोनिएशन की आवश्यकता है और आपको एहसास है कि आपको मनमानी सटीक अंकगणितीय पुस्तकालय की आवश्यकता है। –

3

यहाँ एक और कार्यान्वयन जो बराबरी से घातांक का उपयोग करता है (@gasche द्वारा प्रदान सेवाओं की तरह) है, लेकिन यह एक पूंछ पुनरावर्ती

let is_even n = 
    n mod 2 = 0 

(* https://en.wikipedia.org/wiki/Exponentiation_by_squaring *) 
let pow base exponent = 
    if exponent < 0 then invalid_arg "exponent can not be negative" else 
    let rec aux accumulator base = function 
    | 0 -> accumulator 
    | 1 -> base * accumulator 
    | e when is_even e -> aux accumulator (base * base) (e/2) 
    | e -> aux (base * accumulator) (base * base) ((e - 1)/2) in 
    aux 1 base exponent 
+1

ध्यान दें कि पूंछ -क्रियाशीलता इसके इनपुट में फ़ंक्शन लॉगरिदमिक के लिए कोई फर्क नहीं पड़ता। आप कभी ढेर कैसे उड़ सकते हैं? बेशक, यदि पूंछ-पुनरावृत्ति एक अलग दृष्टिकोण प्रदान करती है जो कोड के बारे में कुछ दिलचस्प बताती है, या इसे पढ़ने में आसान बनाता है, तो यह अभी भी दिलचस्प हो सकता है। – gasche

+0

@gasche आप सही हैं। यह कोड 63 या 31 बिट पूर्णांक के लिए समझ में नहीं आता है। इस तरह एक एल्गोरिदम मनमानी-परिशुद्धता संख्याओं के लिए समझ में आता है। – Halst

+0

"कुछ दिलचस्प बताता है": यह आपकी टिप्पणी, @gasche संकेत दिया। :-) – Mars