সি / সি ++ এ সর্বনিম্ন দ্বিগুণ মান


92

কোনও সি (++) প্রোগ্রামে ক্ষুদ্রতম নেতিবাচক মান (যেমন নেতিবাচক অনন্ততা ব্যবহার করার জন্য) উপস্থাপনের জন্য কি কোনও স্ট্যান্ডার্ড এবং / বা পোর্টেবল উপায় আছে?

ভাসা-র মধ্যে DBL_MIN হ'ল ক্ষুদ্রতম ধনাত্মক সংখ্যা।


4
আমি -ডিবিএল_ম্যাক্সের জন্য যাব, তবে আমি নিশ্চিত যে এটির কিছু প্রযুক্তিগত কারণ রয়েছে :-)

4
@Neil, কোন সেখানে নেই, আসুন 2 পরিপূর্ণ পূর্ণসংখ্যার মত হল তাই না
ফোরট্রান

আমি এখনও স্ট্যান্ডার্ডে কিছু বলতে দেখিনি যে ভাসমান পয়েন্টের ধরণের পরিসীমা শূন্যের কাছাকাছি প্রতিসম হতে হবে। তবে সীমাগুলির শৃঙ্খলাগুলি এবং <limits> পরামর্শ দেয় যে সি এবং সি ++ স্ট্যান্ডার্ড উভয়ই তাদের প্রত্যাশার ধরণ kind
স্টিভ জেসোপ

4
প্রকৃতপক্ষে float.h এ DBL_MIN হ'ল ক্ষুদ্রতম ধনাত্মক স্বাভাবিক সংখ্যা। আরও ছোট যে সংখ্যা আছে।
fdermishin

4
@ ফিফর্টান: আইইইই 754 এফপি একটি সাইন বিট ব্যবহার করে, এবং অবশ্যই আজকাল বেশিরভাগ এফপি হার্ডওয়্যার আইইইই 754 But সর্বনিম্ন উপস্থাপনযোগ্য মানের সমান হতে হবে।
j_random_hacker

উত্তর:


135

-DBL_MAX এএনএসআই সি-তে , যা ফ্লোট। h এ সংজ্ঞায়িত।


এটা হল সবচেয়ে মান এবং পোর্টেবল বলে মনে হয়
উইল

আমার -১ এর ব্যাখ্যা এখানে: কে বা কী বলে যে -DBL_MAX সি বা সি ++ ভাষা দ্বারা প্রতিনিধিত্বযোগ্য হওয়ার গ্যারান্টিযুক্ত? বেশিরভাগ এফপি হার্ডওয়্যার আইইইই 754-কনফর্মেন্ট এবং এটি এই উপস্থাপনাটি ব্যবহার করে, এর অর্থ এই নয় যে -ডিবিএল_ম্যাক্স কোনও মানক-কনফর্মেন্ট সি প্ল্যাটফর্মে কাজ করার গ্যারান্টিযুক্ত।
j_random_hacker

@ জেআর্যান্ডম_হ্যাকার: ফোর্টরানের উত্তর 'নীচে' দেখুন।
জনটর্টোগো

4
@ j_random_hacker এটি একটি খুব ভাল পয়েন্ট, তবে সি স্ট্যান্ডার্ডটি -DBL_MAXহুবহু উপস্থাপনযোগ্য হওয়া দরকার , সুতরাং যদি এফপি হার্ডওয়্যার এটি সক্ষম না হয় তবে বাস্তবায়নটি কেবল তার চারপাশে কাজ করতে হবে। 5.2.4.2.2 এ ভাসমান-পয়েন্ট মডেলটি দেখুন C99 এর ভাসমান ধরণের <ফ্লোট। H> পি 2 এর বৈশিষ্ট্য (তখন থেকে অন্য কোথাও স্থানান্তরিত হতে পারে)।

4
@ j_random_hacker হ্যাঁ, তবে p2 নির্দিষ্ট করে e_min এবং e_max সাইন বিট থেকে স্বতন্ত্র, DBL_MAXঠিক ঠিক (1 - b ^ )p) b ^ e_max, যা ঠিক উপস্থাপনযোগ্য, সর্বাধিক-নেতিবাচক সীমাবদ্ধ মানটি হ'ল - (1 - বি ^ -p) খ ^ e_max এবং যেহেতু যে ঠিক হতে হবে -DBL_MAX, অস্বীকার DBL_MAXকোন rounding ত্রুটি পারেন পরিচয় করিয়ে করতে পারবে না।

70

ভাসমান পয়েন্ট সংখ্যা (আইইইই 754) প্রতিসম হয়, তাই আপনি যদি সর্বোচ্চ মান ( DBL_MAXবা numeric_limits<double>::max()) উপস্থাপন করতে পারেন তবে কেবল একটি বিয়োগ চিহ্নটি প্রিপেন্ড করুন।

এবং তারপরে দুর্দান্ত উপায়:

double f;
(*((long long*)&f))= ~(1LL<<52);

6
+1 ভাসমান পয়েন্ট সংখ্যার প্রতিসাম্য নির্দেশ করার জন্য :)
অ্যান্ড্রু হ্যারে

4
সি / সি ++ বাস্তবায়নগুলি সম্পর্কে যা আইইইই 754 ফ্লোট ব্যবহার করে না?
স্টিভ জেসোপ

4
-ফিসট-ম্যাথের জন্য জিসিসির ম্যানুয়ালটিতে "সেটস -ফনো-ম্যাথ-এর্নো, -ফুনস্যাফ-ম্যাথ-অপটিমাইজেশন, -ফিনিট-ম্যাথ-ওয়ান, -ফনো-রাউন্ডিং-ম্যাথ, -ফনো-সিগন্যালিং-ন্যানস এবং -ফসিএক্স-লিমিটেড- পরিসীমা এই বিকল্পটি কোনও-ও বিকল্প দ্বারা চালু করা হয়নি কারণ এটি এমন প্রোগ্রামগুলির জন্য ভুল আউটপুট তৈরি করতে পারে যা গণিতের ক্রিয়াকলাপগুলির জন্য আইইইই বা আইএসও বিধি / স্পেসিফিকেশনের সঠিক প্রয়োগের উপর নির্ভর করে however এই নির্দিষ্টকরণের গ্যারান্টি প্রয়োজন হয় না। " দ্রুত গণিত একটি সাধারণ সেটিং এবং উদাহরণস্বরূপ ইন্টেল আইসিসি এটির ডিফল্ট। সব, নিশ্চিত করুন কি এই মানে না আমার জন্য :-) সকল
উইল

4
এর অর্থ হল বাস্তবায়নগুলি আইইইই 754 গাণিতিক ব্যবহার করে না, তবে ন্যায্য হতে এই বিকল্পগুলি এখনও আইইইই উপস্থাপনা ব্যবহার করে। আপনি নন-আইইইই উপস্থাপন ব্যবহার করে কিছু এমুলেশন লাইব্রেরি পেতে পারেন, যেহেতু সমস্ত প্রসেসরের একটি নেটিভ ফ্লোট ফর্ম্যাট নেই (যদিও তারা সি এবিআই প্রকাশ করতে পারে যা নির্মাতাকে সরবরাহিত এমুলেশন লিবের সাথে সংযুক্ত করে) format সুতরাং সমস্ত সংকলক একটি ব্যবহার করতে পারে না। আপনি যখন "স্ট্যান্ডার্ড এবং / বা পোর্টেবল" চান তখন আপনার অর্থটি নির্ভর করে, নীতিগতভাবে বহনযোগ্য এবং অনুশীলনে বহনযোগ্য there's
স্টিভ জেসোপ

4
আপনি যা বলছেন তা আইইইই 754 এর ক্ষেত্রে সত্য, তবে স্ট্যান্ডার্ডটির জন্য এই এনকোডিংটি ব্যবহারের প্রয়োজন নেই (@ স্টিভ জেসোপ উল্লেখ করেছেন যে, বাস্তবে বহনযোগ্য নীতিগতভাবে বহনযোগ্য হিসাবে একই নয়)।
ক্রিস্টোফ

44

সি তে, ব্যবহার করুন

#include <float.h>

const double lowest_double = -DBL_MAX;

সি ++ প্রাক -11 এ, ব্যবহার করুন

#include <limits>

const double lowest_double = -std::numeric_limits<double>::max();

সি ++ 11 এবং তারপরে, ব্যবহার করুন

#include <limits>

constexpr double lowest_double = std::numeric_limits<double>::lowest();

min()সি ++ 11 এর আগে কি ফাংশনটি উপলব্ধ ছিল না ? নাকি এর চেয়ে আলাদা মান -max()? en.cppreferences.com/w/cpp/tyype/numeric_limits
অ্যালেক্সিস উইলক

4
@ অ্যালেক্সিস: আপনি যে পৃষ্ঠায় লিঙ্ক করেছেন তার উপরের সারণির সর্বনিম্ন তিনটি সারিটি যদি আপনি দেখেন তবে আপনি দেখতে পাবেন যে minআপনি মাত্রার সবচেয়ে ক্ষুদ্রতম ধনাত্মক মান এবং মাত্রার lowestসবচেয়ে বড় নেতিবাচক মান পেয়ে যাচ্ছেন। হ্যাঁ, এটা ভয়ানক। সি ++ স্ট্যান্ডার্ড লাইব্রেরির উজ্জ্বল বিশ্বে আপনাকে স্বাগতম :-P
রুবেনভিবি

সি জন্য এটি সংজ্ঞায়িত করা হয় float.hlimits.hপূর্ণসংখ্যার জন্য
সিপরিয়ান টোমাইগা

33

এটা চেষ্টা কর:

-1 * numeric_limits<double>::max()

তথ্যসূত্র: numeric_limits

এই শ্রেণিটি প্রতিটি মৌলিক ধরণের জন্য বিশেষায়িত, এর সদস্যরা ফিরে আসে বা বিভিন্ন মানগুলিতে সেট করে যা নির্দিষ্ট প্ল্যাটফর্মটিতে সংকলন করে এমন বৈশিষ্ট্যগুলি নির্দিষ্ট করে।


4
শুধু কেন নয় -numeric_limits<double>::max()?
k06a

4
@ k06a এত দীর্ঘ অভিব্যক্তিতে একটি চরিত্রের দ্বারা উপস্থাপিত হওয়া, যেখানে স্ট্রিং এমনকি "সর্বাধিক" বলছে, তাড়াতাড়ি বা পরে কাউকে পেতে নিশ্চিত। হয় এটি বর্ণনামূলক ভেরিয়েবলে সঞ্চিত রয়েছে, বা -1 * ...এটি আরও পরিষ্কার করার জন্য ব্যবহার করুন।
ফিলিপ হাগলুন্ড

20

আপনি কি প্রকৃত অনন্ত বা ন্যূনতম সীমাবদ্ধ মান খুঁজছেন? প্রাক্তন যদি, ব্যবহার

-numeric_limits<double>::infinity()

যা কেবল যদি কাজ করে

numeric_limits<double>::has_infinity

অন্যথায়, আপনি ব্যবহার করা উচিত

numeric_limits<double>::lowest()

যা সি ++ 11 এ পরিচিত ছিল।

যদি lowest()উপলভ্য না হয় তবে আপনি এখানে ফিরে যেতে পারেন

-numeric_limits<double>::max()

যা lowest()নীতিগতভাবে পৃথক হতে পারে , তবে সাধারণত অনুশীলনে হয় না।


সীমাবদ্ধ এবং অসীম মানের মধ্যে পার্থক্য জন্য +1! কিন্তু মান কোনও সিমেট্রিক ভাসমান পয়েন্ট এনকোডিংয়ের গ্যারান্টি দেয় না। সুতরাং -numeric_limits<double>::max()এটি অনুশীলনে কাজ করলেও তত্ত্বের ক্ষেত্রে পুরোপুরি পোর্টেবল হয় না।
ক্রিস্টোফ


10

একটি সত্যই বহনযোগ্য সি ++ সমাধান

সি ++ 11 হিসাবে আপনি ব্যবহার করতে পারেন numeric_limits<double>::lowest()। মান অনুযায়ী, এটি আপনি যা খুঁজছেন ঠিক তা ফেরত দেয়:

একটি সীমাবদ্ধ মান x এর মতো অন্য কোনও সীমাবদ্ধ মান y নেই y < x
সব বিশেষায়িত জন্য অর্থপূর্ণ যা is_bounded != false

অনলাইন ডেমো


প্রচুর নন পোর্টেবল সি ++ উত্তর এখানে!

অনেক উত্তর চলেছে -std::numeric_limits<double>::max()

ভাগ্যক্রমে, তারা বেশিরভাগ ক্ষেত্রে ভাল কাজ করবে। ফ্লোটিং পয়েন্ট এনকোডিং স্কিমগুলি একটি ম্যান্টিসা এবং একটি এক্সপোনেন্টে একটি সংখ্যা পচিয়ে দেয় এবং তাদের বেশিরভাগ (যেমন জনপ্রিয় আইইইই -754 ) একটি স্বতন্ত্র চিহ্ন বিট ব্যবহার করে, যা ম্যান্টিসার সাথে সম্পর্কিত নয়। এটি কেবল সাইনটি উল্টিয়ে ক্ষুদ্রতম নেতিবাচক ক্ষেত্রে বৃহত্তম ধনাত্মককে রূপান্তর করতে দেয়:

এখানে চিত্র বর্ণনা লিখুন

কেন এই পোর্টেবল হয় না?

মান কোনও ভাসমান পয়েন্ট স্ট্যান্ডার্ড চাপায় না।

আমি সম্মত হই যে আমার যুক্তিটি কিছুটা তাত্ত্বিক, তবে মনে করুন যে কিছু এক্সেনট্রিক সংকলক প্রস্তুতকারক একটি বিপ্লবী এনকোডিং স্কিমটি কোনও দু'জনের পরিপূরকের কিছু প্রকরণে এনকোডড ম্যান্টিসার সাথে ব্যবহার করবেন । দুটির পরিপূরক এনকোডিং প্রতিসম নয়। উদাহরণস্বরূপ একটি স্বাক্ষরিত 8 বিট চরের জন্য সর্বাধিক ধনাত্মক 127, তবে সর্বনিম্ন নেতিবাচক -128। সুতরাং আমরা কিছু ভাসমান পয়েন্ট এনকোডিং অনুরূপ অসমমিত আচরণের ধারণা করতে পারি।

আমি এর মতো কোনও এনকোডিং স্কিম সম্পর্কে অবগত নই, তবে মূল বিষয়টি হ'ল মানটি গ্যারান্টি দেয় না যে সাইনটি উল্টানো উদ্দেশ্যযুক্ত ফলাফল দেয় । সুতরাং এই জনপ্রিয় উত্তর (দুঃখিত ছেলেরা) পুরোপুরি পোর্টেবল মান সমাধান হিসাবে বিবেচনা করা যায় না! / * কমপক্ষে না যদি আপনি numeric_limits<double>::is_iec559সত্যটি জোড় না করেন তবে * /



1

মূল প্রশ্নটি অসীমকে উদ্বেগ করে। সুতরাং, কেন ব্যবহার করবেন না

#define Infinity  ((double)(42 / 0.0))

আইইইই সংজ্ঞা অনুসারে? আপনি অবশ্যই তা প্রত্যাখ্যান করতে পারেন।


ভাল যুক্তি ! এবং এটি কাজ করে । তবে কেবল যদিnumeric_limits<double>::has_infinity && ! numeric_limits<double>::traps
ক্রিস্টোফ

1

কোনও সি (++) প্রোগ্রামে ক্ষুদ্রতম নেতিবাচক মান (যেমন নেতিবাচক অনন্ততা ব্যবহার করার জন্য) উপস্থাপনের জন্য কি কোনও স্ট্যান্ডার্ড এবং / বা পোর্টেবল উপায় আছে?

সি পদ্ধতির।

অনেকগুলি প্রয়োগগুলি +/- ইনফিনিটিকে সমর্থন করে, তাই সর্বাধিক নেতিবাচক doubleমান -INFINITY

#include <math.h>
double most_negative = -INFINITY;

কোনও মানক এবং / অথবা বহনযোগ্য উপায় আছে ....?

এখন আমাদের অন্যান্য ক্ষেত্রেও বিবেচনা করা দরকার:

  • কোনও অসম্পূর্ণতা নেই

সহজভাবে -DBL_MAX

  • কেবল একটি স্বাক্ষরবিহীন অনন্ত।

আমি এই ক্ষেত্রে আশা করতাম, ওপি পছন্দ করবে -DBL_MAX

  • স্বাভাবিকের চেয়ে বেশি মানের ডি-স্বাভাবিক মান DBL_MAX

এটি একটি অস্বাভাবিক ঘটনা, সম্ভবত ওপির উদ্বেগের বাইরে। কাঙ্ক্ষিত পরিসীমা / প্রেভিশন অর্জনের doubleজন্য যখন একটি ভাসমান পয়েন্টের জুটি হিসাবে এনকোড করা হয় ( ডাবল-ডাবল দেখুন ) সেখানে সর্বাধিক স্বাভাবিক double এবং সম্ভবত একটি বৃহত্তর ডি-নরমাল উপস্থিত থাকে । আমি বিতর্ক দেখেছি যদি উভয়ের DBL_MAXমধ্যে সর্বাধিক স্বাভাবিকের উল্লেখ করা উচিত ।

ভাগ্যক্রমে এই জোড় করা পদ্ধতির মধ্যে সাধারণত একটি অন্তঃসত্তা অন্তর্ভুক্ত থাকে, তাই সর্বাধিক নেতিবাচক মানটি থেকে যায় -INFINITY


আরও বহনযোগ্যতার জন্য, কোডটি রুটে যেতে পারে

// HUGE_VAL is designed to be infinity or DBL_MAX (when infinites are not implemented)
// .. yet is problematic with unsigned infinity.
double most_negative1 = -HUGE_VAL;  

// Fairly portable, unless system does not understand "INF"
double most_negative2 = strtod("-INF", (char **) NULL);

// Pragmatic
double most_negative3 = strtod("-1.0e999999999", (char **) NULL);

// Somewhat time-consuming
double most_negative4 = pow(-DBL_MAX, 0xFFFF /* odd value */);

// My suggestion
double most_negative5 = (-DBL_MAX)*DBL_MAX;

-1

আপনার যদি ভাসা ব্যতিক্রমগুলি সক্ষম না করা থাকে (যা আপনার ইমো করা উচিত নয়), আপনি কেবল বলতে পারেন:

double neg_inf = -1/0.0;

এটি নেতিবাচক অসীম লাভ করে। আপনার যদি একটি ভাসা প্রয়োজন, আপনি হয় ফলাফল নিক্ষেপ করতে পারেন

float neg_inf = (float)-1/0.0;

বা একক নির্ভুলতা গণিত ব্যবহার করুন

float neg_inf = -1.0f/0.0f;

ফলাফল সর্বদা এক রকম হয়, একক এবং দ্বিগুণ উভয় ক্ষেত্রে যথার্থই নেতিবাচক অনন্ততার উপস্থাপনা রয়েছে এবং তারা প্রত্যাশা অনুযায়ী একে অপরকে রূপান্তরিত করে।


আপনি কেবল লেখার পরিবর্তে এটি কেন করবেন-INFINITY
এমএম

এছাড়াও, অনন্ত অস্তিত্ব থাকতে পারে বা নাও থাকতে পারে এবং যদি এটি বিদ্যমান থাকে তবে ইতিবাচক এবং নেতিবাচক পার্থক্যযোগ্য নয় (স্ট্যান্ডার্ড সি তে)।
এমএম

অনেক সংকলক এবং / অথবা আর্কিটেকচারগুলিতে আপনার সি / সি ++ কোড আপনাকে প্রচুর পরিমাণে অনন্ত এবং NaN মান প্রচার করবে।
মার্কগ্যালাসি

@ মার্কগ্যালাসি দয়া করে কাছ থেকে দেখুন: আপনি লক্ষ্য করবেন যে neg_infএটি একটি ধ্রুবক মানের সাথে আরম্ভ করা হয়েছে । সংকলক infমানটি গণনার ক্ষেত্রে যত্ন নেবে । এবং যখন আপনি এটি সর্বাধিক গণনার জন্য নাল-মান হিসাবে ব্যবহার করেন, প্রথম পুনরাবৃত্তি সাধারণত এটি একটি বৃহত্তর মান দিয়ে ওভাররাইট করে। অর্থাৎ পারফরম্যান্স খুব কমই একটি সমস্যা is এবং ওপি বিশেষত "যেমন নেতিবাচক অনন্ত ব্যবহার করতে" সম্পর্কে জিজ্ঞাসা করে, এবং -infসত্যই এটির সঠিক উত্তর only আপনি একটি সঠিক এবং দরকারী উত্তরকে প্রত্যাখ্যান করেছেন।
মাস্টার -
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.