2011-04-01 12 views
5

में NSDecimalNumber का उपयोग करते हुए मैं एक गणना है कि कुछ इस तरह चला जाता है की है। हालांकि, उद्देश्य-सी पर थोड़ी अधिक देखने के बाद, यह कई बार उल्लेख किया गया था कि मुद्रा की गणना करते समय आपको NSDecimalNumber का उपयोग करना चाहिए। मुद्दा रहा है कि मैं तुलना और बातों में इस 'मूल्य' चर का उपयोग, उदाहरण के लिए है:उद्देश्य-सी

if (deposit/price) < 0.2 
    return price*0.05; 

का उपयोग NSDecimalNumber इस एक बहुत अधिक कठिन बना देता है। जहां तक ​​मुझे पता है कि मुझे किसी भी जादू संख्या (इस मामले में 0.2 और 0.05) को NSDecimalNumber में परिवर्तित करना चाहिए, इसलिए मैं उनकी तुलना कर सकता हूं और NSDecimalMultiply जैसे कार्यों का उपयोग कर सकता हूं।

इसके अलावा

, अगर मैं एक समारोह है कि कुछ की तरह है:

return [minRandomPercentage decimalNumberByAdding:[[maxRandomPercentage decimalNumberBySubtracting: minRandomPercentage] decimalNumberByMultiplyingBy:random]] 

इस गंभीरता से कैसे उद्देश्य-सी है:

return (minRandomPercentage + ((maxRandomPercentage - minRandomPercentage) * (randomNumber) 

यह नेस्टेड समारोह की यह हास्यास्पद स्ट्रिंग कॉल की तरह होता जा रहा समाप्त होता है decimals के साथ सौदों? क्या कोई मुझे इस बारे में कोई संकेत दे सकता है कि इसे बहुत कम कठिन कैसे बनाया जाए? मैं नेस्टेड फंक्शन कॉल के साथ रह सकता हूं अगर मैं परिणाम के साथ तुलना कर सकता हूं और मेरे पास हर जादू संख्या कास्टिंग नहीं करना है।

+0

यदि आप मुद्रा से निपट रहे हैं, तो आप आदिम पूर्णांक डेटाटाइप के संदर्भ में क्यों काम नहीं कर रहे हैं? यदि आपके मूल्य "डॉलर" के बजाय "सेंट" में व्यक्त किए जाते हैं (अपना स्वयं का i18n विकल्प), तो आपको fractional मात्राओं के बारे में चिंता करने की आवश्यकता नहीं है। –

उत्तर

9

यदि आप rounding errors से निपटने का जोखिम नहीं उठा सकते हैं जो मानक बेस-2 फ़्लोटिंग पॉइंट प्रकारों के साथ हो सकता है, तो आपको NSDecimal या NSDecimalNumber का उपयोग करना होगा। एनएसडीसीमल एक सी संरचना है, और फाउंडेशन इसके साथ निपटने के लिए एक सी इंटरफ़ेस प्रदान करता है। यह कार्यों को प्रदान करता है NSDecimalAdd, NSDecimalMultiply, आदि

Number and Value Programming Guide से: यदि आप दशमलव संख्याओं को ऑब्जेक्ट्स के रूप में इलाज करने की आवश्यकता नहीं है, तो आप सी इंटरफ़ेस पर विचार कर सकते हैं-यानी, यदि आपको उन्हें स्टोर करने की आवश्यकता नहीं है ऑब्जेक्ट उन्मुख संग्रह एनएसएआरएआरई या एनएस डिक्शनरी के उदाहरण की तरह। यदि आपको अधिकतम दक्षता की आवश्यकता है तो आप सी इंटरफ़ेस पर भी विचार कर सकते हैं। सी इंटरफ़ेस तेज़ है और NSDecimalNumber क्लास की तुलना में कम स्मृति का उपयोग करता है।

यदि आप ऑब्जेक्ट उन्मुख कोड लिख रहे हैं, और आप बड़े पैमाने पर डेटा सेट के साथ बातचीत नहीं कर रहे हैं, तो NSDecimalNumber के साथ रहना सर्वोत्तम हो सकता है। यदि आप अपना कोड प्रोफाइल करते हैं और पाते हैं कि NSDecimalNumber का उपयोग उच्च मेमोरी ओवरहेड का कारण बन रहा है, तो आपको विकल्पों पर विचार करने की आवश्यकता हो सकती है।

यदि गोल त्रुटियां चिंता नहीं हैं, तो आप मूल सी स्केलर्स का भी उपयोग कर सकते हैं। देखें: How to add two NSNumber objects?

NSNumber और NSDecimalNumber ऑब्जेक्ट रैपर के रूप में उपयोग किए जाते हैं जब आपको किसी संग्रह में किसी विधि या स्टोर नंबरों को पास करने की आवश्यकता होती है। चूंकि एनएसएआरएआरई, एनएसएसएटी, एनएस डिक्शन इत्यादि केवल आपको 'आईडी' प्रकार की वस्तुओं को स्टोर करने की अनुमति देते हैं, इसलिए आप इनट्स, फ्लोट इत्यादि को मूल रूप से स्टोर नहीं कर सकते हैं।

यदि आप बड़े डेटा सेट से निपट रहे हैं और गोल करने वाली त्रुटियों का जोखिम उठा सकते हैं, तो आप इनट्स, फ्लोट्स, युगल इत्यादि कच्चे का उपयोग कर सकते हैं। फिर जब आपका नतीजा हो और आपको इसे स्टोर करने या उसे किसी अन्य ऑब्जेक्ट में पास करने की आवश्यकता हो, तो आप इसे एनएसएनंबर में तदनुसार लपेट सकते हैं।

यदि आपको संख्याओं के बड़े संग्रह को स्टोर करने की आवश्यकता है, तो एनएसएनंबर वस्तुओं को शुरू करने और स्टोर करने के बजाय सी एरे का उपयोग करना अधिक कुशल है।

+0

लेकिन अगर मैं स्केलर सी प्रकारों का उपयोग करता हूं तो मुझे दशमलव की सटीकता नहीं मिलती है? मेरा मानना ​​है कि सी में दशमलव प्रकार है, लेकिन इसके लिए हेडर उद्देश्य-सी लाइब्रेरी में मौजूद नहीं है ... – link664

+0

@ link664 - मैंने अपना जवाब स्पष्ट कर दिया है। –

1

गंभीरता से, आप आईओएस में आधार 10 अंकगणित कैसे करते हैं।जैसा कि आप शायद जानते हैं, बेस 10 में सटीक प्रतिनिधित्व करने वाले कई नंबरों में आधार 2 में सटीक प्रतिनिधित्व नहीं होते हैं, और इससे मुद्रा या मीट्रिक माप जैसे बेस 10 सिस्टम के साथ काम करते समय अस्वीकार्य गोलियां हो सकती हैं।

NSDecimalNumber द्वारा प्रतिनिधित्व किए गए मान वस्तुएं हैं, अंतर्निहित संख्यात्मक प्रकार जैसे int, float, और double के विपरीत। यह अंकगणितीय परिचालनों के तरीकों का उपयोग करने के लिए पहले अजीब लगता है, लेकिन जब आप वस्तुओं के रूप में मूल्यों के बारे में सोचना शुरू करते हैं तो यह अधिक समझ में आता है।

+0

तो क्या मुझे इनका उपयोग करने के लिए सभी जादू संख्याओं को परिवर्तित करना है? उदाहरण के लिए, मैं [NSDecimalNumber numberWithFloat: 0.25] कहने में सक्षम होना चाहता हूं, लेकिन यह मुझे एक चेतावनी देता है कि "असम्बद्ध सूचक प्रकार 'NSNumber *' को पैरामीटर प्रकार 'NSDecimalNumber *' पर भेजते हैं क्योंकि WithFloat एक NSNumber फ़ंक्शन है। – link664

+1

@ link664: http://stackoverflow.com/questions/453691/how-use-nsdecimalnumber/454562#454562 –