سؤال

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

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

ما أفكر فيه حاليًا هو أنه يمكنني كتابة برنامج c++ صغير لزيادة الرقم ببطء حتى يحدث التجاوز، لكنني لست متأكدًا من نوع الرقم الذي يجب استخدامه.

هل أنا على الطريق الصحيح؟كيف يمكن للمرء بالضبط حساب هذا؟

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

المحلول

وأعتقد أن كل ما اللغة التي كانت تستخدم من شأنه تحديد كيف تم تخزينها عوامات. وأنا أعلم جافا تفعل ذلك عن طريق استخدام معيار IEEE معين (754، على ما أظن).

إذا ليس تحديده، وأود أن تعتقد أنك يمكن أن مجرد القيام الاختيار الخاصة بك عن طريق إضافة 0،5-1 لمعرفة ما إذا كان يتغير العدد الفعلي. إذا كان كذلك، ثم إضافة ،25-1، و0،125-1، وهلم جرا حتى لا يتغير العدد، شيء من هذا القبيل:

float a = 1;
float b = 0.5;
int bits = 0;
while (a + b != a) {
    bits = bits + 1;
    b = b / 2;
}

إذا كان لديك فقط 3 بت العشري، ثم 1 + 16/01 سيكون يساوي 1.

وبعد ذلك كنت قد استنفدت بت العشري الخاص بك.

هل يمكن فعلا بحاجة إلى رقم الأساس هو 2 بدلا من 1، منذ IEEE754 يستخدم ضمنية "1+" في البداية.

وتحرير:

ويبدو أن الطريقة المذكورة أعلاه قد يكون لها بعض القضايا لأنها تعطي 63 بت لنظام بشكل واضح 4 بايت عوامات.

وإذا كان هذا هو أن تفعل مع نتائج المتوسطة (أشك في ذلك لأن نفس رمز مع يلقي صريحة [while (((float)(a + b) != (float)(a))] لديه مشاكل مماثلة) أو (على الأرجح، أعتقد) إمكانية أن a قيمة الوحدة يمكن تمثيل مع بت أقرب إلى وb كسور عن طريق ضبط الأس، وأنا لا أعرف حتى الآن.

والآن، فمن الأفضل أن تعتمد على معلومات اللغة التي ذكرتها أعلاه مثل استخدام IEEE754 (إذا كانت هذه المعلومات غير متوفرة).

وسأترك رمز مشكلة في كفخ للاعبين الحذر. ربما شخص ما مع مزيد من المعرفة نقطة عائمة ثم لا أستطيع ترك مذكرة شرح لماذا يتصرف بغرابة (لا التخمين، يرجى: -).

وتحرير 2:

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

#include <stdio.h>
#include <float.h>

int main(void) {
    float a = 1;
    float b = 0.5;
    float c = a + b;
    int bits = 1;
    while (c != a) {
        bits = bits + 1;
        b = b / 2;
        c = a + b;
    }
    printf("%d\n",FLT_MANT_DIG);
    printf("%d\n",bits);
    return 0;

و}

ومخرجات هذا الرمز (24،24) لتدل على أن القيمة المحسوبة مباريات واحد في ملف الرأس.

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

نصائح أخرى

بالنسبة إلى لغة C وبامتداد C++، تكون المعلومات موجودة في ملف <float.h> أو <cfloat> رؤوس.

بالنسبة لـ C99، المعلومات موجودة في القسم 5.2.4.2.2 من المعيار:

  • FLT_RADIX
  • FLT_MANT_DIG
  • FLT_DIG
  • FLT_EPSILON
  • FLT_MIN_EXP
  • FLT_MIN
  • FLT_MIN_10_EXP
  • FLT_MAX_EXP
  • FLT_MAX
  • FLT_MAX_10_EXP

وبالمثل بالنسبة لاختلافات DBL وLDBL في معظمها (لا DBL_RADIX أو LDBL_RADIX).يقترح المعيار القيم المناسبة لـ IEEE 754 (الإصدار الأقدم من معيار IEEE 754 الذي كان ساريًا في عام 1999؛وكانت هناك نسخة جديدة نشرت في عام 2008 على ما أعتقد).

وأنت قد ترغب في التحقق من <limits> في C ++ الخاص مكتبة:

#include <iostream>
#include <limits>
#include <typeinfo>

template <typename T>
void printDetailsFor() {
    std::cout
        << "Printing details for " << typeid(T).name() << ":\n"
        << "\tradix:        " << std::numeric_limits<T>::radix        << "\n"
        << "\tradix digits: " << std::numeric_limits<T>::digits       << "\n"
        << "\tepsilon:      " << std::numeric_limits<T>::epsilon()    << "\n"
        << std::endl;
}

int main() {
    printDetailsFor<int>();
    printDetailsFor<float>();
    printDetailsFor<double>();
    printDetailsFor<long double>();
    return 0;
}

وأعتقد أنك تريد std::numeric_limits<T>::digits التي ينبغي أن تكون واحدة أكثر من عدد البتات العشري. الجهاز الخاص بي بطباعة الخروج:

Printing details for i:
    radix:        2
    radix digits: 31
    epsilon:      0

Printing details for f:
    radix:        2
    radix digits: 24
    epsilon:      1.19209e-07

Printing details for d:
    radix:        2
    radix digits: 53
    epsilon:      2.22045e-16

Printing details for e:
    radix:        2
    radix digits: 64
    epsilon:      1.0842e-19
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top