2012-02-29 35 views
16

मैं त्रिकोणमिति के लिए रेंज कमीशन ऑपरेशन को लागू करने की कोशिश कर रहा हूं। लेकिन इसके बजाय मुझे लगता है कि आने वाले डेटा पर मॉड्यूलो पीआई/2 ऑपरेशन करना बेहतर होगा। मैं सोच रहा था कि एल्गोरिदम क्या मौजूद है और 32-बिट आईईईई 754 फ्लोटिंग-पॉइंट के लिए इस ऑपरेशन के लिए कुशल हैं?फ़्लोटिंग प्वाइंट मॉड्यूलो ऑपरेशन

मुझे इसे असेंबली में लागू करना है, इसलिए fmod, विभाजन, गुणा, इत्यादि सिर्फ एक निर्देश के साथ उपलब्ध नहीं हैं। मेरा प्रोसेसर 16-बिट शब्दों का उपयोग करता है और मैंने 32-बिट फ्लोटिंग पॉइंट एडिशन, घटाव, गुणा, विभाजन, स्क्वायर रूट, कोसाइन और साइन लागू किया है। मुझे कोसाइन और साइन के मूल्यों को इनपुट करने के लिए केवल सीमा में कमी (मॉड्यूलस) की आवश्यकता है।

+4

असल में बहुत सारे चालाक एल्गोरिदम हैं, उदाहरण के लिए Google "पेने हनेक रेंज कमी" के लिए Google है, लेकिन मुझे लगता है कि आप जो चाहते हैं वह नहीं है – hirschhornsalz

+1

एनजी द्वारा पेपर आपके द्वारा पिछले संबंधित प्रश्न में लिंक किया गया है वास्तव में पेने-हनेक एल्गोरिदम, जो AFAIK अभी भी सटीक सीमा में कमी के लिए कला की स्थिति है। आपको बस इसे एक परिशुद्धता में अनुकूलित करना होगा। – janneb

+0

@ हर कोई, कृपया अपना उत्तर हटाएं/संपादित करें ताकि यह मेरे वास्तविक प्रश्न पर लागू हो। मैं एक फ्लोटिंग-पॉइंट मॉड्यूलस के भीतर एल्गोरिदम की तलाश में हूं। मुझे यह लागू करने की ज़रूरत है कि एफएमओडी क्या करता है और मेरे द्वारा किए गए विभाजन की संख्या को कम करता है। – Veridian

उत्तर

14

मुझे लगता है कि मानक लाइब्रेरी की fmod() ज्यादातर मामलों में सबसे अच्छा विकल्प हो जाएगा। कई सरल एल्गोरिदम की चर्चा के लिए यहां link है।

मेरी मशीन पर, fmod() का उपयोग करता है अनुकूलित इनलाइन विधानसभा कोड (/usr/include/bits/mathinline.h):

#if defined __FAST_MATH__ && !__GNUC_PREREQ (3, 5) 
__inline_mathcodeNP2 (fmod, __x, __y, \ 
    register long double __value;       \ 
    __asm __volatile__         \ 
    ("1: fprem\n\t"       \ 
    "fnstsw %%ax\n\t"        \ 
    "sahf\n\t"         \ 
    "jp 1b"        \ 
    : "=t" (__value) : "0" (__x), "u" (__y) : "ax", "cc");   \ 
    return __value) 
#endif 

तो यह वास्तव में गणना के लिए एक समर्पित सीपीयू अनुदेश (fprem) का उपयोग करता है।

+0

ओह, मैं वास्तव में लागू करने की कोशिश कर रहा हूं कि एफएमओडी क्या करता है। यही मुद्दा है, मैं फ्लोटिंग पॉइंट के लिए मॉड्यूलस एल्गोरिदम की तलाश में हूं। – Veridian

+0

सबसे प्रत्यक्ष रूप शायद (मेरे पोस्ट में लिंक से लिया गया कोड है, लेकिन यह फ्लोटिंग पॉइंट के लिए मॉड्यूलस की परिभाषा है और इस प्रकार इसे करने का स्पष्ट तरीका है): टेम्पलेट <टाइपनाम टी> टी एफएमओडी (टी एक्स, टी वाई) { टी ए = (टी) (लंबा लंबा) (एक्स/वाई); वापसी एक्स - ए * वाई; } –

+0

मैं उस * y उत्पाद पर घूमने के बारे में थोड़ा चिंतित हूं, लेकिन मुझे यकीन नहीं है कि इसे कैसे कम किया जाए। – zmccord

12

शायद मुझे यहां बिंदु याद आ रही है, लेकिन क्या आपके पास fmod का उपयोग करने के विरुद्ध कुछ भी है?

double theta = 10.4; 
const double HALF_PI = 2 * atan(1); 
double result = fmod(theta, HALF_PI); 
+0

तब एक अपवर्तनीय मूल्य। –

+0

ओह, मैं वास्तव में कार्यान्वित करने की कोशिश कर रहा हूं कि एफएमओडी क्या करता है। यही मुद्दा है, मैं फ्लोटिंग पॉइंट के लिए मॉड्यूलस एल्गोरिदम की तलाश में हूं। – Veridian

+2

'fmod' ठीक है जब तक आप बड़े तर्कों के साथ सटीकता की परवाह नहीं करते हैं। – hirschhornsalz

7

एल्गोरिथ्म आप चाहते हैं, 0 और कुछ मापांक n जो चल बिन्दु value सीमित करने के लिए:

Double fmod(Double value, Double modulus) 
{ 
    return value - Trunc(value/modulus)*modulus; 
} 
उदाहरण pi mod e (3.14159265358979 आधुनिक 2,718281828459045)

3.14159265358979/2.718281828459045 
    = 1.1557273497909217179 

Trunc(1.1557273497909217179) 
    = 1 

1.1557273497909217179 - 1 
    = 0.1557273497909217179 

0.1557273497909217179 * e 
    = 0.1557273497909217179 * 2.718281828459045 
    = 0.42331082513074800 

अनुकरणीय आधुनिक के लिए

ई = 0.42331082513074800

+2

यह मेरे लिए विशेष रूप से सहायक था क्योंकि - प्रारंभिक प्रश्न सी/सी ++ प्रोग्रामिंग के संदर्भ में पूछा गया था, लेकिन मैं इस विशेष प्रश्न के लिए ऐसा करने के लिए एक सामान्य सूत्र की आवश्यकता थी एक निश्चित-बिंदु संख्या प्रणाली में मैं काम कर रहा हूं। मुझे खुशी है कि आपने इसे पोस्ट किया है, क्योंकि fmod() मेरी आवश्यकताओं का समाधान नहीं था, भले ही यह ओपी के लिए हो। ऐसे कुछ लोग हैं जिन्हें अन्य संदर्भों में इस विशेष सूत्र की आवश्यकता है। –

+0

यह [बड़े 'मूल्य के लिए बहुत गलत हो सकता है] (https://stackoverflow.com/questions/9505513/floating-point-modulo-operation/205077761) .comment12038890_9505761)। अधिक परिष्कृत एल्गोरिदम हैं। लेकिन यह आमतौर पर काफी तेज़ होगा, इसलिए यह एक अच्छा विकल्प है यदि यह आपके उपयोग के मामले के लिए संख्यात्मक रूप से ठीक है। –

संबंधित मुद्दे