কেন এনএএন - NaN == 0.0 ইন্টেল সি ++ সংকলক সহ?


300

এটি সুপরিচিত যে ন্যানরা পাটিগণিতের মধ্যে প্রচার করে তবে আমি কোনও বিক্ষোভ খুঁজে পাইনি, তাই আমি একটি ছোট পরীক্ষা লিখেছি:

#include <limits>
#include <cstdio>

int main(int argc, char* argv[]) {
    float qNaN = std::numeric_limits<float>::quiet_NaN();

    float neg = -qNaN;

    float sub1 = 6.0f - qNaN;
    float sub2 = qNaN - 6.0f;
    float sub3 = qNaN - qNaN;

    float add1 = 6.0f + qNaN;
    float add2 = qNaN + qNaN;

    float div1 = 6.0f / qNaN;
    float div2 = qNaN / 6.0f;
    float div3 = qNaN / qNaN;

    float mul1 = 6.0f * qNaN;
    float mul2 = qNaN * qNaN;

    printf(
        "neg: %f\nsub: %f %f %f\nadd: %f %f\ndiv: %f %f %f\nmul: %f %f\n",
        neg, sub1,sub2,sub3, add1,add2, div1,div2,div3, mul1,mul2
    );

    return 0;
}

উদাহরণ ( এখানে সরাসরি চালানো ) মূলত যা প্রত্যাশা করে তা উত্পন্ন করে (নেতিবাচকটি কিছুটা অদ্ভুত, তবে এটি এক ধরণের অর্থ দেয়):

neg: -nan
sub: nan nan nan
add: nan nan
div: nan nan nan
mul: nan nan

এমএসভিসি 2015 অনুরূপ কিছু উত্পাদন করে। তবে, ইন্টেল সি ++ 15 উত্পাদন করে:

neg: -nan(ind)
sub: nan nan 0.000000
add: nan nan
div: nan nan nan
mul: nan nan

বিশেষত qNaN - qNaN == 0.0,।

এই ... ঠিক হতে পারে না, তাই না? প্রাসঙ্গিক মান (আইএসও সি, আইএসও সি ++, আইইইই 754) এ সম্পর্কে কী বলে এবং সংযোজকগুলির মধ্যে আচরণের মধ্যে কেন পার্থক্য রয়েছে?


18
জাভাস্ক্রিপ্ট এবং পাইথন (নমপি) এর আচরণ নেই। Nan-NaNহয় NaN। পার্ল এবং স্কালাও একইরকম আচরণ করে।
পল

33
হতে পারে আপনি অনিরাপদ গণিতের অপটিমাইজেশন ( -ffast-mathজিসিসির সমতুল্য ) সক্ষম করেছেন?
মাত্তেও ইটালিয়া

5
@ এনএম: সত্য নয়। আনেক্সেক্স এফ, যা সমর্থিত হলে butচ্ছিক তবে আদর্শিক এবং ভাসমান পয়েন্ট আচরণ নির্দিষ্টভাবে উল্লেখ করা প্রয়োজনীয়, আইইইই 754 কে সি

5
আপনি যদি আইইইই 754 মান সম্পর্কে জিজ্ঞাসা করতে চান তবে প্রশ্নের কোথাও এটি উল্লেখ করুন।
এন। 'সর্বনাম' মি।

68
আমি নিশ্চিত যে এই প্রশ্নটি শিরোনাম থেকে জাভাস্ক্রিপ্ট সম্পর্কে ছিল।
মাইক দ্য লাইয়ার

উত্তর:


300

ইনটেল সি ++ সংকলকটিতে ডিফল্ট ভাসমান পয়েন্ট হ্যান্ডলিংটি হ'ল /fp:fast, যা NaNঅনিরাপদভাবে পরিচালনা করে (এটি উদাহরণস্বরূপ NaN == NaNহওয়ার ফলেও আসে true)। নির্দিষ্ট করার চেষ্টা করুন /fp:strictবা /fp:preciseকর এবং দেখ যে যদি সাহায্য করে।


15
আমি নিজে এটি চেষ্টা করছিলাম। প্রকৃতপক্ষে, সমস্যাটি নির্দিষ্ট বা কঠোর সমাধানের জন্য নির্দিষ্ট করা।
imallett

67
আমি ডিফল্ট করার জন্য ইন্টেলের সিদ্ধান্তকে সমর্থন করতে চাই /fp:fast: আপনি যদি কিছু নিরাপদ চান তবে আপনার উচিত ভাল NaN গুলি প্রথম স্থানে সরে যাওয়া এবং সাধারণত ==ভাসমান-পয়েন্ট সংখ্যা ব্যবহার করা উচিত নয় । আইইইই 7575৫ এনএএনকে যে অদ্ভুত শব্দার্থিকতা অর্পণ করেছে তার উপর নির্ভর করে সমস্যা জিজ্ঞাসা করছে।
14:30 এ বাম দিকের বাইরে

10
@ বামফেরার চৌবাচ্চা: আইএনএইচএইওর ভয়ঙ্কর সিদ্ধান্ত বাদ দিয়ে, এনএএন-কে কী অদ্ভুত বলে মনে হচ্ছে!
সুপারক্যাট

21
NaN এর গুরুত্বপূর্ণ ব্যবহার রয়েছে - তারা প্রতিটি গণনার পরে পরীক্ষার প্রয়োজন ছাড়াই ব্যতিক্রমী পরিস্থিতি সনাক্ত করতে পারে। প্রতিটি ভাসমান-পয়েন্ট বিকাশকারী তাদের প্রয়োজন হয় না তবে তাদের বরখাস্ত করবেন না।
ব্রুস ডসন

6
@ সুপের্যাট কৌতূহলের বাইরে, আপনি কি NaN==NaNফিরে আসার সিদ্ধান্তের সাথে একমত false?
কাইল স্ট্র্যান্ড

53

এই . । । ঠিক হতে পারে না, তাই না? আমার প্রশ্ন: প্রাসঙ্গিক মান (আইএসও সি, আইএসও সি ++, আইইইই 754) এ সম্পর্কে কী বলে?

পেটর আবদুলিন ইতিমধ্যে উত্তর দিয়েছেন যে সংকলক একটি 0.0উত্তর দেয় কেন

আইইইই-754: ২০০ says এখানে যা বলেছে:

(.2.২ এনএএন সহ অপারেশনস) "[...] নিখুঁত এনএএন ইনপুট সহ অপারেশনের জন্য, সর্বাধিক এবং ন্যূনতম অপারেশন ব্যতীত, যদি কোনও ভাসমান-পয়েন্ট ফলাফল সরবরাহ করা হয় তবে একটি শান্ত এনএন হবে যা একটি হতে হবে ইনপুট NaNs। "

সুতরাং দুটি শান্ত NaN অপরেন্ডের বিয়োগের একমাত্র বৈধ ফলাফল একটি শান্ত NaN; অন্য কোনও ফলাফল বৈধ নয়।

সি স্ট্যান্ডার্ড বলেছেন:

(C11, F.9.2 এক্সপ্রেশন রূপান্তর p1) "[...]

x - x → 0. 0 "এক্স- এক্স এবং এক্স 0 এক্সপ্রেশন সমান হয় না যদি x একটি এনএএন বা অসীম হয়"

(যেখানে এখানে এনএএন F.2.1p1 অনুসারে একটি শান্ত NaN বোঝায় "এই স্পেসিফিকেশন NaNs সংকেত দেওয়ার আচরণ সংজ্ঞায়িত করে না। এটি সাধারণত শান্ত NaNs বোঝাতে NaN শব্দটি ব্যবহার করে")


20

যেহেতু আমি একটি উত্তর দেখতে পেয়েছি যে ইন্টেলের সংকলকটির মান মেনে চলার বিষয়টি উত্সাহিত করছে এবং অন্য কেউ এটি উল্লেখ করেনি, তাই আমি উল্লেখ করব যে জিসিসি এবং ক্ল্যাং উভয়েরই একটি মোড রয়েছে যাতে তারা বেশ কিছু অনুরূপ কাজ করে। তাদের ডিফল্ট আচরণটি আইইইই-সম্মতিযুক্ত -

$ g++ -O2 test.cc && ./a.out 
neg: -nan
sub: nan nan nan
add: nan nan
div: nan nan nan
mul: nan nan

$ clang++ -O2 test.cc && ./a.out 
neg: -nan
sub: -nan nan nan
add: nan nan
div: nan nan nan
mul: nan nan

- তবে আপনি যদি নির্ভুলতার ব্যয়ে গতি চেয়ে থাকেন তবে আপনি যা চান তা পেয়ে যান -

$ g++ -O2 -ffast-math test.cc && ./a.out 
neg: -nan
sub: nan nan 0.000000
add: nan nan
div: nan nan 1.000000
mul: nan nan

$ clang++ -O2 -ffast-math test.cc && ./a.out 
neg: -nan
sub: -nan nan 0.000000
add: nan nan
div: nan nan nan
mul: nan nan

আমি মনে করি আইসিসির ডিফল্ট বাছাইয়ের সমালোচনা করা সম্পূর্ণ ন্যায্য , তবে আমি এই সিদ্ধান্তের পুরো ইউনিক্স যুদ্ধগুলি পড়তে পারব না।


লক্ষ্য করুন যে সঙ্গে -ffast-math, gccআইএসও 9899 থেকে মেনে চলার নয়: ফ্লোটিং পয়েন্ট গাণিতিক কোন সম্মান সঙ্গে 2011।
ফুজ

1
@FUZxxl হ্যাঁ, মুল বক্তব্যটি হ'ল উভয় সংকলকের একটি অবিচ্ছিন্ন ভাসমান-পয়েন্ট মোড রয়েছে, এটি কেবলমাত্র সেই আইডিসিটি সেই মোডে ডিফল্ট হয় এবং জিসিসি হয় না।
zwol

4
কেবল আগুনে জ্বালানি ছড়িয়ে দিতে, আমি ডিফল্টরূপে দ্রুত গণিত সক্ষম করতে ইন্টেলের পছন্দ পছন্দ করি really ফ্লোটগুলি ব্যবহারের সম্পূর্ণ পয়েন্টটি হ'ল থ্রুপুট।
নবীন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.