سؤال

لدي برنامج يحاول تقليص أ double وصولاً إلى الرقم المطلوب. الإخراج الذي أحصل عليه NaN.

ماذا فعلت NaN يعني في جافا؟

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

المحلول

مأخوذ من هذه الصفحة:

"نان" تعني "ليس رقمًا". يتم إنتاج "NAN" إذا كانت عملية النقطة العائمة تحتوي على بعض معلمات الإدخال التي تتسبب في أن تؤدي العملية إلى إنتاج بعض النتائج غير المحددة. على سبيل المثال ، 0.0 مقسوم على 0.0 غير محدد الحسابي. أخذ الجذر التربيعي لعدد سالب غير محدد أيضًا.

نصائح أخرى

NaN يعني "ليس رقمًا" وهو في الأساس تمثيل لقيمة نقطة عائمة خاصة في IEE 754 نقطة عائمة اساسي. نان يعني بشكل عام أن القيمة هي شيء لا يمكن التعبير عنه برقم عائم صالح.

سيؤدي التحويل إلى هذه القيمة ، عندما تكون القيمة التي يتم تحويلها شيء آخر ، على سبيل المثال عند تحويل سلسلة لا تمثل رقمًا.

NaN يعني "ليس رقمًا" وهو نتيجة للعمليات غير المحددة على أرقام النقاط العائمة مثل تقسيم الصفر على الصفر. (لاحظ أنه في حين أن تقسيم رقم غير صفري على الصفر عادة ما يكون غير محدد أيضًا في الرياضيات ، فإنه لا يؤدي إلى NAN ولكن في اللانهاية الإيجابية أو السلبية).

NaN يعني "ليس رقمًا". إنها قيمة عائمة خاصة تعني أن نتيجة العملية لم يتم تعريفها أو عدم تمثيلها كرقم حقيقي.

يرى هنا لمزيد من التفسير لهذه القيمة.

NAN لا يوجد رقم. يتم استخدامه للدلالة على أي قيمة غير محددة رياضيا. مثل تقسيم 0.0 على 0.0. يمكنك البحث هنا لمزيد من المعلومات: https://web.archive.org/web/20120819091816/http://www.concentric.net/~ttwang/tech/javafloat.htm

انشر برنامجك هنا إذا كنت بحاجة إلى مزيد من المساعدة.

نان = ليس رقمًا.

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

ليس رجل Java ، ولكن في JS واللغات الأخرى التي أستخدمها "ليس رقمًا" ، مما يعني أن بعض العمليات تسببت في أن تصبح رقمًا صالحًا.

وهذا يعني حرفيا "ليس رقمًا". أظن أن هناك خطأ ما في عملية التحويل الخاصة بك.

تحقق من قسم الأرقام في هذه المرجع

ليست قيمة فاصلة صالحة (على سبيل المثال نتيجة الانقسام بواسطة الصفر)

http://en.wikipedia.org/wiki/nan

مثال قابلة للتشغيل الحد الأدنى

أول ما عليك معرفته ، هو أن مفهوم NAN يتم تنفيذه مباشرة على أجهزة وحدة المعالجة المركزية.

يبدو أن جميع وحدات المعالجة المركزية الرئيسية الحديثة تتبع IEEE 754 الذي يحدد تنسيقات النقاط العائمة ، و NANS ، والتي هي مجرد قيم تعويم خاصة ، هي جزء من هذا المعيار.

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

قبل المتابعة ، قد ترغب أولاً في قراءة الإجابات التالية التي كتبتها أولاً:

الآن لبعض عمل جافا. معظم وظائف الاهتمام التي ليست في اللغة الأساسية تعيش في الداخل java.lang.Float.

نان

import java.lang.Float;
import java.lang.Math;

public class Nan {
    public static void main(String[] args) {
        // Generate some NaNs.
        float nan            = Float.NaN;
        float zero_div_zero  = 0.0f / 0.0f;
        float sqrt_negative  = (float)Math.sqrt(-1.0);
        float log_negative   = (float)Math.log(-1.0);
        float inf_minus_inf  = Float.POSITIVE_INFINITY - Float.POSITIVE_INFINITY;
        float inf_times_zero = Float.POSITIVE_INFINITY * 0.0f;
        float quiet_nan1     = Float.intBitsToFloat(0x7fc00001);
        float quiet_nan2     = Float.intBitsToFloat(0x7fc00002);
        float signaling_nan1 = Float.intBitsToFloat(0x7fa00001);
        float signaling_nan2 = Float.intBitsToFloat(0x7fa00002);
        float nan_minus      = -nan;

        // Generate some infinities.
        float positive_inf   = Float.POSITIVE_INFINITY;
        float negative_inf   = Float.NEGATIVE_INFINITY;
        float one_div_zero   = 1.0f / 0.0f;
        float log_zero       = (float)Math.log(0.0);

        // Double check that they are actually NaNs.
        assert  Float.isNaN(nan);
        assert  Float.isNaN(zero_div_zero);
        assert  Float.isNaN(sqrt_negative);
        assert  Float.isNaN(inf_minus_inf);
        assert  Float.isNaN(inf_times_zero);
        assert  Float.isNaN(quiet_nan1);
        assert  Float.isNaN(quiet_nan2);
        assert  Float.isNaN(signaling_nan1);
        assert  Float.isNaN(signaling_nan2);
        assert  Float.isNaN(nan_minus);
        assert  Float.isNaN(log_negative);

        // Double check that they are infinities.
        assert  Float.isInfinite(positive_inf);
        assert  Float.isInfinite(negative_inf);
        assert !Float.isNaN(positive_inf);
        assert !Float.isNaN(negative_inf);
        assert one_div_zero == positive_inf;
        assert log_zero == negative_inf;
            // Double check infinities.

        // See what they look like.
        System.out.printf("nan            0x%08x %f\n", Float.floatToRawIntBits(nan           ), nan           );
        System.out.printf("zero_div_zero  0x%08x %f\n", Float.floatToRawIntBits(zero_div_zero ), zero_div_zero );
        System.out.printf("sqrt_negative  0x%08x %f\n", Float.floatToRawIntBits(sqrt_negative ), sqrt_negative );
        System.out.printf("log_negative   0x%08x %f\n", Float.floatToRawIntBits(log_negative  ), log_negative  );
        System.out.printf("inf_minus_inf  0x%08x %f\n", Float.floatToRawIntBits(inf_minus_inf ), inf_minus_inf );
        System.out.printf("inf_times_zero 0x%08x %f\n", Float.floatToRawIntBits(inf_times_zero), inf_times_zero);
        System.out.printf("quiet_nan1     0x%08x %f\n", Float.floatToRawIntBits(quiet_nan1    ), quiet_nan1    );
        System.out.printf("quiet_nan2     0x%08x %f\n", Float.floatToRawIntBits(quiet_nan2    ), quiet_nan2    );
        System.out.printf("signaling_nan1 0x%08x %f\n", Float.floatToRawIntBits(signaling_nan1), signaling_nan1);
        System.out.printf("signaling_nan2 0x%08x %f\n", Float.floatToRawIntBits(signaling_nan2), signaling_nan2);
        System.out.printf("nan_minus      0x%08x %f\n", Float.floatToRawIntBits(nan_minus     ), nan_minus     );
        System.out.printf("positive_inf   0x%08x %f\n", Float.floatToRawIntBits(positive_inf  ), positive_inf  );
        System.out.printf("negative_inf   0x%08x %f\n", Float.floatToRawIntBits(negative_inf  ), negative_inf  );
        System.out.printf("one_div_zero   0x%08x %f\n", Float.floatToRawIntBits(one_div_zero  ), one_div_zero  );
        System.out.printf("log_zero       0x%08x %f\n", Float.floatToRawIntBits(log_zero      ), log_zero      );

        // NaN comparisons always fail.
        // Therefore, all tests that we will do afterwards will be just isNaN.
        assert !(1.0f < nan);
        assert !(1.0f == nan);
        assert !(1.0f > nan);
        assert !(nan == nan);

        // NaN propagate through most operations.
        assert Float.isNaN(nan + 1.0f);
        assert Float.isNaN(1.0f + nan);
        assert Float.isNaN(nan + nan);
        assert Float.isNaN(nan / 1.0f);
        assert Float.isNaN(1.0f / nan);
        assert Float.isNaN((float)Math.sqrt((double)nan));
    }
}

Github upstream.

تشغيل مع:

javac Nan.java && java -ea Nan

انتاج:

nan            0x7fc00000 NaN
zero_div_zero  0x7fc00000 NaN
sqrt_negative  0xffc00000 NaN
log_negative   0xffc00000 NaN
inf_minus_inf  0x7fc00000 NaN
inf_times_zero 0x7fc00000 NaN
quiet_nan1     0x7fc00001 NaN
quiet_nan2     0x7fc00002 NaN
signaling_nan1 0x7fa00001 NaN
signaling_nan2 0x7fa00002 NaN
nan_minus      0xffc00000 NaN
positive_inf   0x7f800000 Infinity
negative_inf   0xff800000 -Infinity
one_div_zero   0x7f800000 Infinity
log_zero       0xff800000 -Infinity

لذلك من هذا نتعلم بعض الأشياء:

  • العمليات العائمة الغريبة التي ليس لديها أي نتيجة معقولة تعطي نان:

    • 0.0f / 0.0f
    • sqrt(-1.0f)
    • log(-1.0f)

    توليد أ NaN.

    في C ، من الممكن في الواقع طلب الإشارات التي تربى على هذه العمليات مع feenableexcept للكشف عنها ، لكنني لا أعتقد أنه مكشوف في جافا: لماذا يعطي تقسيم عدد صحيح من الصفر 1/0 خطأ ولكن النقطة العائمة 1/0.0 تعود "INF"؟

  • العمليات الغريبة التي تقع على حد إما زائد أو ناقص اللانهاية ، ولكن تعطي +- اللانهاية بدلاً من النان

    • 1.0f / 0.0f
    • log(0.0f)

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

  • إذا كان NAN هو إدخال عملية عائمة ، فإن الإخراج يميل أيضًا إلى أن يكون نان

  • هناك العديد من القيم المحتملة لل NAN 0x7fc00000, 0x7fc00001, 0x7fc00002, ، على الرغم من أن x86_64 يبدو أنه يولد فقط 0x7fc00000.

  • نان واللفيني لديهم تمثيل ثنائي مماثل.

    دعنا نتفكك بعضهم:

    nan          = 0x7fc00000 = 0 11111111 10000000000000000000000
    positive_inf = 0x7f800000 = 0 11111111 00000000000000000000000
    negative_inf = 0xff800000 = 1 11111111 00000000000000000000000
                                | |        |
                                | |        mantissa
                                | exponent
                                |
                                sign
    

    من هذا نؤكد ما يحدده IEEE754:

    • كل من NAN و Infinities لهما الأسس == 255 (كل ذلك)
    • اللانهائيات لها mantissa == 0. لذلك لا يوجد سوى اثنين من اللانهائيات الممكنة: + و -، متباينة عن بت.
    • نان لديه mantissa! = 0. هناك العديد من الاحتمالات ، باستثناء mantissa == 0 وهو ما لا نهاية
  • يمكن أن تكون NANs إيجابية أو سلبية (الجزء العلوي) ، على الرغم من أنه ليس له أي تأثير على العمليات العادية

تم اختباره في Ubuntu 18.10 AMD64 ، OpenJDK 1.8.0_191.

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