'كونست تعويم' قيمة مختلفة من 'تعويم' عند الصب إلى 'كثافة العمليات' في ج#

StackOverflow https://stackoverflow.com//questions/24016294

  •  21-12-2019
  •  | 
  •  

سؤال

هل يمكن لأي منكم أن يشرح لماذا يحدث هذا?

static void Main()
{
    const float xScaleStart = 0.5f;
    const float xScaleStop = 4.0f;
    const float xScaleInterval = 0.1f;
    const float xScaleAmplitude = xScaleStop - xScaleStart;

    const float xScaleSizeC = xScaleAmplitude / xScaleInterval;

    float xScaleSize = xScaleAmplitude / xScaleInterval;

    Console.WriteLine(">const float {0}, (int){1}", xScaleSizeC, (int)xScaleSizeC);

    Console.WriteLine(">      float {0}, (int){1}", xScaleSize, (int)xScaleSize);

    Console.ReadLine();
}

الناتج:

>const float 35, (int)34
>      float 35, (int)35

وأنا أعلم أن التمثيل الثنائي من 0.1 هو في الواقع 0.09999990463256835937, على الرغم من لماذا يحدث هذا باستخدام 'كونست تعويم' وليس مع 'تعويم'?هل يعتبر هذا خطأ مترجم?

للسجل ، رمز يجمع في:

private static void Main(string[] args)
{
    float xScaleSize = 35f;
    Console.WriteLine(">const float {0}, (int){1}", 35f, 34);
    Console.WriteLine(">      float {0}, (int){1}", xScaleSize, (int)xScaleSize);
    Console.ReadLine();
}
هل كانت مفيدة؟

المحلول

و "لماذا" من هذا سوف تختزل أساسا إلى حقيقة أنه في كثير من الأحيان ، عند العمل مع float البيانات ، يمكن استخدام تمثيل داخلي له دقة أكبر مما هو محدد لـ float أو double.يتم تلبية هذا صراحة في نظام التنفيذ الظاهري (فيس) المواصفات (القسم 12 من القسم الأول):

يتم تمثيل أرقام الفاصلة العائمة باستخدام نقطة عائمة داخلية اكتب.في كل حالة من هذه الحالات ، يكون النوع الاسمي للمتغير أو التعبير إما float32 أو float64, ، ولكن لها يمكن تمثيل القيمة داخليا بنطاق و/أو دقة إضافية

ثم في وقت لاحق لدينا:

استخدام تمثيل داخلي أوسع من float32 أو float64 يمكن أن يسبب اختلافات في النتائج الحسابية عندما يقوم المطور بإجراء تعديلات تبدو غير ذات صلة على التعليمات البرمجية الخاصة به ، نتيجة والتي يمكن أن تكون عبارة عن انسكاب قيمة من التمثيل الداخلي (على سبيل المثال ، في السجل) إلى موقع على كومة.

الآن ، وفقا ل ج # مواصفات اللغة:

يستخدم تقييم وقت الترجمة للتعبيرات الثابتة نفس القواعد مثل تقييم وقت التشغيل للتعبيرات غير الثابتة ، باستثناء أنه في حالة وجود استثناء في تقييم وقت التشغيل ، يتسبب تقييم وقت الترجمة في حدوث خطأ في وقت الترجمة.

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


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

نصائح أخرى

لا أستطيع أن أقول هذا هو سؤال مكرر منذ هنا --> إريك Postpischil التعليق

وأوضح شيء مشابه جدا فيما يتعلق الباحث و const int هو.

الفكرة الرئيسية هي أن تقسيم اثنين من الثوابت محسوبة من قبل المترجم قبل توليد رمز وليس في وقت التشغيل ، ولكن في هذه الحالة المحددة كلما مترجم هل هذا ينفذ العمليات الحسابية في مزدوج تنسيق.وبالتالي xScaleSizeC هو في الأساس يساوي 34.9999...لذلك عندما تحصل على المدلى بها في وقت التشغيل إلى int يصبح 34.

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