পাইথনে প্রায় সমতার জন্য ভাসমানগুলির তুলনা করার সর্বোত্তম উপায় কী?


331

এটি সুপরিচিত যে গোলাকার এবং যথার্থ ইস্যুগুলির কারণে সমতার জন্য ভাসমান তুলনা করা কিছুটা মজাদার।

উদাহরণস্বরূপ: https://randomascii.wordpress.com/2012/02/25/compering-floating-Point-numbers-2012-edition/

পাইথনে এটি মোকাবেলার প্রস্তাবিত উপায় কী?

নিশ্চয়ই কোথাও এর জন্য একটি স্ট্যান্ডার্ড লাইব্রেরি ফাংশন আছে?


@ টলোমিয়া: যেহেতু এটি আপনার অ্যাপ্লিকেশন এবং আপনার ডেটা এবং আপনার সমস্যা ডোমেনের উপর নির্ভর করে - এবং এটি কোডের একমাত্র লাইন - কেন সেখানে "স্ট্যান্ডার্ড লাইব্রেরি ফাংশন" থাকবে?
এস .লট

9
@ S.Lott: all, any, max, minপ্রতিটি মূলত এক liners,, এবং তারা একটি লাইব্রেরি দেওয়া হয় না, তারা ফাংশন builtin করছি। বিডিএফএল এর কারণগুলি এমন নয়। বেশিরভাগ লোকেরা যে একটি কোডের কোড লিখে থাকেন তা হ'ল বেশ অযৌক্তিক এবং প্রায়শই কাজ করে না, যা আরও ভাল কিছু সরবরাহ করার একটি দৃ reason় কারণ। অবশ্যই অন্য কৌশলগুলি সরবরাহকারী যে কোনও মডিউলকে উপযুক্ত হওয়ার সময় তাদের বর্ণনাকারীদেরও সরবরাহ করতে হবে এবং আরও গুরুত্বপূর্ণভাবে যখন তারা না থাকে। সংখ্যা বিশ্লেষণ শক্ত, ভাষা ডিজাইনাররা সাধারণত এটির সাহায্যের জন্য সরঞ্জামগুলি ব্যবহার করে না এমনটি কোনও বড় অসম্মানজনক বিষয় নয়।
স্টিভ জেসোপ

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

6
@ এস.লোট: আমি সম্ভবত সম্মত হইলাম যদি স্ট্যান্ডার্ড পাইথন বিতরণটি এক্সএমএল ইন্টারফেসের জন্য একাধিক মডিউল নিয়ে আসে না । স্পষ্টতই যে বিভিন্ন অ্যাপ্লিকেশনগুলির আলাদাভাবে কিছু করা দরকার তা বেস সেডে মডিউলগুলি একভাবে বা অন্যভাবে করার জন্য কোনও বাধা নেই। অবশ্যই ফ্লোটগুলির সাথে তুলনা করার জন্য কৌশলগুলি রয়েছে যা প্রচুর পরিমাণে পুনরায় ব্যবহৃত হয়, সর্বাধিক বেসিক একটি নির্দিষ্ট সংখ্যক। সুতরাং আমি কেবল আংশিকভাবে একমত - সমস্যাটি হ'ল সংখ্যার বিশ্লেষণ শক্ত is পাইথন পারে নীতি, এটা কিছুটা সহজ করতে সরঞ্জাম প্রদান কিছু সময়। আমার ধারণা, কেউ স্বেচ্ছাসেবিত হয়নি।
স্টিভ জেসোপ

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

উত্তর:


323

পাইথন 3.5 পিইপি 485 তে বর্ণিত হিসাবে math.iscloseএবং cmath.iscloseফাংশনগুলি যুক্ত করে ।

আপনি যদি পাইথনের পূর্ববর্তী সংস্করণ ব্যবহার করেন তবে ডকুমেন্টেশনে সমতুল্য ফাংশনটি দেওয়া হয় ।

def isclose(a, b, rel_tol=1e-09, abs_tol=0.0):
    return abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)

rel_tolএটি একটি আপেক্ষিক সহনশীলতা, এটি দুটি আর্গুমেন্টের আকারের বৃহত্তর দ্বারা গুণিত হয়; মানগুলি বড় হওয়ার সাথে সাথে তাদের সমান বিবেচনা করার সময়ও তাদের মধ্যে অনুমোদিত পার্থক্য থাকে।

abs_tolসমস্ত ক্ষেত্রে যেমন হয় তেমন প্রয়োগ করা হয় এমন এক পরম সহনশীলতা। পার্থক্য যদি সেই সহনশীলতার যে কোনও একটির চেয়ে কম হয় তবে মানগুলি সমান হিসাবে বিবেচিত হয়।


26
নোট করুন কখন aবা কখন , bএকটি কাজ করে। numpy arraynumpy.isclose
dbliss

6
@ মার্স rel_tolএকটি আপেক্ষিক সহনশীলতা , এটি দুটি আর্গুমেন্টের বৃহত্তর দ্বারা গুণিত হয়; মানগুলি বড় হওয়ার সাথে সাথে তাদের সমান বিবেচনা করার সময়ও তাদের মধ্যে অনুমোদিত পার্থক্য থাকে। সমস্ত ক্ষেত্রে যেমন হয় তেমন প্রয়োগ করা হয় abs_tolএমন এক পরম সহনশীলতা । পার্থক্য যদি সেই সহনশীলতার যে কোনও একটির চেয়ে কম হয় তবে মানগুলি সমান হিসাবে বিবেচিত হয়।
মার্ক রান্সম

5
এই উত্তরের মান হ্রাস না করা (আমি মনে করি এটি একটি ভাল), ডকুমেন্টেশনটিতে আরও বলা হয়েছে: "মোডুলো ত্রুটি পরীক্ষা করা ইত্যাদি, ফাংশনটি ফলাফলটি ফিরিয়ে দেবে ..." অন্য কথায়, iscloseফাংশন (উপরে) সম্পূর্ণ বাস্তবায়ন নয়।
রকেশ

5
পুরানো থ্রেডটি পুনরুদ্ধারের জন্য ক্ষমা চেয়েছিলেন, তবে এটি উল্লেখ করা উপযুক্ত বলে মনে হয় যা iscloseসর্বদা কম রক্ষণশীল মানদণ্ডকে মেনে চলে । আমি কেবল এটি উল্লেখ করেছি কারণ সেই আচরণটি আমার কাছে প্রতিদ্বন্দ্বী। আমি যদি দুটি মানদণ্ড নির্দিষ্ট করে থাকি তবে আমি সর্বদা ক্ষুদ্রতর সহনশীলতাটিকে আরও বেশি করে তুলতে আশা করি।
ম্যাকি মেসার

3
@ ম্যাকিমেসার আপনি অবশ্যই আপনার মতামতের অধিকারী, তবে এই আচরণটি আমার কাছে সঠিক ধারণা দেয়। আপনার সংজ্ঞা অনুসারে কিছুই কখনও শূন্যের কাছাকাছি হতে পারে না, কারণ শূন্য দ্বারা গুণিত একটি আপেক্ষিক সহনশীলতা সর্বদা শূন্য থাকে।
মার্ক

71

নীচের মত সাধারণ কিছু কি যথেষ্ট পর্যাপ্ত নয়?

return abs(f1 - f2) <= allowed_error

8
আমি যে লিঙ্কটি দিয়েছি তা উল্লেখ করেছি, যদি আপনি আগে থেকে সংখ্যার আনুমানিক পরিধিটি জানেন তবে বিয়োগ কেবলমাত্র কাজ করে।
গর্ডন রাইগলে

8
আমার অভিজ্ঞতা, ভাসে তুলনা জন্য শ্রেষ্ঠ পদ্ধতি হল: abs(f1-f2) < tol*max(abs(f1),abs(f2))। এই ধরণের আপেক্ষিক সহনশীলতা হ'ল সাধারণভাবে ভাসমানগুলির তুলনা করার একমাত্র অর্থবহ উপায়, কারণ তারা সাধারণত ছোট দশমিক স্থানে রাউন্ডঅফ ত্রুটির দ্বারা প্রভাবিত হয়।
Sesquipedal

2
এটি কার্যকর না হওয়ায় কেবল একটি সাধারণ উদাহরণ যুক্ত >>> abs(0.04 - 0.03) <= 0.01করে:, ফলন হয় False। আমি ব্যবহার করিPython 2.7.10 [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
0-0 এ স্কেচেন

3
@ ন্যায্য হতে হবে, উদাহরণটি নির্দিষ্ট তুলনার তুলনায় মেশিন বাইনারি যথার্থ / ফর্ম্যাটগুলির সাথে আরও বেশি কিছু করতে পারে। আপনি সিস্টেমে 0.03 প্রবেশ করানোর সময়, এটি আসলে সিপিইউতে তৈরি করা সংখ্যা নয়।
অ্যান্ড্রু হোয়াইট

2
@ অ্যান্ড্রুউইট উদাহরণটি দেখায় যা abs(f1 - f2) <= allowed_errorপ্রত্যাশার মতো কাজ করে না।
স্ক্যান করুন

44

আমি সম্মত হব যে গ্যারেথের উত্তর সম্ভবত একটি লাইটওয়েট ফাংশন / সমাধান হিসাবে সবচেয়ে উপযুক্ত।

তবে আমি ভেবেছিলাম এটি সহায়ক হবে যে আপনি যদি নম্পপি ব্যবহার করছেন বা এটি বিবেচনা করছেন তবে এটির জন্য একটি প্যাকেজড ফাংশন রয়েছে।

numpy.isclose(a, b, rtol=1e-05, atol=1e-08, equal_nan=False)

যদিও কিছুটা অস্বীকৃতি: আপনার প্ল্যাটফর্মের উপর নির্ভর করে NumPy ইনস্টল করা একটি তুচ্ছ অভিজ্ঞতা হতে পারে।


1
"ন্যাম্পি ইনস্টল করা আপনার প্ল্যাটফর্মের উপর নির্ভর করে একটি তুচ্ছ অভিজ্ঞতা হতে পারে" "... উম কি? কোন প্ল্যাটফর্মগুলি নম্পটি ইনস্টল করা "অ-তুচ্ছ"? কী একে একে তুচ্ছ-তুচ্ছ করে তুলেছে?
জন

10
@ জন: উইন্ডোজের জন্য একটি 64-বিট বাইনারি পাওয়া শক্ত to pipউইন্ডোজের মাধ্যমে অদ্ভুত পাওয়া শক্ত ।
বেন বলকার

@ টার্নাক: আমি করি তবে আমার কিছু শিক্ষার্থী উইন্ডোজ ব্যবহার করে, তাই আমাকে এই জিনিসগুলি মোকাবেলা করতে হবে।
বেন বলকার

4
@BenBolker আপনি পাইথন দ্বারা চালিত মুক্ত ডেটা বিজ্ঞান প্ল্যাটফর্ম ইনস্টল করতে থাকে, তাহলে সবচেয়ে ভালো উপায় Anaconda দ্বারা হয় continuum.io/downloads (পান্ডাস, numpy এবং বাক্সের বাইরে বেশি)
jrovegno

অ্যানাকোন্ডা ইনস্টল করা তুচ্ছ
এন্ডোলিথ

13

পাইথনের decimalমডিউল ব্যবহার করুন , যা Decimalশ্রেণি সরবরাহ করে ।

মন্তব্য থেকে:

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


11

পাইথন স্ট্যান্ডার্ড লাইব্রেরিতে (বা অন্য কোথাও) ডসনের AlmostEqual2sComplementফাংশন প্রয়োগ করে এমন কিছু সম্পর্কে আমি সচেতন নই । যদি আপনি চান এমন আচরণ যদি এটি করতে চান তবে আপনাকে এটি নিজে প্রয়োগ করতে হবে। (যা ক্ষেত্রে, বরং ডসন এর চালাক, bitwise হ্যাক ব্যবহার না করে আপনি সম্ভবত ভাল ফর্ম আরো প্রচলিত পরীক্ষা ব্যবহার করতে করতে চাই if abs(a-b) <= eps1*(abs(a)+abs(b)) + eps2বা অনুরূপ পেতে ডসন মত আচরণ তোমার মত কিছু বলতে পারে। if abs(a-b) <= eps*max(EPS,abs(a),abs(b))কিছু ছোট সংশোধন করা হয়েছে EPS; এই ঠিক নয় ডসনের মতো একই, তবে এটি স্পিরিটের সাথে একই।


আপনি এখানে যা করছেন তা আমি পুরোপুরি অনুসরণ করি না তবে এটি আকর্ষণীয়। Eps, eps1, eps2 এবং EPS এর মধ্যে পার্থক্য কী?
গর্ডন রাইগলে

eps1এবং eps2কোনও আত্মীয় এবং নিরঙ্কুশ সহনশীলতার সংজ্ঞা দিন: আপনি কত বড় তারা আরও কতবার তা মঞ্জুরি দিতে aএবং bআলাদা করার জন্য প্রস্তুত । একক সহনশীলতা; আপনি কত বড় সেগুলি মঞ্জুরি দেওয়ার জন্য এবং তার থেকে পৃথক হওয়ার জন্য প্রস্তুত রয়েছেন, এই প্রবণতার সাথে যে আকার বা ছোট কিছুকে আকার বলে মনে করা হয় । যদি আপনি আপনার ভাসমান-বিন্দুর প্রকারের ক্ষুদ্রতম অ-ডেনারমাল মান হিসাবে গ্রহণ করেন তবে এটি ডসনের তুলনাকারের সাথে খুব একই রকম (2 ^ # বিটের একটি ফ্যাক্টর বাদে কারণ ডসন ওপলসগুলিতে সহনশীলতা পরিমাপ করে)। eps1eps2epsabepsEPSEPSEPS
গ্যারেথ ম্যাককৌঘান

2
ঘটনাক্রমে, আমি এস লটের সাথে একমত হই যে ডান থিংটি সর্বদা আপনার প্রকৃত প্রয়োগের উপর নির্ভর করে যা এজন্য আপনার সমস্ত ভাসমান-পয়েন্ট তুলনা প্রয়োজনের জন্য একক মানের গ্রন্থাগার ফাংশন নেই।
গ্যারেথ ম্যাককৌঘান

@ গ্যারেথ-এমসিএকউঘান কীভাবে পাইথনটির জন্য একজন "আপনার ভাসমান-বিন্দুর ধরণের ক্ষুদ্রতম অ-ডেনারমাল মান" নির্ধারণ করবেন?
গর্ডন রাইগলে

এই পৃষ্ঠাটি docs.python.org/tutorial/floatingpoint.html প্রায় সব পাইথন বাস্তবায়নের আইইইই-754 ডবল স্পষ্টতা ভাসে ব্যবহার বলছেন এবং এই পৃষ্ঠাটি en.wikipedia.org/wiki/IEEE_754-1985 বলছেন সাধারণ সংখ্যার শূন্য নিকটস্থ ± 2 হয় * * -1022।
গর্ডন রাইগলে

11

সমানতার জন্য ভাসমান-পয়েন্ট সংখ্যাগুলির তুলনা করা যায় না এমন সাধারণ জ্ঞানটি সঠিক নয়। ভাসমান-পয়েন্ট সংখ্যাগুলি পূর্ণসংখ্যার চেয়ে পৃথক নয়: আপনি যদি "a == খ" মূল্যায়ন করেন তবে সেগুলি যদি অভিন্ন সংখ্যা এবং অন্যথায় মিথ্যা হয় তবে সত্য হবে (এই বোঝার সাথে যে দুটি এনএএন অবশ্যই অভিন্ন সংখ্যা নয়)।

আসল সমস্যাটি হ'ল: আমি যদি কিছু গণনা করেছি এবং আমি নিশ্চিত হতে পারি না যে দুটি সংখ্যার সাথে আমার তুলনা করতে হবে ঠিক সঠিক, তবে কী? এই সমস্যাটি ভাসমান-পয়েন্টের ক্ষেত্রে একই হিসাবে এটি পূর্ণসংখ্যার জন্য। যদি আপনি "7/3 * 3" পূর্ণসংখ্যাটি মূল্যায়ণ করেন তবে এটি "7 * 3/3" এর সাথে তুলনা করবে না।

সুতরাং ধরুন আমরা জিজ্ঞাসা করেছি "সাম্যের জন্য আমি কীভাবে পূর্ণসংখ্যার তুলনা করব?" এমন পরিস্থিতিতে কোন একক উত্তর নেই; আপনার কী করা উচিত তা নির্দিষ্ট পরিস্থিতির উপর নির্ভর করে, উল্লেখযোগ্যভাবে আপনার কী ধরণের ত্রুটি রয়েছে এবং আপনি কী অর্জন করতে চান।

এখানে কয়েকটি সম্ভাব্য পছন্দ রয়েছে।

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

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

আপনি যদি গাণিতিকভাবে সঠিক সংখ্যাটি অসম হলে "মিথ্যা" ফলাফল পেতে চান, আপনার যদি প্রমাণ করা দরকার যে গাণিতিকভাবে সঠিক সংখ্যাটি অসম হবে তবে সংখ্যার আপনার মূল্যায়নের বিভিন্ন সংখ্যা পাওয়া যায়। অনেক সাধারণ পরিস্থিতিতে ব্যবহারিক উদ্দেশ্যে এটি অসম্ভব হতে পারে। সুতরাং আসুন একটি বিকল্প বিবেচনা করা যাক।

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

সুতরাং, ভাসমান-পয়েন্ট সংখ্যাগুলির তুলনা করার সময় কী কী ফিরে আসবেন তা আপনি কীভাবে সিদ্ধান্ত নেবেন তা আপনার নির্দিষ্ট পরিস্থিতির উপর নির্ভর করে।

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

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

এই বিষয় সম্পর্কে আরও অনেক কিছুই লেখা যেতে পারে (এবং হয়) তবে আমাকে সেখানে থামতে হবে। সংক্ষেপে, উত্তরটি হল: এই তুলনা করার জন্য লাইব্রেরির কোনও রুটিন নেই কারণ কোনও একক সমাধান নেই যা বেশিরভাগ প্রয়োজনের সাথে খাপ খায় যা লাইব্রেরির রুটিনে রাখার মতো worth (যদি কোনও আপেক্ষিক বা পরম ত্রুটি ব্যবধানের সাথে তুলনা করা আপনার পক্ষে যথেষ্ট হয় তবে আপনি এটি লাইব্রেরির রুটিন ব্যতীত সহজভাবে করতে পারেন)


3
গ্যারেথ ম্যাককাউনের সাথে উপরের আলোচনা থেকে সঠিকভাবে আপেক্ষিক ত্রুটির সাথে তুলনা করা মূলত " অ্যাবস ( অ্যাব) <= এপিএস সর্বাধিক (2 * -1022, অ্যাবস (এ), অ্যাবস (বি))" এর সমান, এটি আমি বর্ণনা করছি এমন কিছু নয় হিসাবে সহজ এবং অবশ্যই কিছু না আমি নিজেই কাজ করেছি। স্টিভ জেসোপ যেমন উল্লেখ করেছেন যে এটি সর্বাধিক, ন্যূনতম, যে কোনও এবং সবকিছুরই অনুরূপ জটিলতা, যা সমস্ত বিল্টইন। সুতরাং প্রমিত গণিতের মডিউলটিতে তুলনামূলক ত্রুটি সরবরাহ করা ভাল ধারণা বলে মনে হচ্ছে।
গর্ডন রাইগলে

(7/3 * 3 == 7 * 3/3) পাইথনে সত্যের মূল্যায়ন করে।
xApple

@ এক্সপ্লেল: আমি ওএস এক্স 10.8.3 এ পাইথন ২.7.২ চালিয়ে প্রবেশ করেছি (7/3*3 == 7*3/3)। এটি মুদ্রিত False
এরিক পোস্টপিশিল

3
আপনি সম্ভবত টাইপ করতে ভুলে গেছেন from __future__ import division। যদি আপনি এটি না করেন তবে কোনও ভাসমান পয়েন্ট সংখ্যা নেই এবং তুলনা দুটি পূর্ণসংখ্যার মধ্যে রয়েছে।
এক্সএপল

3
এটি একটি গুরুত্বপূর্ণ আলোচনা, তবে অবিশ্বাস্যরূপে সহায়ক নয়।
ড্যান হাল্মে

6

আপনি যদি এটি টেস্টিং / টিডিডি প্রসঙ্গে ব্যবহার করতে চান তবে আমি বলতে পারি এটি একটি আদর্শ উপায়:

from nose.tools import assert_almost_equals

assert_almost_equals(x, y, places=7) #default is 7

5

math.isclose () পাইথন 3.5 তে যুক্ত করা হয়েছে ( উত্স কোড ) এর জন্য। পাইথন ২-তে এটির একটি বন্দর এখানে রয়েছে মার্ক র্যানসমের এক-লাইনারের থেকে পার্থক্য হ'ল এটি "ইনফ" এবং "ইনফ" সঠিকভাবে পরিচালনা করতে পারে।

def isclose(a, b, rel_tol=1e-09, abs_tol=0.0):
    '''
    Python 2 implementation of Python 3.5 math.isclose()
    https://hg.python.org/cpython/file/tip/Modules/mathmodule.c#l1993
    '''
    # sanity check on the inputs
    if rel_tol < 0 or abs_tol < 0:
        raise ValueError("tolerances must be non-negative")

    # short circuit exact equality -- needed to catch two infinities of
    # the same sign. And perhaps speeds things up a bit sometimes.
    if a == b:
        return True

    # This catches the case of two infinities of opposite sign, or
    # one infinity and one finite number. Two infinities of opposite
    # sign would otherwise have an infinite relative tolerance.
    # Two infinities of the same sign are caught by the equality check
    # above.
    if math.isinf(a) or math.isinf(b):
        return False

    # now do the regular computation
    # this is essentially the "weak" test from the Boost library
    diff = math.fabs(b - a)
    result = (((diff <= math.fabs(rel_tol * b)) or
               (diff <= math.fabs(rel_tol * a))) or
              (diff <= abs_tol))
    return result

2

আমি নিম্নলিখিত তুলনা সহায়ক বলে মনে করেছি:

str(f1) == str(f2)

এটি আকর্ষণীয়, তবে str (.1 + .2) == .3 এর কারণে খুব ব্যবহারিক নয়
গর্ডন রাইগলে

str (.1 + .2) == স্ট্র (.3) সত্য
ফেরায়

এটি কীভাবে এফ 1 == এফ 2 থেকে আলাদা - যদি তারা উভয় ঘনিষ্ঠ হন তবে যথার্থতার কারণে আলাদা হয় তবে স্ট্রিংয়ের উপস্থাপনাগুলিও অসম হবে।
মিঃমাস

2
.1 + .2 == .3 মিথ্যা প্রত্যাবর্তন করে যখন str (.1 + .2) == স্ট্র (.3) সত্য
ফেরায়

4
পাইথন ৩.7.২-তে, str(.1 + .2) == str(.3)মিথ্যা ফিরিয়ে দেয়। উপরে বর্ণিত পদ্ধতিটি কেবল পাইথন ২ এর জন্য কাজ করে
ড্যানিবিক্স

1

কিছু ক্ষেত্রে যেখানে আপনি উত্স নম্বর উপস্থাপনাকে প্রভাবিত করতে পারেন, আপনি পূর্ণসংখ্যার অঙ্ক এবং ডিনোমিনেটর ব্যবহার করে ফ্লোটের পরিবর্তে ভগ্নাংশ হিসাবে প্রতিনিধিত্ব করতে পারেন। এইভাবে আপনি সঠিক তুলনা করতে পারেন।

দেখুন ভগ্নাংশ ভগ্নাংশ বিস্তারিত জানার জন্য মডিউল থেকে।


1

আমি @ স্পেসিপিডেলের পরামর্শটি পছন্দ করেছি তবে পরিবর্তনের সাথে (যখন একটি বিশেষ ব্যবহারের ক্ষেত্রে যখন উভয় মানই 0 টি মিথ্যা হয়) se আমার ক্ষেত্রে আমি পাইথন ২.7 এ ছিলাম এবং স্রেফ একটি সাধারণ ফাংশন ব্যবহার করেছি:

if f1 ==0 and f2 == 0:
    return True
else:
    return abs(f1-f2) < tol*max(abs(f1),abs(f2))

1

যে ক্ষেত্রে আপনি নিশ্চিত করতে চান যে 2 সংখ্যা একই 'যথাযথ অবধি', সেখানে সহনশীলতা নির্দিষ্ট করার দরকার নেই:

  • 2 সংখ্যার নূন্যতম নির্ভুলতা সন্ধান করুন

  • উভয়কে ন্যূনতম নির্ভুলতা এবং তুলনায় গোল করুন

def isclose(a,b):                                       
    astr=str(a)                                         
    aprec=len(astr.split('.')[1]) if '.' in astr else 0 
    bstr=str(b)                                         
    bprec=len(bstr.split('.')[1]) if '.' in bstr else 0 
    prec=min(aprec,bprec)                                      
    return round(a,prec)==round(b,prec)                               

লিখিত হিসাবে, কেবল তাদের স্ট্রিং উপস্থাপনায় 'ই' ছাড়াই সংখ্যার জন্য কাজ করে (যার অর্থ 0.9999999999995e-4 <সংখ্যা <= 0.9999999999995e11)

উদাহরণ:

>>> isclose(10.0,10.049)
True
>>> isclose(10.0,10.05)
False

কাছাকাছি সীমাহীন ধারণা আপনাকে ভাল পরিবেশন করবে না। isclose(1.0, 1.1)উত্পাদন করে Falseএবং isclose(0.1, 0.000000000001)ফেরত দেয় True
কেএফসনে 21

1

প্রদত্ত দশমিক পর্যন্ত তুলনা করা ছাড়া atol/rtol:

def almost_equal(a, b, decimal=6):
    return '{0:.{1}f}'.format(a, decimal) == '{0:.{1}f}'.format(b, decimal)

print(almost_equal(0.0, 0.0001, decimal=5)) # False
print(almost_equal(0.0, 0.0001, decimal=4)) # True 

1

এটি সম্ভবত কিছুটা কুৎসিত হ্যাক, তবে যখন আপনার ডিফল্ট ফ্লোট যথার্থতা (প্রায় 11 দশমিক) এর চেয়ে বেশি প্রয়োজন হয় না তখন এটি বেশ ভাল কাজ করে।

Round_to ফাংশন ব্যবহার বিন্যাস পদ্ধতি থেকে বিল্ট-ইন একটি স্ট্রিং, যাতে প্রয়োজন দশমিক সংখ্যা সঙ্গে ভাসা প্রতিনিধিত্ব করে, এবং তারপর ভাসা ধরপাকড় করার Str বর্গ প্রযোজ্য Eval বৃত্তাকার ভাসা স্ট্রিং ফিরে পেতে করার বিল্ট ইন ফাংশন ভাসা সংখ্যার টাইপ।

Is_close ফাংশন শুধু বৃত্তাকার আপ ভাসা এটি একটি সহজ শর্তাধীন প্রযোজ্য।

def round_to(float_num, prec):
    return eval("'{:." + str(int(prec)) + "f}'.format(" + str(float_num) + ")")

def is_close(float_a, float_b, prec):
    if round_to(float_a, prec) == round_to(float_b, prec):
        return True
    return False

>>>a = 10.0
10.0
>>>b = 10.0001
10.0001
>>>print is_close(a, b, prec=3)
True
>>>print is_close(a, b, prec=4)
False

হালনাগাদ:

@ স্টেপহিজফক্সের পরামর্শ অনুসারে, " ইওআল " এড়ানো rount_to ফাংশন তৈরির একটি ক্লিনার উপায় নেস্টেড ফর্ম্যাটিংটি ব্যবহার করছে :

def round_to(float_num, prec):
    return '{:.{precision}f}'.format(float_num, precision=prec)

একই ধারণা অনুসরণ করে দুর্দান্ত নতুন এফ-স্ট্রিংগুলি (পাইথন ৩.6+) ব্যবহার করে কোডটি আরও সহজ হতে পারে :

def round_to(float_num, prec):
    return f'{float_num:.{prec}f}'

সুতরাং, আমরা এগুলি সমস্ত কিছু একটি সাধারণ এবং পরিষ্কার 'is_close' ফাংশনে গুটিয়ে রাখতে পারি :

def is_close(a, b, prec):
    return f'{a:.{prec}f}' == f'{b:.{prec}f}'

1
eval()প্যারামিটারাইজড ফরম্যাটিং পেতে আপনাকে ব্যবহার করতে হবে না । এর মতো কিছু return '{:.{precision}f'.format(float_num, precision=decimal_precision) এটি করা উচিত
স্টেফেনজফক্স

1
আমার মন্তব্য এবং আরও উদাহরণের জন্য উত্স: pyformat.info/#param_align
স্টেফেনজফক্স

1
ধন্যবাদ @ স্টেফেনজফক্স আমি নেস্টেড ফর্ম্যাটিং সম্পর্কে জানতাম না। বিটিডব্লিউ, আপনার স্যাম্পল কোডটিতে শেষ কোঁকড়া ধনুর্বন্ধুর অভাব রয়েছে:return '{:.{precision}}f'.format(float_num, precision=decimal_precision)
অ্যালবার্ট অলমার

1
ভাল ক্যাচ, এবং বিশেষত এফ-স্ট্রিংগুলির সাহায্যে ভাল কাজ করা। কোণার চারপাশে পাইথন 2 এর মৃত্যুর সাথে, সম্ভবত এটি আদর্শ হয়ে উঠবে
স্টেফেনজফক্স

0

পরম ত্রুটির শর্তাবলী, আপনি কেবল পরীক্ষা করতে পারেন

if abs(a - b) <= error:
    print("Almost equal")

পাইথনে কেন ভাসমান আচরণের কিছু তথ্য https://youtu.be/v4HhvoNLILk?t=1129

আপেক্ষিক ত্রুটির জন্য আপনি math.isclose ব্যবহার করতে পারেন

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