সি-তে ন্যান এবং ইনফ কীভাবে ব্যবহার করবেন?


91

আমার কাছে একটি সাংখ্যিক পদ্ধতি রয়েছে যা কোনও ত্রুটি থাকলে নান বা ইনফ ফিরে আসতে পারে, এবং পরীক্ষা করার জন্য আমি পরিস্থিতিটি সঠিকভাবে পরিচালিত হচ্ছে কিনা তা নিশ্চিত করতে আমি সাময়িকভাবে এটিকে ন্যান বা ইনফ ফিরে আসতে বাধ্য করতে চাই। সি-তে ন্যান এবং ইনফের মান তৈরি করার জন্য কি কোনও নির্ভরযোগ্য, সংকলক-স্বাধীন উপায় আছে?

প্রায় 10 মিনিট ধরে গুগল করার পরে আমি কেবল সংকলক নির্ভর সমাধান পেতে সক্ষম হয়েছি।


ভাসমানগুলি সি স্ট্যান্ডার্ড দ্বারা সংজ্ঞায়িত হয় না। সুতরাং আপনি যা চান তা করার কোনও সংকলক-স্বাধীন উপায় নেই।
জোহান কোটলিনস্কি

উত্তর:


87

আপনার প্রয়োগে এটি রয়েছে কিনা আপনি পরীক্ষা করতে পারেন:

INFINITYসি 99 এর অস্তিত্বের গ্যারান্টি রয়েছে (বা সর্বশেষতম খসড়াটি অন্তত) এবং "ধরণী ধাপের ধ্রুবক বা স্বাক্ষরিত অসীম প্রতিনিধিত্ব করে যদি এটি পাওয়া যায় তবে ধ্রুবক ধরণের অভিব্যক্তিতে প্রসারিত হয়; অন্যথায় অনুবাদের সময় প্রবাহিত ধরণের ধনাত্মক ধ্রুবকে"

NAN সংজ্ঞায়িত হতে পারে বা নাও হতে পারে এবং "সংজ্ঞায়িত হয় কেবলমাত্র এবং যদি বাস্তবায়নটি ফ্লোট ধরণের জন্য শান্ত NaNs সমর্থন করে It

মনে রাখবেন যে আপনি যদি ভাসমান পয়েন্টের মানগুলি তুলনা করছেন, এবং করুন:

অথচ,

মিথ্যা। NaN এর জন্য চেক করার একটি উপায় হ'ল:

আপনি এটিও করতে পারেন: a != aযদি পরীক্ষাগুলি না aহয় তবে ।

রয়েছে isfinite(), isinf(), isnormal(), এবং signbit()এ ম্যাক্রো math.hC99 হবে।

C99 এরও nanকার্য রয়েছে:

(তথ্যসূত্র: n1256)।

দস্তাবেজগুলি ইনফিনিটি ডক্স এনএএন


4
দুর্দান্ত উত্তর। এনএএন এবং ইনফিনিটি ম্যাক্রোগুলির জন্য রেফারেন্স সি 99 997.12 অনুচ্ছেদ 4 এবং 5 রয়েছে। (ইসানান (ক)) আপনি সি এর যথাযথ প্রয়োগের জন্য (এ! = ক) ব্যবহার করেও এনএএন পরীক্ষা করতে পারেন
স্টিফেন ক্যানন

24
পাঠযোগ্যতার ভালবাসার জন্য, কখনও ব্যবহার করা a != aউচিত নয় ।
ক্রিস কেরিকস

4
@ ক্রিসকারিক্স: দুঃখের বিষয়, আমাদের কারও কারও কাছে এনএএন রয়েছে তবে ইসানান নেই ()। হ্যাঁ, এই 2017. :( হয়
EFF

মিথ্যা ফিরতে সি-এর কখনই কোনও aসংখ্যা a == NANনয়- আইইইই এটির প্রয়োজন। এমনকি বাস্তবায়ন যা আইইইই মেনে চলে, বেশিরভাগ ক্ষেত্রেই তা করে । যখন isnan()বাস্তবায়ন করা হয় না, সরাসরি কোডের চেয়ে পরীক্ষাটি মোড়ানো ভাল a == NAN
chux -

34

এটি করার কোনও সংকলক স্বতন্ত্র উপায় নেই, কারণ সি (বা সি ++) মানের কোনওটিই বলে না যে ভাসমান পয়েন্ট গণিতের ধরণগুলি অবশ্যই এনএএন বা আইএনএফ সমর্থন করে।

সম্পাদনা করুন: আমি সবেমাত্র সি ++ স্ট্যান্ডার্ডের শব্দটি পরীক্ষা করে দেখেছি এবং এটিতে বলা হয়েছে যে এই ফাংশনগুলি (টেম্প্লেটেড ক্লাসের সংখ্যাসূচক_মিলিট সদস্য):

উইল এনএএন উপস্থাপনাগুলি "যদি পাওয়া যায়" ফিরিয়ে দেয়। "যদি পাওয়া যায়" এর অর্থ কী তা প্রসারিত হয় না, তবে সম্ভবত "বাস্তবায়নের এফপি প্রতিনিধি তাদের সমর্থন করলে" এর মতো কিছু হবে। একইভাবে, একটি ফাংশন রয়েছে:

যা "যদি পাওয়া যায়" একটি ইতিবাচক INF প্রতিনিধি প্রদান করে।

এগুলি উভয়ই <limits>শিরোনামে সংজ্ঞায়িত করা হয়েছে - আমি অনুমান করব যে সি স্ট্যান্ডার্ডের কিছু মিল রয়েছে (সম্ভবত "যদি পাওয়া যায়") তবে আমার কাছে বর্তমান সি 99 স্ট্যান্ডার্ডের একটি অনুলিপি নেই।


হতাশ এবং অবাক করা। সি এবং সি ++ আইআইইই ভাসমান পয়েন্ট সংখ্যাগুলির সাথে খাপ খায় না, যাদের ন্যান এবং ইনফের জন্য স্ট্যান্ডার্ড প্রতিনিধিত্ব আছে?
গ্রাফিক্স নুব

14
C99, সি হেডারের মধ্যে <math.h>সংজ্ঞায়িত nan(), nanf()এবং nanl()NaN যে রিটার্ন বিভিন্ন উপস্থাপনা (ক যেমন double, floatএবং intযথাক্রমে), এবং অনন্ত (যদি এখনে) সঙ্গে এক উৎপাদিত দ্বারা ফিরে যেতে পারে log(0)বা কিছু। এমনকি তাদের জন্য চেক করার কোনও স্ট্যান্ডার্ড উপায় নেই, এমনকি C99 তেও। <float.h>হেডার ( <limits.h>অবিচ্ছেদ্য ধরনের জন্য) সম্পর্কে দুর্ভাগ্যবশত নীরব infএবং nanমান।
ক্রিস লুটজ

বাহ, এটি একটি বড় মিশ্রণ। nanl()একটি long double, intআমার মন্তব্য মত একটি না ফেরত । আমি টাইপ করার সময় কেন বুঝতে পারিনি তা আমি জানি না।
ক্রিস লুৎজ

@ ক্রিস, সি 99 এর জন্য আমার উত্তরটি দেখুন।
অলোক সিংহল

4
@ ইঞ্জহেেনরিকসেন - খুব নিশ্চিত যে মাইক্রোসফ্ট জানিয়েছে যে ভিসি +++ সি 99 সমর্থন করার কোনও উদ্দেশ্য নেই।
ক্রিস লুৎজ

25

এটি উভয়ের জন্য কাজ করে floatএবং double:

সম্পাদনা: কেউ ইতিমধ্যে বলেছে, পুরানো আইইইই স্ট্যান্ডার্ড বলেছে যে এই জাতীয় মানগুলি ফাঁদ বাড়াতে পারে। তবে নতুন সংকলক প্রায় সর্বদা ট্র্যাপগুলি স্যুইচ অফ করে এবং প্রদত্ত মানগুলি ফেরত দেয় কারণ ট্র্যাপিং ত্রুটি পরিচালনার ক্ষেত্রে হস্তক্ষেপ করে।


754-1985 এর মধ্যে অনুমোদিত ত্রুটি পরিচালনা করার জন্য ট্র্যাপিংয়ের একটি বিকল্প ছিল । বেশিরভাগ আধুনিক হার্ডওয়্যার / সংকলকগণের দ্বারা ব্যবহৃত আচরণেরও অনুমতি দেওয়া হয়েছিল (এবং কমিটির অনেক সদস্যের পক্ষে এটি পছন্দসই আচরণ ছিল)। অনেক প্রয়োগকারী ভুলভাবে ধরে নিয়েছিলেন যে স্ট্যান্ডার্ডটিতে "ব্যতিক্রম" শব্দটির দুর্ভাগ্যজনক ব্যবহারের কারণে ফাঁদে ফেলা দরকার ছিল। এটি সংশোধিত 754-2008 এ ব্যাপকভাবে স্পষ্ট করা হয়েছে।
স্টিফেন ক্যানন

হাই, স্টিফেন, আপনি ঠিকই বলেছেন, তবে মানটিটি আরও বলেছে: "একজন ব্যবহারকারীর পক্ষে একজন হ্যান্ডলার নির্দিষ্ট করে পাঁচটি ব্যতিক্রমের একটিতে ফাঁদ পেতে অনুরোধ করা উচিত He বিদ্যমান হ্যান্ডলারটি অক্ষম করার জন্য তাকে অনুরোধ করতে সক্ষম হওয়া উচিত , সংরক্ষণ করা বা পুনরুদ্ধার করা হয়েছে। কোনও নির্ধারিত ব্যতিক্রমের জন্য কোনও নির্দিষ্ট ট্র্যাপ হ্যান্ডলার সক্ষম হয়েছে কিনা তাও তার নির্ধারণ করা উচিত "" "উচিত" হিসাবে সংজ্ঞায়িত (২. সংজ্ঞা) এর অর্থ "দৃ strongly়ভাবে প্রস্তাবিত" এবং এর প্রয়োগ কেবল তখনই বাদ দেওয়া উচিত যদি আর্কিটেকচার ইত্যাদি এটিকে অবৈধ করে তোলে। 80x86 স্ট্যান্ডার্ডকে পুরোপুরি সমর্থন করে, সুতরাং সি এর সমর্থন না করার কোনও কারণ নেই।
থারস্টেন এস।

আমি সম্মত হই যে সি এর 754 (2008) ভাসমান পয়েন্ট প্রয়োজন হওয়া উচিত, তবে এটি না করার পিছনে ভাল কারণ রয়েছে; বিশেষত, সি 86 এর সাথে সমস্ত ধরণের পরিবেশে ব্যবহৃত হয় যা এম্বেড থাকা ডিভাইসগুলিতে হার্ডওয়্যার ফ্লোটিং-পয়েন্ট নেই এবং সিগন্যাল প্রসেসিং ডিভাইসগুলি সহ যেখানে প্রোগ্রামাররা এমনকি ভাসমান পয়েন্ট ব্যবহার করতে চান না including সঠিকভাবে বা ভুলভাবে, এগুলি ভাষা বর্ণনায় প্রচুর জড়তার জন্য অ্যাকাউন্ট ব্যবহার করে।
স্টিফেন ক্যানন

আমি জানি না কেন উপরের উত্তরটি এটি তৈরি করেছিল। এটি অনুরোধকৃত মানগুলি উত্পাদন করার কোনও উপায় দেয় না। এই উত্তর দেয়।
শুকনোডাম

#define is_nan(x) ((x) != (x))ন্যানের জন্য একটি সহজ, পোর্টেবল পরীক্ষা হিসাবে কার্যকর হতে পারে।
বব স্টেইন

21

একটি সংকলক স্বাধীন উপায়, তবে প্রসেসরের স্বতন্ত্র উপায় নয় এগুলি পাওয়ার জন্য:

এটি এমন কোনও প্রসেসরের উপর কাজ করা উচিত যা আইইইই 754 ফ্লোটিং পয়েন্ট ফর্ম্যাট (যা x86 করে) ব্যবহার করে।

আপডেট: পরীক্ষিত এবং আপডেট হয়েছে।


4
@ ওয়াফলম্যাট - 32/64 বিটের মধ্যে এই বন্দরটি কেন হবে না? আইইইই 754 একক নির্ভুলতা ফ্লোট অন্তর্নিহিত প্রসেসরের ঠিকানা আকার নির্বিশেষে 32-বিট is
হারুন

6
কাস্টিং (float &)? এটি আমার কাছে সি-এর মতো দেখাচ্ছে না। আপনার প্রয়োজনint i = 0x7F800000; return *(float *)&i;
ক্রিস লুটজ

6
নোট এটি আইইইই -754 মানক মধ্যে 0x7f800001একটি তথাকথিত সংকেত NaN। যদিও অধিকাংশ লাইব্রেরি ও হার্ডওয়্যার সংকেত Nans সমর্থন করি না, এটি সম্ভবত ভাল মত একটি শান্ত NaN আসতে হয় 0x7fc00000
স্টিফেন ক্যানন

6
সতর্কতা: কঠোর অ্যালাইজিং বিধি লঙ্ঘনের মাধ্যমে এটি অনির্ধারিত আচরণকে ট্রিগার করতে পারে । সুপারিশ করা (এবং সেরা কম্পাইলার সমর্থিত) উপায় করতে টাইপ punning মাধ্যমে হয় ইউনিয়ন সদস্যদের
ulidtko

4
@ জুলিদকো দেখিয়েছেন যে কঠোর আলিয়াজিং ইস্যু ছাড়াও, এটি ধরে নেওয়া হয়েছে যে লক্ষ্যটি পূর্ণসংখ্যার জন্য একই ভাসমান পয়েন্ট হিসাবে ভাসমান পয়েন্ট হিসাবে ব্যবহার করে, যা অবশ্যই সবসময় হয় না।
মিঃস্টোবে

16

4
এটি একটি স্মার্ট পোর্টেবল সমাধান! সি 99 এর জন্য strtodএনএএন এবং ইনফের রূপান্তর করে does
ulidtko

4
এই সমাধানটির কোনও অসুবিধা নেই; তারা ধ্রুবক নয়। আপনি উদাহরণস্বরূপ (বা একটি অ্যারে শুরু করার জন্য) একটি বৈশ্বিক চলক আরম্ভ করার জন্য এই মানগুলি ব্যবহার করতে পারবেন না।
মার্ক

4
@ মার্ক। আপনার সর্বদা একটি ইনিশিয়ালাইজার ফাংশন থাকতে পারে যা এগুলিকে একবার কল করে বিশ্বব্যাপী নেমস্পেসে সেট করে। এটি একটি খুব কার্যকর অপূর্ণতা।
ম্যাড পদার্থবিদ

3

এবং


0

আমিও অবাক হয়েছি এগুলি সময় সংকীর্ণ নয়। তবে আমি মনে করি আপনি কেবলমাত্র একটি নির্দেশ কার্যকর করে এই মানগুলি সহজেই যথেষ্ট পরিমাণে তৈরি করতে পারেন যা এই জাতীয় অবৈধ ফলাফল দেয়। 0 দ্বারা বিভাজক, 0 লগ, 90 এর ট্যান, যে ধরনের জিনিস।


0

আমি সাধারণত ব্যবহার করি

বা

যা কমপক্ষে আইইইই 754 প্রসঙ্গে কাজ করে কারণ সর্বোচ্চ উপস্থাপনযোগ্য ডাবল মান মোটামুটি 1e3081e309ঠিক যেমন কাজ করবে তেমনি 1e99999তিনটি নাইনও যথেষ্ট এবং স্মরণীয়। যেহেতু এটি হয় দ্বৈত আক্ষরিক ( #defineক্ষেত্রে) বা প্রকৃত Infমান, আপনি 128-বিট ("দীর্ঘ ডাবল") ভাসা ব্যবহার করলেও এটি অসীম থাকবে।


4
এটি আমার মতে অত্যন্ত বিপজ্জনক। কল্পনা করুন যে কীভাবে কেউ আপনার কোডটি 20 বা ততোধিক বছরে 128 বিটটিতে ভাসমান (আপনার কোডটি অবিশ্বাস্যরকম জটিল বিবর্তনের মধ্য দিয়ে যাওয়ার পরে, আপনি আজ যে পূর্বে ভবিষ্যদ্বাণী করতে পেরেছিলেন তার কোনওটিই নয়)। হঠাৎ, এক্সপোনেন্টের পরিসীমা মারাত্মকভাবে বৃদ্ধি পায় এবং আপনার সমস্ত 1e999আক্ষরিক আর গোল হয় না +Infinity। মার্ফির আইন অনুসারে, এটি একটি অ্যালগরিদমকে ভেঙে দেয়। সবচেয়ে খারাপ: "128-বিট" বিল্ড করা একজন মানব প্রোগ্রামার সম্ভবত ত্রুটিটি আগে থেকেই দেখতে পাবে না। অর্থাৎ সম্ভবত এই ত্রুটিটি খুঁজে পাওয়া ও স্বীকৃতি পেলে খুব দেরী হয়ে যাবে। খুব বিপজ্জনক
ulidtko

4
অবশ্যই, উপরের সবচেয়ে খারাপ পরিস্থিতি বাস্তবসম্মত হতে পারে। তবুও, বিকল্পগুলি বিবেচনা করুন! নিরাপদে থাকাই ভাল।
ulidtko

4
"20 বছরে", হি। চলে আসো. এই উত্তরটি নয় যে খারাপ।
আলেকোভ

@ জুলিদকো আমি এইটাও পছন্দ করি না, তবে সত্যি?
ইহরব আল আসিমি

0

এই ধ্রুবকগুলি সংজ্ঞায়িত করার জন্য এখানে একটি সহজ উপায় এবং আমি নিশ্চিত যে এটি বহনযোগ্য:

যখন আমি এই কোডটি চালাই:

আমি পাই:

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