سؤال

عندما بدأت في برمجة تطبيقي الأول، استخدمت NSNumber للحصول على القيم المالية دون التفكير مرتين.ثم اعتقدت أنه ربما كانت أنواع C كافية للتعامل مع قيمي.ومع ذلك، فقد نصحني منتدى iPhone SDK باستخدام NSDecimalNumber، نظرًا لقدرات التقريب الممتازة التي يتمتع بها.

نظرًا لأنني لست عالم رياضيات بمزاج، فقد اعتقدت أن نموذج الجزء العشري/الأس قد يكون مبالغًا فيه؛ومع ذلك، أثناء البحث في Google، أدركت أن معظم المحادثات حول المال/العملة في الكاكاو تمت إحالتها إلى NSDecimalNumber.

لاحظ أن التطبيق الذي أعمل عليه سيتم تدويله، لذا فإن خيار حساب المبلغ بالسنتات ليس قابلاً للتطبيق حقًا، لأن البنية النقدية تعتمد بشكل كبير على اللغة المستخدمة.

أنا متأكد بنسبة 90% من أنني بحاجة إلى استخدام NSDecimalNumber، ولكن بما أنني لم أجد إجابة لا لبس فيها على الويب (شيء مثل:"إذا كنت تتعامل بالمال، فاستخدم NSDecimalNumber!") اعتقدت أنني سأسأل هنا.ربما تكون الإجابة واضحة للكثيرين، ولكنني أريد التأكد قبل البدء في عملية إعادة هيكلة واسعة النطاق لتطبيقي.

اقنعني :)

هل كانت مفيدة؟

المحلول

وماركوس زارا لديها موقف واضح جدا على هذا: <لأ href = "http://www.cimgf.com/2008/04/23/cocoa-tutorial-dont-be-lazy-with-nsdecimalnumber-like- لي / "يختلط =" noreferrer ">" إذا كنت تتعامل مع العملات في كل شيء، ثم يجب أن تكون باستخدام NSDecimalNumber ". مقالته ألهمني للنظر في NSDecimalNumber، وأنا معجب جدا به. IEEE العائمة أخطاء نقطة عند التعامل مع قاعدة 10 الرياضيات وقد غضب مني لبعض الوقت (1 * (0.5 - 0،4-0،1) = -،00000000000000002776). وNSDecimalNumber يلغي معهم

وNSDecimalNumber لا مجرد إضافة أرقام قليلة أخرى من ثنائية النقطة العائمة الدقة، فإنه في الواقع لا قاعدة 10 الرياضيات. هذا يتخلص من الأخطاء مثل واحد هو مبين في المثال أعلاه.

والآن، أنا أكتب تطبيق الرياضيات رمزي، لذلك رغبتي 30+ دقة أرقام عشرية ولا غريبة العائمة أخطاء نقطة قد تكون استثناء، ولكن أعتقد أنه يستحق النظر. العمليات هي أكثر من ذلك بقليل محرجا من بسيطة الرياضيات فار = 1 + 2 نمط، ولكنها لا تزال يمكن التحكم فيها. إذا كنت قلقة بشأن تخصيص جميع أنواع الحالات خلال عمليات الرياضيات، NSDecimal ما يعادل C البنية من NSDecimalNumber وهناك وظائف C للقيام بعمليات نفس الرياضيات بالضبط معها. في تجربتي، وهذه هي الكثير بسرعة للجميع ولكن التطبيقات الأكثر تطلبا (3344593 الإضافات / ثانية، 254017 الانقسامات / ثانية على ماك بوك اير، 281555 الإضافات / ثانية، 12027 الانقسامات / ثانية على اي فون).

واضاف باعتبارها مكافأة، descriptionWithLocale NSDecimalNumber ل: يوفر طريقة سلسلة مع إصدار مترجم من العدد، بما في ذلك الفاصل العشري الصحيح. وينطبق نفس الشيء في الاتجاه المعاكس لفي initWithString: لغة: طريقة

نصائح أخرى

نعم.عليك أن تستخدم

NSDecimalNumber و

لا مزدوج أو يطفو عندما تتعامل بالعملة على نظام iOS.

لماذا هذا؟؟

لأننا لا نريد الحصول على أشياء مثل $9.9999999998 بدلاً من $10

كيف يحدث ذلك؟؟

العوامات والزوجي هي تقريبية.أنها تأتي دائما مع خطأ التقريب.يتسبب التنسيق الذي تستخدمه أجهزة الكمبيوتر لتخزين الكسور العشرية في حدوث خطأ التوجيه هذا.إذا كنت بحاجة إلى مزيد من التفاصيل اقرأ

http://floating-point-gui.de/

وفقًا لمستندات Apple،

NSDecimalNumber هي فئة فرعية غير قابلة للتغيير من NSNumber، وتوفر غلافًا موجهًا للكائنات للقيام بعمليات حسابية على أساس 10.يمكن أن يمثل المثيل أي رقم يمكن التعبير عنه بالجزء العشري x 10^الأس حيث الجزء العشري عبارة عن عدد صحيح عشري يصل طوله إلى 38 رقمًا، والأس هو عدد صحيح من –128 إلى 127.wrapper لإجراء عمليات حسابية على أساس 10.

لذلك يوصى باستخدام NSDecimalNumber للتعامل مع العملة.

(مقتبس من تعليقي على الإجابة الأخرى.)

نعم يجب عليك.يعمل العدد الصحيح من البنسات فقط طالما أنك لا تحتاج إلى تمثيل نصف سنت على سبيل المثال.إذا حدث ذلك، يمكنك تغييره لحساب نصف سنت، ولكن ماذا لو كنت بحاجة بعد ذلك إلى تمثيل ربع سنت، أو ثمن سنت؟

الحل المناسب الوحيد هو NSDecimalNumber (أو شيء من هذا القبيل)، مما يؤجل المشكلة إلى 10^-128¢ (أي،
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000001¢).

(هناك طريقة أخرى تتمثل في إجراء عمليات حسابية دقيقة، ولكن ذلك يتطلب مكتبة منفصلة، ​​مثل مكتبة مكتبة GNU MP Bignum.GMP تحت LGPL.لم أستخدم هذه المكتبة مطلقًا ولا أعرف بالضبط كيف تعمل، لذلك لا أستطيع أن أقول مدى نجاحها بالنسبة لك.)

[يحرر:من الواضح أن شخصًا واحدًا على الأقل - براد لارسون - يعتقد أنني أتحدث عن الفاصلة العائمة الثنائية في مكان ما في هذه الإجابة.أنالست.]

وسؤال الأفضل هو عندما يجب أن <م> لا استخدام NSDecimalNumber للتعامل مع المال. الجواب باختصار على هذا السؤال هو، عندما كنت لا تستطيع تحمل النفقات العامة أداء NSDecimalNumber وكنت لا تهتم حول أخطاء التقريب الصغيرة لأنك لا تتعامل مع أكثر من بضعة أرقام من الدقة. الجواب أقصر هي، يجب عليك على دائما استخدام NSDecimalNumber عند التعامل مع المال.

ولقد وجدت أنه من المناسب استخدام صحيح لتمثيل عدد سنتا ثم القسمة على 100 لعرضها. يتجنب المسألة برمتها.

وفيزا، ماستركارد وغيرها تستخدم قيم الأعداد الصحيحة أثناء مروره المبالغ. والامر متروك المرسل والمتلقي لتحليل amouts بشكل صحيح وفقا لالأس العملات (الفجوة أو مضاعفة بنسبة 10 ^ الأسطوانات، حيث الأسطوانات - هو الأس العملة). لاحظ أن العملات المختلفة لها الأسس المختلفة. عادة انها 2 (ومن ثم نقسم وضرب من قبل 100)، ولكن بعض العملات لها الأس = 0 (VND، الخ)، أو = 3.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top