অ্যাপসিলন ব্যবহার করে ডাবল থেকে শূন্যের তুলনা করুন


214

আজ আমি কয়েকটি সি ++ কোড (অন্য কারো দ্বারা লিখিত) সন্ধান করছিলাম এবং এই বিভাগটি পেয়েছি:

double someValue = ...
if (someValue <  std::numeric_limits<double>::epsilon() && 
    someValue > -std::numeric_limits<double>::epsilon()) {
  someValue = 0.0;
}

আমি এটি বোঝার চেষ্টা করছি যে এটি এমনকি অর্থবোধ করে কিনা।

এর জন্য ডকুমেন্টেশন epsilon()বলেছেন:

ফাংশনটি 1 টির চেয়ে বড় মানের এবং 1 টির চেয়েও ছোট মানের পার্থক্যটি প্রদান করে যা [দ্বিগুণ দ্বারা] উপস্থাপনযোগ্য।

এটি 0-তেও প্রযোজ্য, অর্থাৎ epsilon()ক্ষুদ্রতম মানটি 0 এর চেয়ে বেশি? বা এর মধ্যে সংখ্যা রয়েছে 0এবং 0 + epsilonএটি একটি দ্বারা প্রতিনিধিত্ব করা যেতে পারে double?

তা না হলে তুলনা কি সমান নয় someValue == 0.0?


3
প্রায় 1 এর এপিসিলনটি সম্ভবত প্রায় 0 এর চেয়ে বেশি হবে, সুতরাং 0 এবং 0 + অ্যাপসিলন_এটিউ-এর মধ্যে সম্ভবত মান থাকবে। আমি অনুমান করি যে এই বিভাগটির লেখক ছোট কিছু ব্যবহার করতে চেয়েছিলেন, তবে তিনি কোনও ম্যাজিক ধ্রুবক ব্যবহার করতে চান নি, তাই তিনি কেবল এই মূলত স্বেচ্ছাচারিত মানটি ব্যবহার করেছেন।
enobayram

2
ভাসমান পয়েন্ট সংখ্যা তুলনা করা শক্ত এবং এপসিলন বা প্রান্তিক মান ব্যবহার এমনকি উত্সাহিত করা হয়। দয়া করে রেফার করুন: সিএস.প্রিন্সটন.ইডু / সিন্ট্রোকস / ৯৯
আদিত্য কুমার পান্ডে

40
প্রথম লিঙ্কটি 403.99999999
গ্রাহাম.ব্রিডস

6
আইএমও, এক্ষেত্রে ব্যবহার numeric_limits<>::epsilonবিভ্রান্তিকর এবং অপ্রাসঙ্গিক। আমরা যা চাই তা 0 ধরে নেওয়া উচিত যদি আসল মান 0 থেকে কিছুটা আলাদা হয় না And এবং ε সমস্যার স্পেসিফিকেশনের ভিত্তিতে বেছে নেওয়া উচিত, কোনও মেশিন-নির্ভর মানের উপর ভিত্তি করে নয়। আমি সন্দেহ করতে পারি যে বর্তমান এপসিলন অকেজো, এমনকি মাত্র কয়েকটি এফপি অপারেশন এর চেয়েও বেশি ত্রুটি জমা করতে পারে।
আন্দ্রে ভিহারভ

1
+1 টি। অ্যাপসিলন ক্ষুদ্রতম সম্ভাব্য নয় তবে বেশিরভাগ ব্যবহারিক প্রকৌশল সংক্রান্ত কাজের ক্ষেত্রে প্রদত্ত উদ্দেশ্যটি পরিবেশন করতে পারে যদি আপনি জানেন যে আপনার কী নির্ভুলতা প্রয়োজন এবং আপনি কী করছেন।
শেচপুরিন

উত্তর:


192

64৪-বিট আইইইইই ডাবল ধরে নিলে, এখানে একটি 52-বিট ম্যান্টিসা এবং 11-বিট এক্সপোনেন্ট রয়েছে। এটি বিট ভাঙ্গা যাক:

1.0000 00000000 00000000 00000000 00000000 00000000 00000000 × 2^0 = 1

1 টির চেয়ে ছোটতম প্রতিনিধিত্বযোগ্য সংখ্যা:

1.0000 00000000 00000000 00000000 00000000 00000000 00000001 × 2^0 = 1 + 2^-52

অতএব:

epsilon = (1 + 2^-52) - 1 = 2^-52

0 এবং অ্যাপসিলনের মধ্যে কোনও সংখ্যা আছে? প্রচুর পরিমাণে ... যেমন সর্বনিম্ন ইতিবাচক প্রতিনিধিত্বযোগ্য (সাধারণ) সংখ্যাটি হ'ল:

1.0000 00000000 00000000 00000000 00000000 00000000 00000000 × 2^-1022 = 2^-1022

আসলে (1022 - 52 + 1)×2^52 = 43729952381767516160 এবং অ্যাপসিলনের মধ্যে সংখ্যা রয়েছে, যা ইতিবাচক প্রতিনিধিত্বমূলক সংখ্যার 47% ...


27
তাই অদ্ভুত যে আপনি বলতে পারেন :) "ইতিবাচক সংখ্যার 47%"
Configurator

13
@ কনফিগারেশন: নাহ, আপনি এটি বলতে পারবেন না (কোনও 'প্রাকৃতিক' সীমাবদ্ধ পরিমাপ বিদ্যমান নেই)) তবে আপনি "ইতিবাচক প্রতিনিধিত্বমূলক সংখ্যার 47%" বলতে পারেন ।
ইয়াকভ গালকা

1
@ybungalobill আমি এটি বুঝতে পারি না। এক্সপোনেন্টের 11 টি বিট রয়েছে: 1 সাইন বিট এবং 10 মান বিট। কেন 2 ^ -1022 এবং 2 ^ -1024 নয় সবচেয়ে কম ধনাত্মক সংখ্যা?
পাভলো ডাইবান

3
@PavloDyban: কারণ বহিঃপ্রকাশ না একটি সাইন বিট আছে। সেগুলিকে অফসেট হিসাবে এনকোড করা হয়: যদি এনকোডেড এক্সপোনেন্ট হয় 0 <= e < 2048তবে ম্যান্টিসাকে 2 এর গুণতে গুণ করা হয় e - 1023। এর যেমন এক্সপোনেন্ট 2^0যেমন এনকোডেড হয়েছে e=1023, 2^1যেমন e=1024এবং 2^-1022হিসাবে e=1। মানটি e=0নিম্নমানের এবং আসল শূন্যের জন্য সংরক্ষিত।
ইয়াকভ গালকা

2
@ পাভলোডাইবান: 2^-1022সর্বনিম্ন সাধারণ সংখ্যাও। ক্ষুদ্রতম সংখ্যাটি আসলে 0.0000 00000000 00000000 00000000 00000000 00000000 00000001 × 2^-1022 = 2^-1074। এটি অসাধারণ, অর্থাত্ ম্যান্টিসার অংশটি 1 এর চেয়ে ছোট, সুতরাং এটি ঘোরের সাথে এনকোডযুক্ত e=0
ইয়াকভ গালকা

17

পরীক্ষা অবশ্যই এক হিসাবে না someValue == 0। ভাসমান-পয়েন্ট সংখ্যাগুলির পুরো ধারণাটি হ'ল তারা একটি ঘনিষ্ঠ এবং একটি তাত্পর্যপূর্ণ সঞ্চয় করে। সুতরাং তারা নির্ভুলতার বাইনারি উল্লেখযোগ্য পরিসংখ্যানগুলির একটি নির্দিষ্ট সংখ্যার (একটি আইইইই ডাবল ক্ষেত্রে 53) একটি মান উপস্থাপন করে। উপস্থাপনযোগ্য মানগুলি 1 টির কাছাকাছি হওয়ার চেয়ে 0 এর কাছাকাছি অনেক বেশি ঘন প্যাক হয়।

আরও পরিচিত দশমিক সিস্টেমটি ব্যবহার করার জন্য, ধরুন আপনি একটি দশমিক মান "4 থেকে 4 উল্লেখযোগ্য পরিসংখ্যান "গুলিকে ব্যয়কারী সহ সঞ্চয় করেন। তারপর পরবর্তী representable মান চেয়ে বড় 1হয় 1.001 * 10^0, এবং epsilonহয় 1.000 * 10^-3। তবে 1.000 * 10^-4এটি উপস্থাপনযোগ্যও, ধরে নেওয়া যায় যে খাতাটি -4 সঞ্চয় করতে পারে। আপনি এটির জন্য আমার কথাটি নিতে পারেন যে কোনও আইইইই ডাবল এক্সপোশনগুলির চেয়ে কম সঞ্চয় করতে পারেepsilon

আপনি এই কোডটি একাকীই বলতে পারবেন না যে এটি epsilonসীমাবদ্ধ হিসাবে নির্দিষ্টভাবে ব্যবহার করা অনুধাবন করে বা না বোঝায় , আপনার প্রসঙ্গটি দেখার প্রয়োজন to এটি হতে পারে যে epsilonউত্পাদিত গণনায় ত্রুটিটির একটি যুক্তিসঙ্গত অনুমান someValueএবং এটি হতে পারে যে এটি তা নয়।


2
ভাল পয়েন্ট, তবে এটি যদি হয় তবে, আরও ভাল অনুশীলন হ'ল ত্রুটিটিকে যুক্তিসঙ্গত নামযুক্ত ভেরিয়েবলের সাথে আবদ্ধ রাখা এবং তুলনা করে এটি ব্যবহার করা। এটি যেমন দাঁড়িয়ে আছে, এটি কোনও যাদু ধ্রুবক থেকে আলাদা নয়।
enobayram

সম্ভবত আমার প্রশ্নে আমার আরও পরিষ্কার হওয়া উচিত: আমি প্রশ্ন করি নি যে অ্যাপসিলন গণনাগত ত্রুটি coverাকতে যথেষ্ট বড় "প্রান্তিক" কিনা তবে এই তুলনাটি সমান কিনা someValue == 0.0
সেবাস্তিয়ান ক্রাইসমানস্কি

13

0 এবং অ্যাপসিলনের মধ্যে বিদ্যমান এমন সংখ্যা রয়েছে কারণ অ্যাপসিলন হল 1 এবং পরবর্তী সর্বোচ্চ সংখ্যার মধ্যে পার্থক্য যা 1 এর উপরে উপস্থাপিত হতে পারে এবং 0 এবং পরবর্তী সর্বোচ্চ সংখ্যার মধ্যে পার্থক্য নয় যা 0 এর উপরে উপস্থাপিত হতে পারে (যদি এটি ছিল, যে কোড খুব সামান্য কাজ করবে): -

#include <limits>

int main ()
{
  struct Doubles
  {
      double one;
      double epsilon;
      double half_epsilon;
  } values;

  values.one = 1.0;
  values.epsilon = std::numeric_limits<double>::epsilon();
  values.half_epsilon = values.epsilon / 2.0;
}

একটি ডিবাগার ব্যবহার করে, প্রোগ্রামটির শেষে প্রান্তটি থামান এবং ফলাফলগুলি দেখুন এবং আপনি দেখতে পাবেন যে অ্যাপসিলন / 2 অ্যাপসিলন, শূন্য এবং একের থেকে আলাদা।

সুতরাং এই ফাংশনটি +/- অ্যাপসিলনের মধ্যে মান নেয় এবং তাদের শূন্য করে তোলে।


5

নীচের প্রোগ্রামের সাথে একটি সংখ্যার (১.০, ০.০, ...) কাছাকাছি অ্যাপসিলনের একটি ক্ষুদ্রতম সম্ভাব্য পার্থক্য (মুখ্যতম পার্থক্য) মুদ্রণ করা যেতে পারে। এটি নিম্নলিখিত আউটপুটটি মুদ্রণ করে:
epsilon for 0.0 is 4.940656e-324
epsilon for 1.0 is 2.220446e-16
একটি সামান্য চিন্তাভাবনা এটি পরিষ্কার করে দেয় যে, এপিসিলনটি এর অ্যাপিলন-মানটি দেখার জন্য আমরা যত কম সংখ্যা ব্যবহার করি ততই ক্ষুদ্রতর হয় কারণ উদ্দীপকটি সেই সংখ্যার আকারের সাথে সামঞ্জস্য করতে পারে।

#include <stdio.h>
#include <assert.h>
double getEps (double m) {
  double approx=1.0;
  double lastApprox=0.0;
  while (m+approx!=m) {
    lastApprox=approx;
    approx/=2.0;
  }
  assert (lastApprox!=0);
  return lastApprox;
}
int main () {
  printf ("epsilon for 0.0 is %e\n", getEps (0.0));
  printf ("epsilon for 1.0 is %e\n", getEps (1.0));
  return 0;
}

2
আপনি কি বাস্তবায়ন পরীক্ষা করেছেন? এটি অবশ্যই জিসিসি ৪.7-এর ক্ষেত্রে নয়।
আন্তন গোলভ

3

মনে করুন আমরা খেলনা ভাসমান পয়েন্ট নম্বর নিয়ে কাজ করছি যা 16 বিট রেজিস্ট্রারে ফিট করে। এখানে একটি সাইন বিট, একটি 5 বিট এক্সপোনেন্ট এবং 10 বিট ম্যান্টিসা রয়েছে।

এই ভাসমান বিন্দুর সংখ্যার মান হ'ল ম্যান্টিসা, বাইনারি দশমিক মান হিসাবে ব্যাখ্যা করা হয়, ব্যয়কারীর শক্তির দ্বিগুণ।

প্রায় 1 এর প্রায়শ্লেখ শূন্যের সমান। সুতরাং ম্যান্টিসার ক্ষুদ্রতম সংখ্যাটি 1024 এ একটি অংশ।

প্রায় ১/২ ঘনিষ্ঠটি বিয়োগফল এক, সুতরাং ম্যান্টিসার ক্ষুদ্রতম অংশটি অর্ধেক বড়। পাঁচ বিট এক্সপোনেন্ট সহ এটি নেতিবাচক 16 এ পৌঁছতে পারে, যেখানে মন্টিসার ক্ষুদ্রতম অংশটি 32 মিটারের এক অংশের মূল্যবান। এবং নেতিবাচক 16 এক্সপোনেন্টে, মান 32k এর এক অংশের কাছাকাছি, আমরা উপরে গণনা করা একের কাছাকাছি এপসিলনের তুলনায় শূন্যের কাছাকাছি!

এখন এটি একটি খেলনা ভাসমান বিন্দু মডেল যা সত্যিকারের ভাসমান পয়েন্ট সিস্টেমের সমস্ত কীর্তিকে প্রতিফলিত করে না, তবে এপিসিলনের চেয়ে ছোট মান প্রতিফলিত করার ক্ষমতা বাস্তব ভাসমান পয়েন্টের মানগুলির সাথে যুক্তিযুক্ত similar


3

মধ্যে পার্থক্য Xএবং পরবর্তী মান Xঅনুযায়ী পরিবর্তিত হয় X
epsilon()এর মধ্যে 1এবং পরবর্তী মানের মধ্যে কেবল পার্থক্য 1
মধ্যে পার্থক্য 0এবং পরবর্তী মান 0নয় epsilon()

পরিবর্তে আপনি নিম্নলিখিত হিসাবে std::nextafterএকটি ডাবল মান তুলনা করতে ব্যবহার করতে পারেন 0:

bool same(double a, double b)
{
  return std::nextafter(a, std::numeric_limits<double>::lowest()) <= b
    && std::nextafter(a, std::numeric_limits<double>::max()) >= b;
}

double someValue = ...
if (same (someValue, 0.0)) {
  someValue = 0.0;
}

2

আমি মনে করি এটি আপনার কম্পিউটারের নির্ভুলতার উপর নির্ভর করে । এই টেবিলটি একবার দেখুন : আপনি দেখতে পাচ্ছেন যে যদি আপনার এপিসিলনটি দ্বিগুণ দ্বারা প্রতিনিধিত্ব করা হয় তবে আপনার নির্ভুলতা বেশি হয় তবে তুলনাটি সমান নয়

someValue == 0.0

ভাল প্রশ্ন যাই হোক!


2

আপনি এটি 0 তে প্রয়োগ করতে পারবেন না, ম্যান্টিসা এবং এক্সপোনেন্ট অংশগুলির কারণে। এক্সপোনেন্টের কারণে আপনি খুব অল্প সংখ্যক স্টোর করতে পারেন, যা এপসিলনের চেয়ে ছোট, তবে যখন আপনি কিছু করার চেষ্টা করবেন (1.0 - "খুব ছোট সংখ্যা") আপনি 1.0 পাবেন you'll এপসিলন হ'ল মানের নয়, মান সুনির্দিষ্টতার একটি সূচক, যা মান্টিসে রয়েছে। এটি দেখায় যে আমরা সংখ্যার সংখ্যার কতগুলি সঠিক ফলস্বরূপ দশমিক অঙ্কগুলি সঞ্চয় করতে পারি।


2

আইইইইই ভাসমান-পয়েন্ট সহ, ক্ষুদ্রতম অ-শূন্য ধনাত্মক মান এবং ক্ষুদ্রতম অ-শূন্য নেতিবাচক মানের মধ্যে দুটি মান রয়েছে: ধনাত্মক শূন্য এবং negativeণাত্মক শূন্য। মানটি ক্ষুদ্রতম অ-শূন্য মানের মধ্যে কিনা তা পরীক্ষা করা শূন্যের সাথে সমতার জন্য পরীক্ষার সমতুল্য; অ্যাসাইনমেন্টটির কোনও প্রভাব থাকতে পারে, কারণ এটি negativeণাত্মক শূন্যকে ধনাত্মক শূন্যে পরিণত করবে।

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


"1 / (1-1)" (আপনার উদাহরণ থেকে) অনন্যতা শূন্যের চেয়ে নয়?
সেবাস্তিয়ান ক্রিসমানস্কি

পরিমাণগুলি (1-1), (1 / INF) এবং (-1 / INF) সকলেই শূন্যকে উপস্থাপন করে তবে তাদের প্রত্যেকের দ্বারা একটি ধনাত্মক সংখ্যাকে ভাগ করলে তত্ত্বের মধ্যে তিনটি পৃথক ফলাফল পাওয়া উচিত (আইইইই গণিত প্রথম দুটিকে অভিন্ন হিসাবে বিবেচনা করে) )।
সুপারক্যাট

1

সুতরাং যাক যাক সিস্টেমটি 1.0000000000000000000000000 এবং 1.00000000000000000000001 পার্থক্য করতে পারে না। এটি 1.0 এবং 1.0 + 1e-20। আপনি কি মনে করেন যে এখনও কিছু মান রয়েছে যা -1e-20 এবং + 1e-20 এর মধ্যে উপস্থাপিত হতে পারে?


শূন্য ব্যতীত, আমি মনে করি না যে -1e-20 এবং + 1e-20 এর মধ্যে মান আছে। তবে কেবলমাত্র আমি মনে করি এটি সত্য করে তোলে না।
সেবাস্তিয়ান ক্রিসমানস্কি

@ সেবাস্তিয়ান ক্রাইসম্যানস্কি: এটি সত্য নয়, 0 এবং এর মধ্যে প্রচুর ভাসমান-পয়েন্টের মান রয়েছে epsilon। কারণ এটি ভাসমান পয়েন্ট, নির্দিষ্ট পয়েন্ট নয়।
স্টিভ জেসপ

ক্ষুদ্রতম উপস্থাপনযোগ্য মান যা শূন্যের থেকে পৃথক, ঘাঁটিঘাঁটি প্রতিনিধিত্ব করতে বরাদ্দ করা বিটের সংখ্যা দ্বারা সীমাবদ্ধ। সুতরাং ডাবলের যদি 11 বিট এক্সপোঞ্জার থাকে তবে ক্ষুদ্রতম সংখ্যাটি 1e-1023 হবে।
কাবাবুঙ্গা

0

এছাড়াও, এই জাতীয় কোনও ক্রিয়াকলাপ থাকার একটি ভাল কারণ হ'ল "ডেনারমালস" সরিয়ে ফেলা (যারা খুব অল্প সংখ্যক যা প্রকৃত নেতৃস্থানীয় "1" ব্যবহার করতে পারে না এবং তাদের একটি বিশেষ এফপি উপস্থাপনা থাকতে পারে)। তুমি কেন এটা করতে চাও? কারণ কিছু মেশিন (বিশেষত, কিছু পুরানো পেন্টিয়াম 4 এস) ডেনারমালগুলি প্রক্রিয়া করার সময় সত্যই, সত্যই ধীর হয়। অন্যরা কিছুটা ধীর হয়ে যায়। আপনার অ্যাপ্লিকেশনটির যদি সত্যিই এই খুব অল্প সংখ্যক প্রয়োজন না হয় তবে এগুলি শূন্যে ফ্লাশ করা ভাল সমাধান। এটি বিবেচনা করার জন্য ভাল জায়গা হ'ল যে কোনও আইআইআর ফিল্টার বা ক্ষয় ফাংশনগুলির শেষ পদক্ষেপ।

আরও দেখুন: কেন 0.1x থেকে 0 পরিবর্তন 10x দ্বারা কর্মক্ষমতা কমিয়ে দেয়?

এবং http://en.wikedia.org/wiki/Denormal_number


1
এটি কেবল অস্বীকৃত সংখ্যার চেয়ে আরও অনেকগুলি সংখ্যা সরিয়ে দেয়। এটি প্লাঙ্কের ধ্রুবক বা একটি ইলেকট্রনের ভরকে শূন্যে পরিবর্তন করে যা আপনি এই সংখ্যাগুলি ব্যবহার করলে আপনাকে খুব, খুব ভুল ফলাফল দেয়।
gnasher729
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.