سؤال

أنا أكتب التطبيقات المالية حيث كنت معركة باستمرار قرار استخدام مزدوج مقابل استخدام عشري.

كل من الرياضيات يعمل على الأرقام مع أكثر من 5 خانات عشرية و ليست أكبر من ~100,000.لدي شعور بأن كل من هذه يمكن أن تكون ممثلة على النحو الزوجي على أي حال دون خطأ التقريب ، ولكن لم تكن متأكدا.

وأود أن تذهب إلى الأمام وجعل التحول من عشرية إلى الزوجي هو واضح ميزة السرعة, إلا أنه في نهاية اليوم, أنا لا تزال تستخدم ToString طريقة لنقل الأسعار إلى البورصات و في حاجة للتأكد من أنها دائما النواتج عدد أتوقع.(89.99 بدلا من 89.99000000001)

الأسئلة:

  1. هو ميزة السرعة حقا كبيرة بقدر من السذاجة الاختبارات توحي ؟ (~100 مرات)
  2. هل هناك طريقة لضمان الإخراج من ToString إلى ما أريد ؟ هذا تتأكدوا من حقيقة أن رقمي هو دائما قابل للتمثيل?

تحديث:يجب أن العملية ~ 10 مليار تحديثات السعر قبل التطبيق يمكن تشغيلها, و لقد نفذت مع العشرية الآن واضحة واقية الأسباب ، لكنه يأخذ ~3 ساعات فقط لتشغيل ، يضاعف من شأنه الحد بشكل كبير من دورى على الوقت.هل هناك طريقة آمنة للقيام بذلك مع مضاعف ؟

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

المحلول

  1. حساب النقطة العائمة ستكون دائما تقريبا بشكل أسرع لأنه المدعومة مباشرة من قبل الأجهزة.حتى الآن تقريبا لا تستخدم على نطاق واسع في الأجهزة تدعم عشري الحسابية (على الرغم من أن هذا التغير ، انظر التعليقات).
  2. التطبيقات المالية أن دائما استخدام الأرقام العشرية عدد من قصص الرعب الناجمة عن استخدام النقطة العائمة في التطبيقات المالية التي لا نهاية لها ، يجب أن تكون قادرة على العثور على العديد من هذه الأمثلة مع بحث Google.
  3. في حين عشري الحساب قد يكون أبطأ بكثير من حساب النقطة العائمة, إلا إذا كنت تنفق قدرا كبيرا من الوقت في معالجة بيانات عشري تأثير على البرنامج الخاص بك من المرجح أن تكون ضئيلة.كما هو الحال دائما, هل المناسبة التنميط قبل أن تبدأ بالقلق الفرق.

نصائح أخرى

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

أما عن تمثيل دقيق, أنت على حق أن يكون حذرا لأن الدقيق عشري مثل 1/10 لديه الدقيق الثنائية نظيره.ومع ذلك, إذا كنت تعرف أن كنت بحاجة فقط 5 أرقام عشرية من الدقة ، يمكنك استخدام تحجيم الحساب الذي كنت تعمل على أرقام مضروبة في 10^5.هكذا على سبيل المثال إذا كنت تريد أن تمثل 23.7205 بالضبط ذلك كما 2372050.

دعونا نرى إذا كان هناك ما يكفي من الدقة:الدقة المزدوجة يعطيك 53 أجزاء من الدقة.هذا هو ما يعادل 15+ الأرقام العشرية من الدقة.لذلك هذا من شأنه أن تسمح لك خمسة أرقام بعد العلامة العشرية و 10 خانات قبل الفاصلة العشرية ، والتي يبدو وافرة للتطبيق الخاص بك.

وأود أن وضع هذا الكود في ملف .ساعة الملف:

typedef double scaled_int;

#define SCALE_FACTOR 1.0e5  /* number of digits needed after decimal point */

static inline scaled_int adds(scaled_int x, scaled_int y) { return x + y; }
static inline scaled_int muls(scaled_int x, scaled_int y) { return x * y / SCALE_FACTOR; }

static inline scaled_int scaled_of_int(int x) { return (scaled_int) x * SCALE_FACTOR; }
static inline int intpart_of_scaled(scaled_int x) { return floor(x / SCALE_FACTOR); }
static inline int fraction_of_scaled(scaled_int x) { return x - SCALE_FACTOR * intpart_of_scaled(x); }

void fprint_scaled(FILE *out, scaled_int x) {
  fprintf(out, "%d.%05d", intpart_of_scaled(x), fraction_of_scaled(x));
}

ربما يكون هناك عدد قليل من البقع الخام ولكن هذا ينبغي أن يكون كافيا للحصول على انك بدأته.

أي النفقات العامة بالنسبة إلى تكلفة مضاعفة أو تقسيم الزوجي.

إذا كان لديك الوصول إلى C99, يمكنك أيضا محاولة تحجيم عدد صحيح الحسابية باستخدام int64_t 64 بت من نوع عدد صحيح.وهو أسرع سيعتمد على منصة الأجهزة الخاصة بك.

دائما استخدام عشري عن أي حسابات مالية أو سوف يكون إلى الأبد مطاردة 1المائة أخطاء التقريب.

  1. نعم ؛ البرامج الحسابية حقا هو 100 مرات أبطأ من الأجهزة.أو على الأقل هو أبطأ كثيرا ، عامل 100 أو أمر من حجم ، هو عن الحق.مرة أخرى في الأيام القديمة السيئة عندما كنت لا يمكن أن نفترض أن كل 80386 كان 80387 النقطة العائمة co-processor, ثم كنت قد محاكاة البرمجيات الثنائية النقطة العائمة أيضا ، و التي كانت بطيئة.
  2. لا ؛ كنت تعيش في أرض الخيال إذا كنت تعتقد أن نقي ثنائي النقطة العائمة يمكن من أي وقت مضى بالضبط تمثل جميع الأرقام العشرية.الأرقام الثنائية يمكن الجمع بين نصفين ، أرباع وأثمان ، إلخ ، ولكن منذ الدقيقة عشري من 0.01 يتطلب عاملين من أحد الخامسة عامل واحد من الربع (1/100 = (1/4)*(1/5)*(1/5)) و منذ خمس لا التمثيل الدقيق في الثنائية ، أنت لا تمثل بالضبط كل القيم العشرية مع القيم الثنائية (لأن 0.01 هو المثال والمثال الذي لا يمكن أن تكون ممثلة بالضبط لكن هو ممثل فئة كبيرة من الأرقام العشرية التي لا يمكن أن تكون ممثلة بالضبط).

لذلك عليك أن تقرر ما إذا كان يمكنك التعامل مع التقريب قبل الاتصال ToString() أو إذا كنت بحاجة إلى إيجاد آلية التعامل مع التقريب النتائج الخاصة بك كما يتم تحويلها إلى سلسلة.أو يمكنك الاستمرار في استخدام عشري الحساب لأنه سوف تظل دقيقة, و سوف تحصل على أسرع مرة آلات صدر هذا الدعم الجديد IEEE 754 عشري الحساب في الأجهزة.

واجب المرجعية: ما كل عالم الكمبيوتر يجب أن تعرف عن حساب الفاصلة العائمة.هذا هو واحد من العديد من عناوين المواقع.

معلومات عن العشرية الحساب الجديد IEEE 754:2008 القياسية في هذا Speleotrove الموقع.

مجرد استخدام طويلة و ضرب من قبل قوة من 10.بعد الانتهاء من ذلك ، القسمة على نفس القوة من 10.

العشرية ينبغي دائما أن تستخدم في الحسابات المالية.حجم الأرقام ليست مهمة.

أسهل طريقة بالنسبة لي أن أشرح عبر بعض التعليمات البرمجية C#.

double one = 3.05;
double two = 0.05;

System.Console.WriteLine((one + two) == 3.1);

أن قليلا من التعليمات البرمجية سوف طباعة كاذبة على الرغم من 3.1 يساوي 3.1...

نفس الشيء...ولكن باستخدام عشري:

decimal one = 3.05m;
decimal two = 0.05m;

System.Console.WriteLine((one + two) == 3.1m);

هذا الآن طباعة صحيح!

إذا كنت ترغب في تجنب هذا النوع من المشكلة ، أنصحك عصا مع الكسور العشرية.

أود أن أشير لك جوابي تعطى هذا السؤال.

استخدام طويلة, تخزين أصغر كمية تحتاج إلى تتبع ، وعرض القيم وفقا لذلك.

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