ভাসমান পয়েন্ট গণিত কি ভেঙে গেছে?


2977

নিম্নলিখিত কোড বিবেচনা করুন:

0.1 + 0.2 == 0.3  ->  false
0.1 + 0.2         ->  0.30000000000000004

কেন এই অনর্থক ঘটনা ঘটে?


127
ভাসমান পয়েন্ট ভেরিয়েবলগুলির সাধারণত এই আচরণ থাকে। তারা হার্ডওয়্যারে কীভাবে সংরক্ষণ করা হয় তার কারণে এটি ঘটে। আরও তথ্যের জন্য ভাসমান পয়েন্ট সংখ্যাগুলির উইকিপিডিয়া নিবন্ধটি দেখুন
বেন এস

62
জাভাস্ক্রিপ্ট দশমিককে ভাসমান পয়েন্ট সংখ্যা হিসাবে বিবেচনা করে , যার অর্থ সংযোজনের মতো ক্রিয়াকলাপটি বৃত্তাকার ত্রুটির সাথে সম্পর্কিত হতে পারে। আপনি এই নিবন্ধটি একবার দেখে নিতে পারেন: প্রতিটি কম্পিউটার বিজ্ঞানী ভাসমান-পয়েন্ট গাণিতিক সম্পর্কে কি জানা উচিত
ম্যাট বি

4
কেবল তথ্যের জন্য, জাভাস্ক্রিপ্টে সমস্ত সংখ্যার প্রকারগুলি হ'ল আইইইই -754 ডাবল।
গ্যারি উইলফোবি

6
জাভাস্ক্রিপ্টটি গণিতের জন্য আইইইই 754 মান ব্যবহার করে, এটি 64-বিট ভাসমান সংখ্যার ব্যবহার করে of সংক্ষিপ্তভাবে, বেস 2 তে কাজ করা কম্পিউটারগুলির কারণে এবং দশমিক 10 হ'ল কম্পিউটার 10 এর ফলে ভাসমান পয়েন্ট (দশমিক) গণনা করার সময় এটি নির্ভুল ত্রুটি ঘটায় ।
পারদীপ জৈন

উত্তর:


2243

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

জন্য 0.1মান মধ্যে binary64ফরম্যাট, উপস্থাপনা ঠিক হিসেবে লেখা যেতে পারে

বিপরীতে, যুক্তিযুক্ত সংখ্যা 0.1, যা হয় 1/10ঠিক ঠিক হিসাবে লেখা যেতে পারে

  • 0.1 দশমিক মধ্যে, বা
  • 0x1.99999999999999...p-4সি 99 হেক্সফ্লায়েট স্বরলিপিটির একটি অ্যানালগে, যেখানে ...9 এর সমাপ্তি ধারাবাহিকতা উপস্থাপন করে।

আপনার প্রোগ্রামে ধ্রুবকগুলি 0.2এবং 0.3তাদের প্রকৃত মূল্যবোধগুলির সাথে অনুমানও হবে। ঘটনাচক্রে নিকটস্থ যে doubleকরতে 0.2মূলদ সংখ্যার চেয়ে বড় 0.2কিন্তু যে নিকটতম doubleকরতে 0.3মূলদ সংখ্যার চেয়ে কম 0.3। যোগফল 0.1এবং 0.2যুক্তিযুক্ত সংখ্যার চেয়ে বড় হয়ে বাড়ে 0.3এবং তাই আপনার কোডের ধ্রুবকটির সাথে একমত নন।

ভাসমান-পয়েন্ট পাটিগণিত বিষয়গুলির একটি মোটামুটি বিস্তৃত চিকিত্সা হ'ল প্রতিটি কম্পিউটার বিজ্ঞানী ভাসমান-পয়েন্ট পাটিগণিত সম্পর্কে জানা উচিত । সহজে-ডাইজেস্ট ব্যাখ্যার জন্য ভাসমান -পয়েন্ট- gui.de দেখুন ।

পার্শ্ব দ্রষ্টব্য: সমস্ত অবস্থানগত (বেস-এন) নম্বর সিস্টেম নির্ভুলতার সাথে এই সমস্যাটি ভাগ করে

সরল পুরাতন দশমিক (বেস 10) সংখ্যার একই সমস্যা রয়েছে, এ কারণেই 1/3 এর মতো নম্বরগুলি 0.333333333 হিসাবে শেষ হয় ...

আপনি কেবলমাত্র একটি সংখ্যায় (3-10) হোঁচট খেয়েছেন যা দশমিক সিস্টেমের সাথে প্রতিনিধিত্ব করা সহজ বলে মনে হয় তবে বাইনারি সিস্টেমে ফিট করে না। এটি উভয় উপায়েও যায় (কিছুটা কম ডিগ্রীতেও): ১/১16 দশমিক (০.০6২৫) এ একটি কুৎসিত সংখ্যা, তবে বাইনারিতে এটি দশম (১০,০০০) **-তে যতটা 10,000 এর মতো পরিষ্কার ঝরঝরে দেখাচ্ছে - যদি আমরা থাকতাম আমাদের প্রতিদিনের জীবনে বেস -২ নম্বর সিস্টেমটি ব্যবহার করার অভ্যাসটি, আপনি এমনকি সেই সংখ্যাটি দেখতে চাইবেন এবং স্বভাবতই বুঝতে পারবেন যে আপনি সেখানে কিছুটা অর্ধেক রেখে আবার পৌঁছে যেতে পারেন এবং বারবার ফিরে আসতে পারেন।

** অবশ্যই, ভাসমান-পয়েন্ট সংখ্যাগুলি মেমরিতে কীভাবে সংরক্ষণ করা হয় তা নয় (তারা বৈজ্ঞানিক স্বরলিপি ব্যবহার করে)। তবে এটি সেই বিন্দুর চিত্র তুলে ধরেছে যে বাইনারি ভাসমান-পয়েন্ট যথার্থ ত্রুটিগুলি ক্রপ হওয়ার প্রবণতা দেখা দেয় কারণ আমরা যে "আসল ওয়ার্ল্ড" নাম্বারগুলির সাথে সাধারণত কাজ করতে আগ্রহী তা প্রায় দশবারের শক্তি - তবে কেবলমাত্র আমরা দশমিক সংখ্যা সিস্টেমের দিন ব্যবহার করি- আজ. এ কারণেই আমরা "প্রতি of জনের মধ্যে ৫" এর পরিবর্তে %১% এর মতো জিনিসগুলি বলব (%১% একটি অনুমান, কারণ ৫/ any কোনও দশমিক সংখ্যার সাথে হুবহু উপস্থাপন করা যায় না)।

সুতরাং না: বাইনারি ভাসমান পয়েন্ট সংখ্যাগুলি ভাঙা হয় না, তারা কেবল প্রতিটি অন্যান্য বেস-এন নম্বর সিস্টেমের মতো অপূর্ণ হতে পারে :)

সাইড সাইড নোট: প্রোগ্রামিং ইন ফ্লোটের সাথে কাজ করা

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

আপনাকে সাম্যতা পরীক্ষাগুলি তুলনা করে প্রতিস্থাপন করতে হবে যা কিছু পরিমাণ সহনশীলতার মঞ্জুরি দেয়, যার অর্থ:

না না নাif (x == y) { ... }

পরিবর্তে না if (abs(x - y) < myToleranceValue) { ... }

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


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

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

19
গতির জন্য ক্রে খচিত আইইইই -754 সম্মতি। জাভা পাশাপাশি এটির একটি অপ্টিমাইজেশন হিসাবে আলগা।
আর্ট টেলর

28
আমি মনে করি যে অর্থের পরিমাণ কীভাবে গণনা করা যায় সবসময় পূর্ণসংখ্যার উপর স্থির-পয়েন্ট পাটিগণিত দিয়ে করা উচিত সে সম্পর্কে আপনার এই উত্তরে কিছু যুক্ত করা উচিত , কারণ অর্থের পরিমাণ চূড়ান্ত হয়। (শতকরা ক্ষুদ্র ক্ষুদ্র অংশে অভ্যন্তরীণ হিসাব নিরীক্ষণ করা বা আপনার ক্ষুদ্রতম মুদ্রা ইউনিট যা-ই হবে তা বোঝা যায় - এটি প্রায়শই উদাহরণস্বরূপ, "প্রতি মাসে ২৯.৯৯ ডলার" রূপান্তর করার সময় রাউন্ড-অফ ত্রুটি হ্রাস করতে সহায়তা করে - তবে এটি হওয়া উচিত) এখনও স্থির-পয়েন্ট পাটিগণিত হতে হবে।)
zwol

18
মজাদার ঘটনা: বাইনারি ভাসমান বিন্দুতে একেবারে 0.1 টি সঠিকভাবে উপস্থাপিত না হওয়ায় একটি কুখ্যাত প্যাট্রিয়ট ক্ষেপণাস্ত্র সফ্টওয়্যার বাগের সৃষ্টি হয়েছিল যার ফলস্বরূপ প্রথম ইরাক যুদ্ধের সময় 28 জন নিহত হয়েছিল।
এইচডিএল

602

একটি হার্ডওয়্যার ডিজাইনারের দৃষ্টিভঙ্গি

আমি বিশ্বাস করি যেহেতু আমি ভাসমান পয়েন্ট হার্ডওয়্যার ডিজাইন করি এবং তৈরি করি সেহেতু আমার এটিতে একটি হার্ডওয়্যার ডিজাইনারের দৃষ্টিভঙ্গি যুক্ত করা উচিত। ত্রুটিটির উত্স জানার ফলে সফ্টওয়্যারটিতে কী ঘটছে তা বুঝতে সহায়তা করতে পারে এবং শেষ পর্যন্ত, আমি আশা করি যে এটি কেন ভাসমান পয়েন্ট ত্রুটিগুলি ঘটে যায় এবং সময়ের সাথে এটি কীভাবে জমা হয় বলে মনে হয় তার কারণগুলি ব্যাখ্যা করতে সহায়তা করে।

1। সংক্ষিপ্ত বিবরণ

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

2. মানক

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

আইইইই-754৪ স্ট্যান্ডার্ডে, হার্ডওয়্যার ডিজাইনারদের ত্রুটি / এপসিলনের কোনও মান অনুমোদিত হয় যতক্ষণ না এটি শেষ স্থানে এক ইউনিটের অর্ধেকেরও কম, এবং ফলাফলটি কেবল সর্বশেষে এক ইউনিটের অর্ধেকেরও কম হতে হবে একটি অপারেশন জন্য স্থান। এটি ব্যাখ্যা করে যে কেন যখন বারবার অপারেশন করা হয়, ত্রুটিগুলি যুক্ত হয়। আইইইই-75 75৪ ডাবল স্পষ্টতার জন্য, এটি 54 তম বিট, যেহেতু 53 বিটগুলি ভাসমান পয়েন্ট সংখ্যার (যেমন, ম্যান্টিসা) নামক সংখ্যাটি (সাধারণকরণ) উপস্থাপন করতে ব্যবহৃত হয় (উদাহরণস্বরূপ 5.3e5-তে 5.3)। পরবর্তী বিভাগগুলি বিভিন্ন ভাসমান পয়েন্ট ক্রিয়াকলাপগুলিতে হার্ডওয়্যার ত্রুটির কারণগুলি সম্পর্কে আরও বিশদে যায়।

৩. বিভাগে রাউন্ডিং ত্রুটির কারণ

ভাসমান বিন্দু বিভাগে ত্রুটির মূল কারণটি ভাগফল গণনা করার জন্য ব্যবহৃত বিভাগ অ্যালগরিদম। সর্বাধিক কম্পিউটার সিস্টেম, একটি বিপরীত দ্বারা গুণ ব্যবহার বিভাজন নিরূপণ প্রধানত মধ্যে Z=X/Y,Z = X * (1/Y) । একটি বিভাগ পুনরাবৃত্তভাবে গণনা করা হয় অর্থাত্ প্রতিটি চক্রটি যথাক্রমে নির্ভুলতা না পাওয়া পর্যন্ত ভাগফলের কিছু বিট গণনা করে, যা আইইইই -754 এর জন্য শেষ স্থানে এক ইউনিটেরও কম ত্রুটিযুক্ত এমন কোনও কিছুই। Y (1 / Y) এর পুনঃপ্রেরণের টেবিলটি ধীর বিভাগে ভাগফল নির্বাচন টেবিল (কিউএসটি) হিসাবে পরিচিত, এবং ভাগফল নির্বাচন টেবিলের বিটগুলির আকারটি সাধারণত রেডিক্সের প্রস্থ বা বেশ কয়েকটি বিট হয় ভাগফল প্রতিটি পুনরাবৃত্তিতে গুণিত হয়, এবং কয়েক গার্ড বিট। আইইইই-754৪ স্ট্যান্ডার্ড, ডাবল যথার্থতা (64৪-বিট) এর জন্য এটি ডিভাইডারের মূলাকৃতির আকার এবং কয়েকটি গার্ড বিট কে হবে যেখানেk>=2। সুতরাং উদাহরণস্বরূপ, একটি বিভাজকের জন্য একটি আদর্শ কোটিয়েন্টিয়েন্ট সিলেকশন টেবিল যা একসাথে ভাগফলের 2 বিট গণনা করে (মূলা 4) 2+2= 4বিট (আরও কয়েকটি aচ্ছিক বিট) হবে।

৩.১ বিভাগের রাউন্ডিং ত্রুটি: পারিশ্রমিকের সমাপ্তি

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

4. অন্যান্য অপারেশনগুলিতে রাউন্ডিং ত্রুটি: কাটা

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

5. পুনরাবৃত্তি অপারেশন

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

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

6. সংক্ষিপ্তসার

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


8
(3) ভুল। বিভাগে গোল করার ত্রুটিটি শেষ স্থানে এক ইউনিটের চেয়ে কম নয় , তবে শেষ স্থানে প্রায় অর্ধেক ইউনিট।
gnasher729

6
@ gnasher729 ভাল ক্যাচ বেশিরভাগ বেসিক অপারেশনগুলিতে ডিফল্ট আইইইই রাউন্ডিং মোড ব্যবহার করে শেষ স্থানে এক ইউনিটের 1/2 এরও কম ত্রুটি থাকে। ব্যাখ্যাটি সম্পাদনা করেছেন এবং আরও উল্লেখ করেছেন যে ব্যবহারকারী যদি ডিফল্ট রাউন্ডিং মোডকে ওভাররাইড করে (তবে এম্বেডড সিস্টেমে এটি বিশেষত সত্য) তবে এটি একটি উল্টোর ১/২ এর চেয়ে বেশি হতে পারে তবে 1 টি কমের চেয়ে কম হতে পারে।
কর্নেলপানিক

39
(1) ভাসমান পয়েন্ট সংখ্যাতে ত্রুটি নেই। প্রতিটি ভাসমান পয়েন্টের মানটি হুবহু। বেশিরভাগ (তবে সমস্ত নয়) ভাসমান পয়েন্ট অপারেশনগুলি নির্ভুল ফলাফল দেয়। উদাহরণস্বরূপ, কোনও বাইনারি ভাসমান বিন্দু মান নেই যা 1.0 / 10.0 এর ঠিক সমান। কিছু কার্যকলাপ (যেমন, 1.0 + + 1.0) না অন্যদিকে সঠিক ফলাফল দেয়।
সলোমন স্লো

19
"ভাসমান বিন্দু বিভাগে ত্রুটির প্রধান কারণ, ভাগফল গণনা করার জন্য ব্যবহৃত বিভাগ অ্যালগরিদম" বলতে খুব বিভ্রান্তিকর বিষয়। আইইইই -৫ 75৪ অনুসারী বিভাগের জন্য, ভাসমান-পয়েন্ট বিভাগে ত্রুটির একমাত্র কারণ ফলাফলের বিন্যাসে হুবহু প্রতিনিধিত্ব করতে অক্ষমতা; অ্যালগরিদম নির্বিশেষে একই ফলাফল গণনা করা হয় যা ব্যবহৃত হয়।
স্টিফেন ক্যানন

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

461

যখন আপনি .1 বা 1/10 কে বেস 2 (বাইনারি) এ রূপান্তর করেন আপনি দশমিক পয়েন্টের পরে পুনরাবৃত্তি প্যাটার্নটি পান, ঠিক যেমন বেস 10 তে 1/3 উপস্থাপন করার চেষ্টা করার মতো মান সঠিক নয়, এবং তাই আপনি করতে পারবেন না সাধারণ ভাসমান পয়েন্ট পদ্ধতি ব্যবহার করে এর সাথে সঠিক গণিত।


133
দুর্দান্ত এবং সংক্ষিপ্ত উত্তর। পুনরাবৃত্তি প্যাটার্ন দেখতে 0.00011001100110011001100110011001100110011001100110011 ...
কনস্ট্যান্টিন

4
এটি ব্যাখ্যা করে না যে কেন আরও ভাল অ্যালগরিদম ব্যবহার করা হয়নি যা বাইনারিগুলিকে প্রথম স্থানে রূপান্তর করে না।
দিমিত্রি জইতসেভ

12
কারণ পারফরম্যান্স। বাইনারি ব্যবহার করা কয়েক হাজার গুণ দ্রুত, কারণ এটি মেশিনের জন্য স্থানীয়।
জোয়েল কোহর্ন

7
এখানে এমন পদ্ধতি রয়েছে যা সঠিক দশমিক মান দেয়। বিসিডি (বাইনারি কোডড দশমিক) বা দশমিক সংখ্যার বিভিন্ন রূপ। তবে এগুলি উভয়ই ধীর (খুব বেশি ধীর) এবং বাইনারি ভাসমান পয়েন্ট ব্যবহার করার চেয়ে বেশি সঞ্চয়স্থান গ্রহণ করে। (উদাহরণস্বরূপ, স্কুবা BCD দোকানে একটি বাইট 2 দশমিক সংখ্যা বস্তাবন্দী এটা একটা বাইট যে আসলে একটি বাইট সম্ভাব্য মান 60% সম্পর্কে 256 সম্ভাব্য মান, বা 100/256, যা বর্জ্য সংরক্ষণ করতে পারেন 100 সম্ভাব্য মান আছে।।)
ডানকান সি

16
@ জ্যাকসনকর আপনি এখনও বেস -10 এ ভাবছেন। কম্পিউটারগুলি বেস -২।
জোয়েল কোহর্ন

306

এখানে বেশিরভাগ উত্তর খুব শুষ্ক, প্রযুক্তিগত দিক দিয়ে এই প্রশ্নের সমাধান করে। আমি এটিকে এমন পদে সম্বোধন করতে চাই যা সাধারণ মানুষ বুঝতে পারে।

কল্পনা করুন যে আপনি পিজ্জা টুকরো টুকরো করার চেষ্টা করছেন। আপনি একটি রোবটিক পিজা কর্তনকারী যে পিজা টুকরা কাটা পারেন ঠিক অর্ধেক। এটি পুরো পিজ্জা অর্ধেক করতে পারে, বা এটি কোনও বিদ্যমান স্লাইস অর্ধেক করতে পারে, তবে যে কোনও ক্ষেত্রে, অর্ধেকটি সর্বদা সঠিক।

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

এখন, আপনি কীভাবে এমন সমস্ত টুকরো টুকরো টুকরো করবেন যা পিজ্জার দশমাংশ (0.1) বা পঞ্চমাংশ (0.2) পর্যন্ত যোগ করবে? সত্যিই এটি সম্পর্কে চিন্তা করুন, এবং এটি চেষ্টা করে দেখুন। এমনকি যদি আপনার কাছে কোনও পৌরাণিক নির্ভুল পিজ্জা কাটার থাকে তবে আপনি একটি বাস্তব পিজ্জা ব্যবহার করার চেষ্টা করতে পারেন। :-)


সর্বাধিক অভিজ্ঞ প্রোগ্রামারদের, অবশ্যই, বাস্তব উত্তর, যা একসঙ্গে টুকরা করার কোনো উপায় একটি নেই জানি সঠিক দশম বা পিত্জার পঞ্চম ঐ টুকরা ব্যবহার করে, কোন ব্যাপার কিভাবে finely, আপনি তাদের যেভাবেই। আপনি একটি খুব ভাল আনুমানিকতা করতে পারেন, এবং আপনি যদি ০.০ এর সমমানের সাথে ০. এর কাছাকাছি যোগ করেন তবে আপনি ০.০ এর একটি খুব ভাল অনুমান পেতে পারেন, তবে এটি এখনও ঠিক এটিই, একটি প্রায় অনুমান।

ডাবল-স্পষ্টতা সংখ্যার জন্য (যা নির্ভুলতা আপনাকে আপনার পিজ্জা 53 বার অর্ধেক করার অনুমতি দেয়) জন্য, তাত্ক্ষণিক কম এবং 0.1 এর চেয়ে বেশি নম্বরগুলি 0.09999999999999999167332731531132594682276248931884765625 এবং 0.1000000000000555111512312578270211815834045410। পূর্ববর্তীটি পূর্বের তুলনায় বেশ কিছুটা 0.1 এর কাছাকাছি, সুতরাং একটি সংখ্যার পার্সার, 0.1 এর একটি ইনপুট দেওয়া, পরবর্তীটির পক্ষে হবে favor

(এই দুটি সংখ্যার মধ্যে পার্থক্য হ'ল "ক্ষুদ্রতম স্লাইস" যা আমাদের অবশ্যই অন্তর্ভুক্ত করার সিদ্ধান্ত নিতে হবে, যা একটি wardর্ধ্বমুখী পক্ষপাতের পরিচয় দেয়, বা বাদ দেয়, যা নিম্নমুখী পক্ষপাতের পরিচয় দেয় that সেই ক্ষুদ্রতম স্লাইসের জন্য প্রযুক্তিগত শব্দটি একটি lpাল হয় ))

০.২ এর ক্ষেত্রে, সংখ্যাগুলি সমস্ত একই, কেবল ২ এর গুণক দ্বারা ছোট করে দেওয়া হয়েছে আবারও, আমরা সেই মানটির পক্ষে যা 0.2 এর তুলনায় কিছুটা বেশি।

লক্ষ করুন যে উভয় ক্ষেত্রেই ০.০ এবং ০.২ এর জন্য অনুমানের ক্ষেত্রে সামান্য upর্ধ্বমুখী পক্ষপাত রয়েছে। যদি আমরা এই পক্ষপাতদুষ্টাগুলির মধ্যে যথেষ্ট পরিমাণ যুক্ত করি তবে তারা সংখ্যাটি আমাদের যা চায় তার থেকে আরও দূরে ঠেলে দেবে, এবং প্রকৃতপক্ষে ০.০ + ০.২ এর ক্ষেত্রে পক্ষপাতটি এত বেশি যে ফলস্বরূপ সংখ্যাটি এখন নিকটতম সংখ্যা নয় থেকে 0.3।

বিশেষত, 0.1 + 0.2 সত্যিই 0.1000000000000000035511151231257827021181583404541015625 + 0.200000000000000000000000000110000000000000000000000000000000000008203125 এর কেইউয়াস্তে জবাবদিস্তি হয়েছে 9880082098008208008208008208008208008208008208008208008008008208008208008008208008008008008008008208008208008008008008008208008008208008008208008,815980000


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

(মূলত কোরায় পোস্ট করা হয়েছে))


3
দ্রষ্টব্য যে কয়েকটি ভাষা রয়েছে যার মধ্যে সঠিক গণিত রয়েছে। একটি উদাহরণ স্কিম, উদাহরণস্বরূপ জিএনইউ গুইলের মাধ্যমে via দেখুন draketo.de/english/exact-math-to-the-rescue - এই ভগ্নাংশের হিসাবে গণিত রাখা এবং শুধুমাত্র শেষ পর্যন্ত যেভাবেই।
আর্নি Babenhauserheide

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

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

13
@ কনেক্সেক্স ঠিক আছে। 36 ডিগ্রি পেতে আপনি কীভাবে আপনার পিজ্জা রোটারটিকে প্রোগ্রাম করবেন? 36 ডিগ্রি কি? (ইঙ্গিত: আপনি যদি সঠিক ফ্যাশনে এটি সংজ্ঞায়িত করতে সক্ষম হন তবে আপনার কাছে একটি স্লাইসস-হুবহু দশমিক দশম পিজ্জা কাটারও রয়েছে)) অন্য কথায়, আপনার কাছে আসলে 1/360 (একটি ডিগ্রি) বা 1 / থাকতে পারে না 10 (36 ডিগ্রি) কেবল বাইনারি ভাসমান পয়েন্ট সহ।
ক্রিস জেস্টার-ইয়াং

12
@ কনেক্সেক্সও, "প্রতিটি বুদ্ধিমান" পিজ্জা ঠিক 36 ডিগ্রি ঘোরতে পারে না । মানুষ এত তাত্ক্ষণিকভাবে কিছু করতে খুব ত্রুটিযুক্ত।
ক্রিস জেস্টার-ইয়াং

212

ভাসমান পয়েন্ট রাউন্ডিং ত্রুটি। ৫. এর অনুপস্থিত মৌলিক গুণকের কারণে বেস -১ তে যেমন বেস -২ তে ০.১ যথাযথভাবে উপস্থাপিত হতে পারে না ঠিক যেমন ১/৩ দশমিক হিসাবে প্রতিনিধিত্ব করতে অসীম সংখ্যার গ্রহণ করে তবে বেস -৩-তে "০.০", ০.০ বেস -২ এ অসীম সংখ্যার সংখ্যা নেয় যেখানে এটি বেস -10 এ নয়। এবং কম্পিউটারগুলির অসীম পরিমাণে স্মৃতি থাকে না।


133
কম্পিউটারকে 0.1 + 0.2 = 0.3 ডান পাওয়ার জন্য অসীম পরিমাণের মেমরির প্রয়োজন নেই
পেসারিয়ার

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

15
@ পেসারিয়র: বাইনারি বা দশমিক ভাসমান-পয়েন্ট উভয়ই সঠিকভাবে 1/3 বা 1/13 সঞ্চয় করতে পারে না। দশমিক ভাসমান-পয়েন্টের ধরণগুলি এম / 10 ^ ই ফর্মের মানগুলি যথাযথভাবে উপস্থাপন করতে পারে, তবে অন্যান্য অন্যান্য ভগ্নাংশের প্রতিনিধিত্ব করার ক্ষেত্রে এটি একই আকারের বাইনারি ভাসমান-পয়েন্ট সংখ্যাগুলির তুলনায় কম সুনির্দিষ্ট । বেশ কয়েকটি অ্যাপ্লিকেশনগুলিতে কয়েকটি "বিশেষ" ব্যক্তির সাথে নিখুঁত নির্ভুলতা নির্ধারণের চেয়ে স্বেচ্ছাসেবী ভগ্নাংশের সাথে উচ্চতর নির্ভুলতা থাকা আরও কার্যকর।
সুপারক্যাট

13
@ পেসারিয়র তারা সংখ্যাটি বাইনারি ফ্লোট হিসাবে সংরক্ষণ করে রাখে তবে তারা উত্তরটি দেবে।
মার্ক আমেরিকা

3
@ চাক্স: বাইনারি এবং দশমিক প্রকারের মধ্যে নির্ভুলতার পার্থক্য বিশাল নয়, তবে দশমিক প্রকারের মধ্যে সবচেয়ে খারাপ-মামলার নির্ভুলতার ক্ষেত্রে 10: 1 পার্থক্য বাইনারি ধরণের সাথে 2: 1 পার্থক্যের চেয়ে অনেক বেশি। দশমিক ধরণের যে কোনও একটিতে দক্ষতার সাথে পরিচালনার জন্য কেউ হার্ডওয়্যার বা লিখিত সফ্টওয়্যার তৈরি করেছে কিনা তা সম্পর্কে আমি আগ্রহী, যেহেতু হার্ডওয়্যার বা সফ্টওয়্যারটিতে দক্ষ প্রয়োগের ক্ষেত্রে উভয়ই কার্যকর বলে মনে হয় না।
সুপারক্যাট

121

অন্যান্য সঠিক উত্তর ছাড়াও, আপনি ভাসমান-পয়েন্ট পাটিগণিত নিয়ে সমস্যা এড়াতে আপনার মানগুলি স্কেলিং বিবেচনা করতে পারেন।

উদাহরণ স্বরূপ:

var result = 1.0 + 2.0;     // result === 3.0 returns true

... পরিবর্তে:

var result = 0.1 + 0.2;     // result === 0.3 returns false

জাভাস্ক্রিপ্টে অভিব্যক্তিটি 0.1 + 0.2 === 0.3ফিরে আসে false, তবে ভাগ্যক্রমে ভাসমান-বিন্দুতে পূর্ণসংখ্যার গাণিতিকটি সঠিক, সুতরাং দশমিক উপস্থাপনের ত্রুটিগুলি স্কেলিং দ্বারা এড়ানো যায়।

ব্যবহারিক উদাহরণ হিসাবে, ভাসমান-পয়েন্ট সমস্যাগুলি এড়ানোর জন্য যেখানে নির্ভুলতা সর্বমোট হয়, ডলারের পরিবর্তে সেন্টের সংখ্যা: সেন্টের প্রতিনিধিত্ব করে একটি পূর্ণসংখ্যা হিসাবে অর্থ পরিচালনার জন্য 1 টি সুপারিশ করা হয় ।255025.50


1 ডগলাস ক্রকফোর্ড: জাভাস্ক্রিপ্ট: ভাল পার্টস : পরিশিষ্ট এ - ভয়ঙ্কর যন্ত্রাংশ (পৃষ্ঠা 105)


3
সমস্যাটি হ'ল রূপান্তরটি নিজেই ভুল। 16.08 * 100 = 1607.9999999999998। আমাদের কি সংখ্যাটি বিভক্ত করে আলাদাভাবে রূপান্তর করতে হবে (16 * 100 + 08 = 1608 হিসাবে)?
জেসন

38
এখানে সমাধানটি হ'ল আপনার সমস্ত গণনা পূর্ণসংখ্যায় করা তারপরে আপনার অনুপাত দ্বারা ভাগ করুন (এই ক্ষেত্রে 100) এবং কেবল তথ্য উপস্থাপন করার সময়ই গোল করুন round এটি নিশ্চিত করবে যে আপনার গণনা সর্বদা নির্ভুল থাকবে।
ডেভিড গ্রানাডো

15
শুধু কিছুটা নিটপিক করতে: পূর্ণসংখ্যার গাণিতিকটি কেবলমাত্র এক বিন্দু অবধি ভাসমান-পয়েন্টে সঠিক (পাং উদ্দেশ্যে) is যদি নম্বরটি 0x1p53 এর চেয়ে বড় হয় (জাভা 7 এর হেক্সাডেসিমাল ভাসমান পয়েন্ট নোটেশন ব্যবহার করতে, = 9007199254740992), তবে উলপটি সেই বিন্দুতে 2 হয় এবং 0x1p53 + 1 গোল করে 0x1p53 (এবং 0x1p53 + 3 গোলাকার হয় 0x1p53 + 4, কারণ রাউন্ড টু-ইওন)। :-D তবে অবশ্যই, যদি আপনার সংখ্যা 9 কোয়াড্রিলিয়ান এর চেয়ে কম হয়, আপনার ভাল হওয়া উচিত। :
ক্রিস জেস্টার-ইয়াং

2
জেসন, আপনি কেবল ফলাফল (গোল) (16.08 * 100 + 0.5) গোল করবেন
মিখাইল সেমেনভ

@CodyBugstein " সুতরাং কিভাবে আপনি .3 দেখানোর জন্য .1 + + .2 পেতে পারি? " স্বনির্ধারিত মুদ্রণ ফাংশন লিখতে দশমিক যেখানে আপনি এটি করতে চান স্থাপন করতে।
রনজাহান

113

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

প্রস্তাবনা

একটি আইইইই 754 ডাবল-স্পষ্টতা বাইনারি ফ্লোটিং-পয়েন্ট ফর্ম্যাট (বাইনারি 64) নম্বরটি ফর্মের একটি সংখ্যা উপস্থাপন করে

মান = (-1) * s * (1. মি 51 মি 50 ... মি 2 মি 1 মি 0 ) 2 * 2 ই -1023

64 বিট মধ্যে:

  • প্রথম বিটটি হ'ল সাইন বিট : 1যদি সংখ্যাটি নেতিবাচক হয়, 0অন্যথায় 1
  • পরের 11 বিটগুলি হ'ল এক্সপোনেন্ট , যা 1023 দ্বারা অফসেট হয় other অন্য কথায়, ডাবল-স্পষ্টতা নম্বর থেকে এক্সপোশন বিটগুলি পড়ার পরে, দুটি পাওয়ার পাওয়ার জন্য 1023 বিয়োগ করতে হবে।
  • বাকী ৫২ বিট হ'ল তাৎপর্যপূর্ণ (বা ম্যান্টিসা)। ম্যান্টিসায় কোনও 'বদ্ধমূল' 1.সর্বদা 2 বাদ দেওয়া হয় যেহেতু যে কোনও বাইনারি মানের সবচেয়ে উল্লেখযোগ্য বিট হয় 1

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

2 - এটি ডেনরমাল সংখ্যার ক্ষেত্রে নয় , যার শূন্যের অফসেট এক্সপোঞ্জেন (এবং একটি অন্তর্নিহিত 0.) রয়েছে। ডেনরমাল ডাবল যথার্থ সংখ্যার পরিসীমা ডি মিনিট ≤ | x | Max ডি সর্বাধিক , যেখানে ডি মিনিট (ক্ষুদ্রতম প্রতিনিধিত্বযোগ্য ননজারো সংখ্যা) 2 -1023 - 51 (≈ 4.94 * 10 -324 ) এবং ডি সর্বাধিক (বৃহত্তম সংখ্যাসূচক সংখ্যা, যার জন্য মান্টিস সম্পূর্ণরূপে 1গুলি) 2 -1023 + 1 - 2 -1023 - 51 (≈ 2.225 * 10 -308 )।


দ্বৈত নির্ভুল সংখ্যাটি বাইনারি রূপান্তর করা

দ্বৈত নির্ভুলতা ভাসমান পয়েন্ট সংখ্যাটিকে বাইনারি রূপান্তর করতে অনেক অনলাইন রূপান্তরকারীর উপস্থিতি রয়েছে (যেমন বাইনারি কনভার্ট ডট কম ), তবে ডাবল নির্ভুলতার সংখ্যার জন্য আইইইই 754 উপস্থাপনা পাওয়ার জন্য এখানে কিছু নমুনা সি # কোড দেওয়া হয়েছে (আমি তিনটি অংশ কলোন দিয়ে পৃথক করি :) :

public static string BinaryRepresentation(double value)
{
    long valueInLongType = BitConverter.DoubleToInt64Bits(value);
    string bits = Convert.ToString(valueInLongType, 2);
    string leadingZeros = new string('0', 64 - bits.Length);
    string binaryRepresentation = leadingZeros + bits;

    string sign = binaryRepresentation[0].ToString();
    string exponent = binaryRepresentation.Substring(1, 11);
    string mantissa = binaryRepresentation.Substring(12);

    return string.Format("{0}:{1}:{2}", sign, exponent, mantissa);
}

মূল বক্তব্য: পৌঁছনো

(টিএল; ডিআর সংস্করণের জন্য নীচে যান)

ক্যাটো জনস্টন (প্রশ্নকারী) জিজ্ঞাসা করলেন কেন 0.1 + 0.2! = 0.3।

বাইনারিতে লিখিত (তিনটি অংশ পৃথককারী কলোন সহ), আইইইইই 754 মানগুলির উপস্থাপনা হ'ল:

0.1 => 0:01111111011:1001100110011001100110011001100110011001100110011010
0.2 => 0:01111111100:1001100110011001100110011001100110011001100110011010

নোট করুন যে ম্যান্টিসাটি পুনরাবৃত্ত সংখ্যাগুলির সমন্বয়ে গঠিত 0011। গণনার ক্ষেত্রে কেন ত্রুটি রয়েছে তার মূল কারণ - 0.1, 0.2 এবং 0.3 বাইনারিগুলিতে সুনির্দিষ্টভাবে বাইনারি বিটের একটি নির্দিষ্ট সংখ্যায় 1/9, 1/3 বা 1/7 এর চেয়ে বেশি প্রতিনিধিত্ব করা যেতে পারে দশমিক সংখ্যা

এছাড়াও নোট করুন যে আমরা ঘনিষ্ঠতায় পাওয়ারটি 52 দ্বারা হ্রাস করতে পারি এবং বাইনারি উপস্থাপনার পয়েন্টটি 52 টি জায়গায় ডানদিকে স্থানান্তর করতে পারি (অনেকটা 10 -3 * 1.23 == 10 -5 * 123)। এটি তখন বাইনারি উপস্থাপনাকে সঠিক মান হিসাবে উপস্থাপন করতে সক্ষম করে যা এটি একটি * 2 পি আকারে প্রতিনিধিত্ব করে । যেখানে 'ক' একটি পূর্ণসংখ্যা।

এক্সটেনশনগুলিকে দশমিক রূপান্তর করা, অফসেটটি সরিয়ে, এবং উল্লিখিত 1(বর্গাকার বন্ধনীগুলিতে), 0.1 এবং 0.2 পুনরায় যুক্ত করা হয়:

0.1 => 2^-4 * [1].1001100110011001100110011001100110011001100110011010
0.2 => 2^-3 * [1].1001100110011001100110011001100110011001100110011010
or
0.1 => 2^-56 * 7205759403792794 = 0.1000000000000000055511151231257827021181583404541015625
0.2 => 2^-55 * 7205759403792794 = 0.200000000000000011102230246251565404236316680908203125

দুটি সংখ্যার যোগ করতে এক্সপোশনটি একই হওয়া দরকার, অর্থাত:

0.1 => 2^-3 *  0.1100110011001100110011001100110011001100110011001101(0)
0.2 => 2^-3 *  1.1001100110011001100110011001100110011001100110011010
sum =  2^-3 * 10.0110011001100110011001100110011001100110011001100111
or
0.1 => 2^-55 * 3602879701896397  = 0.1000000000000000055511151231257827021181583404541015625
0.2 => 2^-55 * 7205759403792794  = 0.200000000000000011102230246251565404236316680908203125
sum =  2^-55 * 10808639105689191 = 0.3000000000000000166533453693773481063544750213623046875

যেহেতু সমষ্টি ফর্ম 2 নয় এন * 1. {BBB} আমরা একের পর সূচক বৃদ্ধি এবং দশমিক (নামান বাইনারি ) পয়েন্ট পেতে হবে:

sum = 2^-2  * 1.0011001100110011001100110011001100110011001100110011(1)
    = 2^-54 * 5404319552844595.5 = 0.3000000000000000166533453693773481063544750213623046875

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

a = 2^-54 * 5404319552844595 = 0.299999999999999988897769753748434595763683319091796875
  = 2^-2  * 1.0011001100110011001100110011001100110011001100110011

x = 2^-2  * 1.0011001100110011001100110011001100110011001100110011(1)

b = 2^-2  * 1.0011001100110011001100110011001100110011001100110100
  = 2^-54 * 5404319552844596 = 0.3000000000000000444089209850062616169452667236328125

নোট করুন যে এবং শুধুমাত্র শেষ বিট মধ্যে পৃথক; ...0011+ 1= ...0100। এই ক্ষেত্রে শূন্যের সর্বনিম্ন উল্লেখযোগ্য বিটের মানটি , সুতরাং যোগফলটি হ'ল:

sum = 2^-2  * 1.0011001100110011001100110011001100110011001100110100
    = 2^-54 * 5404319552844596 = 0.3000000000000000444089209850062616169452667236328125

যদিও ০.০ এর বাইনারি উপস্থাপনাটি হ'ল:

0.3 => 2^-2  * 1.0011001100110011001100110011001100110011001100110011
    =  2^-54 * 5404319552844595 = 0.299999999999999988897769753748434595763683319091796875

যা শুধুমাত্র 2 দ্বারা 0.1 থেকে 0.2 এর সমষ্টি বাইনারি উপস্থাপনা থেকে পৃথক -54

০.১ এবং ০.২ এর বাইনারি উপস্থাপনা হ'ল আইইইই 754 দ্বারা অনুমোদিত নম্বরের সর্বাধিক নির্ভুল প্রতিনিধিত্ব।

টি এল; ডিআর

লেখা 0.1 + 0.2একটি আইইইই 754 বাইনারি প্রতিনিধিত্ব (তিনটি অংশ আলাদা কোলন সহ) এবং তুলনা 0.3(আমি বর্গাকার বন্ধনী মধ্যে স্বতন্ত্র বিট রেখেছি) এই হল:

0.1 + 0.2 => 0:01111111101:0011001100110011001100110011001100110011001100110[100]
0.3       => 0:01111111101:0011001100110011001100110011001100110011001100110[011]

দশমীতে ফিরে রূপান্তরিত, এই মানগুলি হ'ল:

0.1 + 0.2 => 0.300000000000000044408920985006...
0.3       => 0.299999999999999988897769753748...

পার্থক্যটি হুবহু 2 -54 , যা মূল মানগুলির সাথে তুলনা করলে তুচ্ছ (অনেক অ্যাপ্লিকেশনের জন্য) - 5.5511151231258 × 10 -17

ভাসমান পয়েন্ট সংখ্যার শেষ কয়েকটি বিটের তুলনা করা সহজাতভাবে বিপজ্জনক, কারণ বিখ্যাত " ফ্লোটিং-পয়েন্ট অ্যারিমেটিক সম্পর্কে প্রতিটি কম্পিউটার বিজ্ঞানী কি জানা উচিত " পড়েন তিনি জানেন (যা এই উত্তরের সমস্ত প্রধান অংশকে কভার করে) will

বেশিরভাগ ক্যালকুলেটররা এই সমস্যাটি পেতে অতিরিক্ত গার্ড ডিজিট ব্যবহার করেন , যা কীভাবে 0.1 + 0.2দেবে 0.3: চূড়ান্ত কয়েকটি বিটকে গোল করা হয়।


14
আমার উত্তরটি পোস্ট করার পরে খুব শীঘ্রই ভোট দেওয়া হয়েছিল। আমি তখন থেকে অনেক পরিবর্তন করেছি (বাইনারিতে ০.১ এবং ০.২ লিখার সময় পুনরাবৃত্ত বিটগুলি স্পষ্টভাবে উল্লেখ করা সহ যা আমি আসলটিতে বাদ দিয়েছি)। নিচে ভোটাররা যে সুযোগটি দেখেছে, আপনি কি দয়া করে আমাকে কিছু প্রতিক্রিয়া জানাতে পারেন যাতে আমি আমার উত্তরটি উন্নত করতে পারি? আমি অনুভব করি যে আমার উত্তর আইইইই 754 এর যোগফলের চিকিত্সা অন্যান্য উত্তরগুলিতে একইভাবে আচ্ছাদিত নয় বলে কিছু নতুন যুক্ত করেছে। "প্রতিটি কম্পিউটার বিজ্ঞানীর কী জানা উচিত ..." তেমন কিছু উপাদান অন্তর্ভুক্ত থাকা অবস্থায়, আমার উত্তরটি বিশেষত ০.০ + ০.২ এর ক্ষেত্রে সম্পর্কিত।
ওয়াই হা লি

57

কম্পিউটারে সঞ্চিত ফ্লোটিং পয়েন্ট সংখ্যা দুটি অংশ, একটি পূর্ণসংখ্যা এবং একটি ঘনিষ্ঠ সমন্বয়ে গঠিত হয় যা বেসকে নেওয়া হয় এবং পূর্ণসংখ্যার অংশ দ্বারা গুণিত হয়।

কম্পিউটার যদি বেস 10 এ কাজ করছিল, 0.1হবে 1 x 10⁻¹, 0.2হবে 2 x 10⁻¹এবং 0.3হবে 3 x 10⁻¹। পূর্ণসংখ্যার গণিত সহজ এবং নির্ভুল, সুতরাং যোগ 0.1 + 0.2করলে স্পষ্টতই ফলাফল আসবে 0.3

কম্পিউটার সাধারণত বেস 10 কাজ করে না, তারা বেস 2. কাজ আপনি এখনও কিছু মান জন্য সঠিক ফলাফল পেতে পারেন, উদাহরণস্বরূপ 0.5হয় 1 x 2⁻¹এবং 0.25হয় 1 x 2⁻², এবং তাদের যুক্ত করতে ফলাফল 3 x 2⁻², বা 0.75। যথাযথভাবে।

সমস্যাটি এমন সংখ্যাগুলির সাথে আসে যা 10 টি বেসে হুবহু উপস্থাপন করা যেতে পারে তবে 2 বেসে নয় Those এই সংখ্যাগুলি তাদের নিকটতম সমতুল্যকে গোল করতে হবে। খুব সাধারণ আইইইই 64-বিট ফ্লোটিং পয়েন্ট ফরম্যাট, নিকটস্থ সংখ্যা ধরে নেওয়া যাক 0.1হয় 3602879701896397 x 2⁻⁵⁵, এবং নিকটস্থ সংখ্যা 0.2হয় 7205759403792794 x 2⁻⁵⁵; এগুলি একসাথে যুক্ত করলে ফলাফল 10808639105689191 x 2⁻⁵⁵, বা এর দশমিক মান 0.3000000000000000444089209850062616169452667236328125। ফ্লোটিং পয়েন্ট নম্বরগুলি সাধারণত প্রদর্শনের জন্য গোল হয়।


2
@ মার্ক এই পরিষ্কার ব্যাখ্যার জন্য আপনাকে ধন্যবাদ তবে তারপরে প্রশ্ন ওঠে যে কেন 0.1 + 0.4 ঠিক 0.5 পর্যন্ত যুক্ত হয় (পাইথন 3 এ ন্যূনতম)? এছাড়াও পাইথন 3 এ ফ্লোটগুলি ব্যবহার করার সময় সমতা যাচাই করার সর্বোত্তম উপায় কী?
pchegoor

2
@ ব্যবহারকারী 2417881 আইইইই ভাসমান পয়েন্ট অপারেশনগুলির প্রতিটি ক্রিয়াকলাপের জন্য রাউন্ডিং বিধি রয়েছে এবং কখনও কখনও দুটি সংখ্যা কিছুটা হলেও বন্ধ হয়ে গেলেও রাউন্ডিং একটি সঠিক উত্তর দিতে পারে। বিশদটি কোনও মন্তব্যের জন্য খুব দীর্ঘ এবং আমি যাইহোক সেগুলির মধ্যে কোনও বিশেষজ্ঞ নই। যেমন আপনি এই উত্তরে দেখছেন ০.০ হ'ল কয়েক দশমিক একের মধ্যে বাইনারি হিসাবে প্রতিনিধিত্ব করা যেতে পারে তবে এটি কেবল একটি কাকতালীয় ঘটনা। সমতা পরীক্ষার জন্য দেখুন স্ট্যাকওভারফ্লো . com/ প্রশ্নগুলি / 5595425/…
মার্ক রান্সম

1
@ ব্যবহারকারী 2417881 আপনার প্রশ্নটি আমাকে উত্সাহিত করেছিল তাই আমি এটিকে একটি পূর্ণ প্রশ্ন এবং উত্তরে রূপান্তরিত করেছি: stackoverflow.com/q/48374522/5987
মার্ক র্যানসোম

47

ভাসমান পয়েন্ট রাউন্ডিং ত্রুটি। প্রতিটি কম্পিউটার বিজ্ঞানী ভাসমান-পয়েন্ট পাটিগণিত সম্পর্কে যা জানা উচিত তা থেকে :

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


33

আমার কার্যনির্বাহী:

function add(a, b, precision) {
    var x = Math.pow(10, precision || 2);
    return (Math.round(a * x) + Math.round(b * x)) / x;
}

নির্ভুলতা সংখ্যার পরে দশমিক পয়েন্টের পরে আপনি যে সংখ্যাগুলি সংরক্ষণ করতে চান তা বোঝায়।


30

প্রচুর ভাল উত্তর পোস্ট করা হয়েছে তবে আমি আরও একটি যুক্ত করতে চাই।

নেই সব নম্বরগুলির মাধ্যমে প্রতিনিধিত্ব করা যাবে ভাসে / ডাবলস উদাহরণস্বরূপ, সংখ্যা "0.2" IEEE754 ভাসা বিন্দু মান একক স্পষ্টতা হিসেবে "0,200000003" প্রতিনিধিত্ব করা হবে না।

হুডের নীচে স্টোর আসল সংখ্যার মডেল হিসাবে ভাসমান সংখ্যা উপস্থাপন করে

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

যদিও আপনি 0.2সহজে টাইপ করতে পারেন, FLT_RADIXএবং DBL_RADIXএটি 2 হয়; এফপিইউ সহ এমন একটি কম্পিউটারের জন্য 10 নয় যা "বাইনারি ফ্লোটিং-পয়েন্ট এরিমেটিক (আইএসও / আইইইই স্ট্যান্ড 754-1985) জন্য আইইইই স্ট্যান্ডার্ড ব্যবহার করে"।

সুতরাং এই জাতীয় সংখ্যার সঠিকভাবে উপস্থাপন করা কিছুটা কঠিন is এমনকি যদি আপনি কোনও মধ্যবর্তী গণনা ছাড়াই এই পরিবর্তনশীলটি স্পষ্টভাবে নির্দিষ্ট করে থাকেন।


28

এই বিখ্যাত দ্বৈত নির্ভুলতা প্রশ্নের সাথে সম্পর্কিত কিছু পরিসংখ্যান।

0.1 এর একটি ধাপ (0.1 থেকে 100 পর্যন্ত) ব্যবহার করে সমস্ত মান ( a + b ) যুক্ত করার সময় আমাদের কাছে নির্ভুল ত্রুটির 15 ডলার সম্ভাবনা রয়েছে । নোট করুন যে ত্রুটির ফলে কিছুটা বড় বা ছোট মান হতে পারে। এখানে কিছু উদাহরন:

0.1 + 0.2 = 0.30000000000000004 (BIGGER)
0.1 + 0.7 = 0.7999999999999999 (SMALLER)
...
1.7 + 1.9 = 3.5999999999999996 (SMALLER)
1.7 + 2.2 = 3.9000000000000004 (BIGGER)
...
3.2 + 3.6 = 6.800000000000001 (BIGGER)
3.2 + 4.4 = 7.6000000000000005 (BIGGER)

সমস্ত মানকে বিয়োগ করার সময় ( a - b যেখানে a> খ ) 0.1 এর একটি ধাপ ব্যবহার করে (100 থেকে 0.1 পর্যন্ত) আমাদের নির্ভুলতা ত্রুটির 34% সম্ভাবনা রয়েছে । এখানে কিছু উদাহরন:

0.6 - 0.2 = 0.39999999999999997 (SMALLER)
0.5 - 0.4 = 0.09999999999999998 (SMALLER)
...
2.1 - 0.2 = 1.9000000000000001 (BIGGER)
2.0 - 1.9 = 0.10000000000000009 (BIGGER)
...
100 - 99.9 = 0.09999999999999432 (SMALLER)
100 - 99.8 = 0.20000000000000284 (BIGGER)

* 15% এবং 34% প্রকৃতপক্ষে বিশাল, তাই যথার্থতা যখন গুরুত্বপূর্ণ হয় তখন সর্বদা বিগডিসিমাল ব্যবহার করুন। 2 দশমিক সংখ্যা (0.01 ধাপ) এর সাহায্যে পরিস্থিতি কিছুটা আরও খারাপ হয় (18% এবং 36%)।


28

না, ভাঙ্গা নয়, তবে বেশিরভাগ দশমিক ভগ্নাংশগুলি অবশ্যই প্রায় অনুমান করা উচিত

সারসংক্ষেপ

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

এমনকি 0.01, 0.02, 0.03, 0.04 ... 0.24 এর মতো সাধারণ সংখ্যা বাইনারি ভগ্নাংশের মতো ঠিক উপস্থাপনযোগ্য নয়। আপনি যদি 0.01, .02, .03 ... গণনা করেন তবে 0.25 না হওয়া পর্যন্ত আপনি বেস 2 তে প্রথম ভগ্নাংশ উপস্থাপনযোগ্য পাবেন । যদি আপনি চেষ্টা করে থাকেন যে এফপি ব্যবহার করে, আপনার 0.01 কিছুটা বন্ধ হয়ে গেছে, সুতরাং তাদের 25 টিকে একটি দুর্দান্ত সঠিক 0.25 পর্যন্ত যুক্ত করার একমাত্র উপায়টির জন্য গার্ড বিটস এবং রাউন্ডিং জড়িত কার্যকারিতার দীর্ঘ শৃঙ্খলার প্রয়োজন হত। এটি পূর্বাভাস দেওয়া খুব শক্ত তাই আমরা হাত বাড়িয়ে বলি "এফপি নিখরচায়", তবে এটি সত্য নয়।

আমরা ক্রমাগত এফপি হার্ডওয়্যার এমন কিছু দিয়ে থাকি যা বেস 10 এ সহজ বলে মনে হয় তবে এটি বেস 2 এর পুনরাবৃত্তি ভগ্নাংশ।

এটা কিভাবে হল?

যখন আমরা দশমিকভাবে লিখি, প্রতিটি ভগ্নাংশ (বিশেষত, প্রতিটি সমাপ্তি দশমিক) ফর্মের যুক্তিযুক্ত সংখ্যা

           এ / (২ এন x 5 মি )

বাইনারি-তে, আমরা কেবল 2 এন পদ পাই , তা হ'ল:

           ক / 2 এন

সুতরাং দশমিক, আমরা উপস্থাপন করতে পারবেন না 1 / 3 । কারণ বেস 10 একটি মৌলিক ফ্যাক্টর হিসেবে 2 অন্তর্ভুক্ত, যে সংখ্যা আমরা একটি বাইনারি ভগ্নাংশ হিসাবে লিখতে পারেন এছাড়াও একটি বেস 10 ভগ্নাংশ হিসাবে লেখা যেতে পারে। তবে, বেস 10 ভগ্নাংশ হিসাবে আমরা খুব কমই লিখি বাইনারি হিসাবে উপস্থাপনযোগ্য। ০.০১, ০.০২, ০.০৩ ... ০.৯৯ থেকে মাত্র তিনটি সংখ্যাকেই আমাদের এফপি ফর্ম্যাটে প্রতিনিধিত্ব করা যেতে পারে: 0.25, 0.50 এবং 0.75, কারণ এগুলি সমস্ত সংখ্যা 1/4, 1/2, এবং 3/4, সমস্ত সংখ্যা শুধুমাত্র 2 এন পদ ব্যবহার করে একটি মৌলিক ফ্যাক্টর সহ ।

বেস 10 আমরা উপস্থাপন করতে পারবেন না 1 / 3 । কিন্তু বাইনারি, আমরা করতে পারবো না 1 / 10 বা 1 / 3

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

এটির সাথে ডিল করছে

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

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

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

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

উপসংহার

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


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

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

আমি একমত নই, ফ্লোটগুলি দশমিক হিসাবে সংরক্ষণ করা উচিত বাইনারি নয় এবং সমস্ত সমস্যার সমাধান করা উচিত।
রোনেন ফেস্টিংগার

" X / (2 ^ n + 5 ^ n) " " x / (2 ^ n * 5 ^ n) " হওয়া উচিত নয়?
ওয়াই হা লি

@ রোনেনফেস্টিংগার - প্রায় ১/৩?
স্টিফেন সি

19

আপনি কি নালী টেপ সমাধান চেষ্টা করে?

ত্রুটিগুলি কখন সংঘটিত হয় তা নির্ধারণ করার চেষ্টা করুন এবং বিবৃতিগুলি সংক্ষেপে সংশোধন করুন, এটি সুন্দর নয় তবে কিছু সমস্যার জন্য এটিই একমাত্র সমাধান এবং এটি তাদের মধ্যে একটি।

 if( (n * 0.1) < 100.0 ) { return n * 0.1 - 0.000000000000001 ;}
                    else { return n * 0.1 + 0.000000000000001 ;}    

সি # তে একটি বৈজ্ঞানিক সিমুলেশন প্রকল্পে আমার একই সমস্যা ছিল এবং আমি আপনাকে বলতে পারি যে আপনি যদি প্রজাপতির প্রভাব উপেক্ষা করেন তবে এটি একটি বড় ফ্যাট ড্রাগনে পরিণত হবে এবং আপনাকে ** তে কামড় দেবে


19

অর্ডার দিতে সালে সবচেয়ে ভালো সমাধান আমি বলতে পারি আমি পদ্ধতি নিম্নলিখিত আবিষ্কৃত:

parseFloat((0.1 + 0.2).toFixed(10)) => Will return 0.3

কেন এটি সেরা সমাধান তা আমাকে ব্যাখ্যা করুন। উপরের উত্তরে যেমন অন্যরা উল্লিখিত হয়েছে, সমস্যা সমাধানের জন্য জাভাস্ক্রিপ্ট থেকে ফিক্সড () ফাংশনটি ব্যবহারের জন্য প্রস্তুত ব্যবহার করা ভাল ধারণা। তবে সম্ভবত আপনি কিছু সমস্যার মুখোমুখি হবেন।

কল্পনা করুন আপনি দুটি ভাসমান সংখ্যা যুক্ত করতে যাচ্ছেন 0.2এবং 0.7এটি এখানে:0.2 + 0.7 = 0.8999999999999999

আপনার প্রত্যাশিত ফলাফলটির 0.9অর্থ হ'ল এই ক্ষেত্রে আপনার 1 ডিজিট যথার্থতার সাথে ফলাফল দরকার। সুতরাং আপনার ব্যবহার করা উচিত ছিল (0.2 + 0.7).tofixed(1) তবে আপনি ফিক্সড () কে কেবল একটি নির্দিষ্ট পরামিতি দিতে পারবেন না কারণ এটি প্রদত্ত সংখ্যার উপর নির্ভর করে, উদাহরণস্বরূপ

`0.22 + 0.7 = 0.9199999999999999`

এই উদাহরণে আপনার 2 ডিজিটের যথার্থতা প্রয়োজন তাই এটি হওয়া উচিত toFixed(2), তাই প্রতিটি প্রদত্ত ফ্লোট সংখ্যাটি ফিট করার জন্য পরামিতিটি কী হওয়া উচিত?

আপনি বলতে পারেন যে এটি প্রতিটি পরিস্থিতিতে এটি 10 ​​হতে দিন:

(0.2 + 0.7).toFixed(10) => Result will be "0.9000000000"

অভিশাপ! 9 এর পরে আপনি সেই অযাচিত জিরোগুলি কী করতে যাচ্ছেন? আপনার ইচ্ছামতো তৈরি করার জন্য এটি এটিকে ফ্লোটে রূপান্তর করার সময়:

parseFloat((0.2 + 0.7).toFixed(10)) => Result will be 0.9

এখন আপনি যে সমাধানটি পেয়েছেন, এটি এটির মতো কার্যকারিতা হিসাবে দেওয়া ভাল:

function floatify(number){
           return parseFloat((number).toFixed(10));
        }

আসুন এটি চেষ্টা করুন:

function floatify(number){
       return parseFloat((number).toFixed(10));
    }
 
function addUp(){
  var number1 = +$("#number1").val();
  var number2 = +$("#number2").val();
  var unexpectedResult = number1 + number2;
  var expectedResult = floatify(number1 + number2);
  $("#unexpectedResult").text(unexpectedResult);
  $("#expectedResult").text(expectedResult);
}
addUp();
input{
  width: 50px;
}
#expectedResult{
color: green;
}
#unexpectedResult{
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="number1" value="0.2" onclick="addUp()" onkeyup="addUp()"/> +
<input id="number2" value="0.7" onclick="addUp()" onkeyup="addUp()"/> =
<p>Expected Result: <span id="expectedResult"></span></p>
<p>Unexpected Result: <span id="unexpectedResult"></span></p>

আপনি এটি এইভাবে ব্যবহার করতে পারেন:

var x = 0.2 + 0.7;
floatify(x);  => Result: 0.9

হিসাবে W3Schools প্রস্তাব দেওয়া আরেকটা সমাধান খুব হয়, তাহলে আপনি গুন করতে পারেন এবং ডিভাইড উপরে সমস্যা সমাধানের জন্য:

var x = (0.2 * 10 + 0.1 * 10) / 10;       // x will be 0.3

মনে (0.2 + 0.1) * 10 / 10হবেন যে এগুলি একই মনে হলেও এগুলি কার্যকর হবে না! আমি প্রথম সমাধানটি পছন্দ করি যেহেতু আমি এটিকে একটি ফাংশন হিসাবে প্রয়োগ করতে পারি যা ইনপুট ফ্লোটকে সঠিক আউটপুট ফ্লোটে রূপান্তর করে।


এটি আমার সত্যিকারের মাথাব্যথা করেছিল। আমি 12 টি ফ্লোট সংখ্যা যোগ করি, তারপরে যোগগুলি এবং সেই সংখ্যাগুলি যদি গড় দেখায়। ফিক্সড () ব্যবহার করে 2 সংখ্যার যোগফল সংশোধন করতে পারে তবে বেশ কয়েকটি সংখ্যার যোগ করলে লিপ তাৎপর্যপূর্ণ হয়।
নুর্য্যাগি মুস্তাপয়েভ

@ নুর্যগিডি মুস্তাপয়েভ আমি আপনার উদ্দেশ্যটি পাইনি, যেমন আপনি 12 টি ভাসমান সংখ্যার যোগফল দেওয়ার আগে পরীক্ষা করেছিলাম, তারপরে ফলাফলটিতে ফ্লোটিফাই () ফাংশনটি ব্যবহার করুন, তারপরে আপনি যা চান তা করুন, আমি এটি ব্যবহার করে কোন সমস্যা লক্ষ্য করেছি।
মোহাম্মদ মুসাভি

আমি কেবল আমার পরিস্থিতিতে বলছি যেখানে আমার প্রায় 20 টি পরামিতি এবং 20 টি সূত্র রয়েছে যেখানে প্রতিটি সূত্রের ফলাফল অন্যের উপর নির্ভর করে এই সমাধানটি সহায়তা করে নি।
নুর্যাদি মুস্তাপায়েভ

16

কম্পিউটারগুলি গণনার উদ্দেশ্যে বাইনারি (বেস 2) নম্বর সিস্টেম ব্যবহার করে কারণ আমরা দশমিক (বেস 10) ব্যবহার করি কারণ এই অদ্ভুত সংখ্যাগুলি উপস্থিত হয়।

সংখ্যাগরিষ্ঠ সংখ্যাগরিষ্ঠ রয়েছে যা বাইনারি বা দশমিক বা উভয় ক্ষেত্রেই যথাযথভাবে উপস্থাপন করা যায় না। ফলাফল - একটি বৃত্তাকার আপ (তবে সুনির্দিষ্ট) সংখ্যার ফলাফল।


আমি আপনার দ্বিতীয় অনুচ্ছেদটি মোটেই বুঝতে পারি না।
Nae

1
@ না আমি দ্বিতীয় অনুচ্ছেদে অনুবাদ করব "" ভগ্নাংশের সিংহভাগ দশমিক বা বাইনারি উভয়ই হুবহু উপস্থাপন করা যায় না । সুতরাং বেশিরভাগ ফলাফলকে গোল করা হবে - যদিও তারা উপস্থাপনের অন্তর্নিহিত বিট / অঙ্কের সংখ্যার জন্য যথাযথ হবে ব্যবহৃত."
স্টিভ সামিট

15

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

যেহেতু এটি একটি ভাষা-অজ্ঞাত প্রশ্ন, তাই এর জন্য ভাষা-অজ্ঞাস্তিক সরঞ্জামগুলির দরকার যেমন ডেসিমাল থেকে ফ্লোটিং-পয়েন্ট রূপান্তরকারী

দ্বিগুণ হিসাবে বিবেচিত, প্রশ্নের নম্বরগুলিতে এটি প্রয়োগ করা:

0.1 রূপান্তর 0.1000000000000000055511151231257827021181583404541015625,

0.2 0.200000000000000000011102230246251565404236316680908203125 এ রূপান্তর করে,

০.০ রূপান্তরিত হয় 0.299999999999999988897769753748434595763683319091796875, এবং

0.3000000000000000004 0.3000000000000000444089209850062616169452667236328125 এ রূপান্তর করে।

প্রথম দুটি সংখ্যা ম্যানুয়ালি বা দশমিক ক্যালকুলেটর যেমন সম্পূর্ণ যথার্থ ক্যালকুলেটরে যুক্ত করা প্রকৃত ইনপুটগুলির সঠিক যোগফল 0.3000000000000000166533453693773481063544750213623046875 দেখায়।

এটি যদি 0.3 এর সমতুল্য হয়ে থাকে তবে রাউন্ডিং ত্রুটিটি 0.0000000000000000277555756156289135105907917022705078125 হবে। 0.3000000000000000004 এর সমতুল্যকে গোল করা এছাড়াও রাউন্ডিং ত্রুটি 0.000000000000000000277555756156289135105907917022705078125 দেয়। রাউন্ড টু-ইন্-টাই টাই ব্রেকার প্রযোজ্য।

ভাসমান বিন্দু রূপান্তরকারীটিতে ফিরে, 0.3000000000000000004 এর কাঁচা হেক্সাডেসিমাল 3fd333333333333334, যা একটি এমনকি সংখ্যায় শেষ হয় এবং তাই সঠিক ফলাফল।


2
যার সম্পাদনায় আমি সবেমাত্র ঘুরিয়েছি: কোড কোডের কোডের জন্য আমি কোড কোটকে উপযুক্ত বলে বিবেচনা করি। এই উত্তরটি ভাষা-নিরপেক্ষ হওয়ায় কোনও উদ্ধৃত কোড মোটেই নেই। নম্বরগুলি ইংরেজী বাক্যে ব্যবহৃত হতে পারে এবং এটি তাদের কোডে রূপান্তরিত করে না।
প্যাট্রিসিয়া শানাহান

এই কারণেই কেউ আপনার নম্বরগুলিকে কোড হিসাবে ফর্ম্যাট করেছে - ফর্ম্যাটের জন্য নয়, তবে পঠনযোগ্যতার জন্য।
ওয়াই হা লি

... এছাড়াও, এমনকি বৃত্তাকার বোঝায় বাইনারি উপস্থাপনা, না দশমিক উপস্থাপনা। দেখুন এই উদাহরণস্বরূপ বা, এই
ওয়াই হা লি

@ ওয়াইএইলি আমি কোনও দশমিক সংখ্যায় বিজোড় / এমনকি পরীক্ষার প্রয়োগ করিনি, কেবলমাত্র হেক্সাডেসিমাল। একটি হেক্সাডেসিমাল ডিজিট এমনকি যদি হয় এবং কেবলমাত্র তার বাইনারি প্রসারণের সর্বনিম্ন উল্লেখযোগ্য বিট শূন্য হয়।
প্যাট্রিসিয়া শানাহান

14

দেওয়া হয়েছে যে কেউ এটি উল্লেখ করেছে ...

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

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

    অর্থের সাথে লেনদেন করার সময় দশমিকগুলি খুব সুন্দর: দশ সেন্ট প্লাস বিশ সেন্ট সবসময় হ'ল ত্রিশ সেন্ট:

    >>> 0.1 + 0.2 == 0.3
    False
    >>> Decimal('0.1') + Decimal('0.2') == Decimal('0.3')
    True
    

    পাইথনের decimalমডিউল আইইইই স্ট্যান্ডার্ড 854-1987 এর উপর ভিত্তি করে ।

  • পাইথনের fractionsমডিউল এবং অ্যাপাচি সাধারণের BigFractionক্লাস । উভয়ই যুক্ত হিসাবে যুক্তিযুক্ত সংখ্যা উপস্থাপন করে (numerator, denominator)এবং তারা দশমিক ভাসমান পয়েন্ট গণিতের চেয়ে আরও সঠিক ফলাফল দিতে পারে।

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


14

আমি কি যুক্ত করতে পারি; লোকেদের সর্বদা এটি একটি কম্পিউটার সমস্যা হিসাবে ধরে নিয়েছে, তবে আপনি যদি নিজের হাতে (বেস 10) গণনা করেন (1/3+1/3=2/3)=trueতবে আপনার কাছে 0.333 ... 0.3.3 যোগ করার মতো অসীমতা না থাকলে আপনি পাবেন না ... ঠিক তেমনি (1/10+2/10)!==3/10বেসের সমস্যার সাথেও 2, আপনি এটি 0.333 + 0.333 = 0.666 এ ছাঁটাই করেছেন এবং সম্ভবত এটি 0.667 এ গোল করবেন যা প্রযুক্তিগতভাবেও ভুল হবে।

ত্রৈমাসিক হিসাবে গণনা করুন, এবং তৃতীয়াংশ কোনও সমস্যা নয় যদিও - সম্ভবত প্রতিটি হাতে 15 টি আঙ্গুল দিয়ে কিছু রেস জিজ্ঞাসা করবে কেন আপনার দশমিক গণিতটি ভেঙে গেছে ...


মানুষ যেহেতু দশমিক সংখ্যা ব্যবহার করে, তাই ভাসমানগুলি ডিফল্ট হিসাবে দশমিক হিসাবে প্রতিনিধিত্ব না করার কোনও সঠিক কারণ আমি দেখতে পাই না সুতরাং আমাদের সঠিক ফলাফল রয়েছে।
রোনেন ফেস্টিংগার

মানুষ বেস 10 (দশমিক) ব্যতীত অনেকগুলি ঘাঁটি ব্যবহার করে, বাইনারি হ'ল আমরা

@ রোনেনফেস্টিংগার বাইনারি পাটিগণিত কম্পিউটারে প্রয়োগ করা সহজ কারণ এটির জন্য সংখ্যা সহ কেবলমাত্র আটটি বেসিক অপারেশন প্রয়োজন: বলুন $ a $, $ b $ in $ 0,1 you আপনার যা জানা দরকার তা হ'ল \ rat অপেরাটর্নাম {এক্সওর} (ক, বি) $ এবং $ \ অপেরাটর্নাম {সিবি} (ক, বি) $, যেখানে এক্সর এক্সক্লুসিভ বা সিবি হ'ল "ক্যারি বিট" যা cases a = 1 = বি except ব্যতীত সকল ক্ষেত্রে $ 0 $ হয়, যার ক্ষেত্রে আমাদের রয়েছে একটি (প্রকৃতপক্ষে সমস্ত ক্রিয়াকলাপের চলাচল আপনাকে $ 2 sa কেস সাশ্রয় করে এবং আপনার যা প্রয়োজন তা হল $ 6 $ নিয়ম)। দশমিক প্রসারণের জন্য 10 \ বার 11 $ (দশমিক স্বীকৃতিতে) কেস সংরক্ষণ করতে হয় এবং প্রতি বিটের জন্য 10 দশমিক $ আলাদা রাজ্য এবং বহনযোগ্য স্টোরেজ নষ্ট করে।
ওসকার লিমকা

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

9

ডিজিটাল কম্পিউটারে যে ধরণের ভাসমান-পয়েন্ট গণিত করা যেতে পারে তা অগত্যা তাদের বাস্তব সংখ্যাগুলির সংলগ্নতা এবং তাদের উপর ক্রিয়াকলাপ ব্যবহার করে। ( স্ট্যান্ডার্ড সংস্করণটি পঞ্চাশ পৃষ্ঠার ডকুমেন্টেশনের দিকে চলে এবং এরটি এবং আরও পরিমার্জনকে মোকাবেলায় একটি কমিটি রয়েছে has)

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

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

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


9

কেবল মজাদার জন্য, আমি স্ট্যান্ডার্ড সি 99 এর সংজ্ঞাগুলি অনুসরণ করে ভাসমানদের প্রতিনিধিত্ব করে খেললাম এবং আমি নীচের কোডটি লিখেছি।

কোডটি 3 টি পৃথক গ্রুপে ভাসমানদের বাইনারি উপস্থাপনা মুদ্রণ করে

SIGN EXPONENT FRACTION

এবং তারপরে এটি একটি যোগফল মুদ্রণ করে, এটি পর্যাপ্ত নির্ভুলতার সাথে যোগ করা হলে, হার্ডওয়্যারে প্রকৃত উপস্থিতিটির মানটি প্রদর্শিত হবে।

সুতরাং আপনি যখন লিখবেন float x = 999..., সংকলকটি ফাংশন দ্বারা মুদ্রিত কিছু উপস্থাপনায় number সংখ্যাটিকে রূপান্তর করবে xxযেমন ফাংশন দ্বারা মুদ্রিত সমষ্টিyy প্রদত্ত সংখ্যার সমান হয়।

বাস্তবে, এই যোগফলটি কেবল একটি আনুমানিক। 999,999,999 সংখ্যার জন্য সংকলকটি 1000,000,000 সংখ্যাটির সামান্য প্রতিনিধিত্ব করে সন্নিবেশ করবে

কোডের পরে আমি একটি কনসোল সেশন সংযুক্ত করি, যেখানে আমি উভয় ধ্রুবক (বিয়োগ পিআই এবং 999999999) এর শর্তগুলির যোগফল গণনা করি যা হার্ডওয়্যারে সত্যই বিদ্যমান, সংকলক দ্বারা সেখানে sertedোকানো হয়েছিল।

#include <stdio.h>
#include <limits.h>

void
xx(float *x)
{
    unsigned char i = sizeof(*x)*CHAR_BIT-1;
    do {
        switch (i) {
        case 31:
             printf("sign:");
             break;
        case 30:
             printf("exponent:");
             break;
        case 23:
             printf("fraction:");
             break;

        }
        char b=(*(unsigned long long*)x&((unsigned long long)1<<i))!=0;
        printf("%d ", b);
    } while (i--);
    printf("\n");
}

void
yy(float a)
{
    int sign=!(*(unsigned long long*)&a&((unsigned long long)1<<31));
    int fraction = ((1<<23)-1)&(*(int*)&a);
    int exponent = (255&((*(int*)&a)>>23))-127;

    printf(sign?"positive" " ( 1+":"negative" " ( 1+");
    unsigned int i = 1<<22;
    unsigned int j = 1;
    do {
        char b=(fraction&i)!=0;
        b&&(printf("1/(%d) %c", 1<<j, (fraction&(i-1))?'+':')' ), 0);
    } while (j++, i>>=1);

    printf("*2^%d", exponent);
    printf("\n");
}

void
main()
{
    float x=-3.14;
    float y=999999999;
    printf("%lu\n", sizeof(x));
    xx(&x);
    xx(&y);
    yy(x);
    yy(y);
}

এখানে একটি কনসোল সেশন রয়েছে যাতে আমি হার্ডওয়্যারটিতে বিদ্যমান ভাসমানের আসল মানটি গণনা করি। আমি bcমূল প্রোগ্রাম দ্বারা আউটপুট পদগুলির যোগফল মুদ্রণ করতে ব্যবহৃত । যে পাইটি পাইথন replবা অনুরূপ কিছু সন্নিবেশ করতে পারে।

-- .../terra1/stub
@ qemacs f.c
-- .../terra1/stub
@ gcc f.c
-- .../terra1/stub
@ ./a.out
sign:1 exponent:1 0 0 0 0 0 0 fraction:0 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 1 0 0 0 0 1 1
sign:0 exponent:1 0 0 1 1 1 0 fraction:0 1 1 0 1 1 1 0 0 1 1 0 1 0 1 1 0 0 1 0 1 0 0 0
negative ( 1+1/(2) +1/(16) +1/(256) +1/(512) +1/(1024) +1/(2048) +1/(8192) +1/(32768) +1/(65536) +1/(131072) +1/(4194304) +1/(8388608) )*2^1
positive ( 1+1/(2) +1/(4) +1/(16) +1/(32) +1/(64) +1/(512) +1/(1024) +1/(4096) +1/(16384) +1/(32768) +1/(262144) +1/(1048576) )*2^29
-- .../terra1/stub
@ bc
scale=15
( 1+1/(2) +1/(4) +1/(16) +1/(32) +1/(64) +1/(512) +1/(1024) +1/(4096) +1/(16384) +1/(32768) +1/(262144) +1/(1048576) )*2^29
999999999.999999446351872

এটাই. 999999999 এর মানটি আসলে

999999999.999999446351872

আপনি bcযেটি পরীক্ষা করতে পারেন -3.14 এছাড়াও বিচলিত হয়। একটি scaleফ্যাক্টর সেট করতে ভুলবেন না bc

প্রদর্শিত যোগফলটি হার্ডওয়্যারের অভ্যন্তরে। এটি গণনা করে আপনি যে মূল্য অর্জন করেন তা আপনার সেট করা স্কেলের উপর নির্ভর করে। আমি scaleফ্যাক্টরটিকে 15 এ সেট করেছিলাম M


5

এটি দেখার আরও একটি উপায়: সংখ্যার প্রতিনিধিত্ব করতে 64 বিট ব্যবহৃত হয়। ফলস্বরূপ 2 ** ,৪ = 18,446,744,073,709,551,616 এর চেয়ে বেশি উপায় নেই different বিভিন্ন সংখ্যা যথাযথভাবে উপস্থাপিত হতে পারে।

যাইহোক, ম্যাথ বলছে যে 0 এবং 1 এর মধ্যে ইতিমধ্যে অসীম অনেকগুলি দশমিক রয়েছে are আইইই 754 এই 64 বিটগুলি আরও বেশি সংখ্যক স্থান প্লাস NaN এবং +/- অনন্ততার জন্য দক্ষতার সাথে ব্যবহার করার জন্য একটি এনকোডিংকে সংজ্ঞায়িত করে, তাই নির্ভুলভাবে প্রতিনিধিত্ব করা সংখ্যার মধ্যে ফাঁক রয়েছে সংখ্যাগুলি প্রায় আনুমানিক।

দুর্ভাগ্যক্রমে 0.3 একটি ফাঁকে বসে।


4

বেজ টেনে কাজ করার কথাটি কল করুন, বলুন, যথার্থতার 8 টি সংখ্যা। আপনি পরীক্ষা করে দেখুন কিনা

1/3 + 2 / 3 == 1

এবং শিখুন যে এই ফিরে আসে false । কেন? ঠিক আছে, আমাদের কাছে আসল সংখ্যা রয়েছে

1/3 = 0.333 .... এবং 2/3 = 0.666 ....

আট দশমিক জায়গায় ছাঁটাই, আমরা পাই

0.33333333 + 0.66666666 = 0.99999999

যা অবশ্যই 1.00000000একেবারে থেকে আলাদা 0.00000001


একটি নির্দিষ্ট সংখ্যক বিটের বাইনারি সংখ্যার পরিস্থিতি হুবহু অভিন্ন। আসল সংখ্যা হিসাবে, আমাদের আছে

1/10 = 0.0001100110011001100 ... (বেস 2)

এবং

1/5 = 0.0011001100110011001 ... (বেস 2)

যদি আমরা এগুলিকে সাতটি বিট কেটে ফেলে বলি, তবে আমরা পেয়ে যাব

0.0001100 + 0.0011001 = 0.0100101

অন্যদিকে,

3/10 = 0.01001100110011 ... (বেস 2)

যা সাতটি বিটকে কাটা হয়েছে 0.0100110, এবং এগুলি একেবারে পৃথক 0.0000001


সঠিক পরিস্থিতি কিছুটা সূক্ষ্ম কারণ এই সংখ্যাগুলি সাধারণত বৈজ্ঞানিক স্বরলিপিতে সংরক্ষণ করা হয়। সুতরাং, উদাহরণস্বরূপ, 1/10 সংরক্ষণ করার পরিবর্তে 0.0001100আমরা এটিকে কিছু পছন্দ করে রাখতে পারি1.10011 * 2^-4 , আমরা খাঁটি এবং ম্যান্টিসার জন্য কত বিট বরাদ্দ করেছি তার উপর নির্ভর করে। এটি আপনার গণনার জন্য কত সংখ্যক নির্ভুলতা পেয়েছে তা প্রভাবিত করে।

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


4

পাইথন ৩.৩ যেহেতুmath.isclose() আনুমানিক সমতা পরীক্ষার জন্য আপনি ফাংশনটি ব্যবহার করতে পারেন :

>>> import math
>>> math.isclose(0.1 + 0.2, 0.3)
True
>>> 0.1 + 0.2 == 0.3
False

3

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

উদাহরণস্বরূপ https://posithub.org/ দেখুন , যা পোজিট (এবং এর পূর্বসূরি আনম) নামক একটি সংখ্যার প্রকার প্রদর্শন করে যা কম বিট দিয়ে আরও ভাল নির্ভুলতার প্রস্তাব দেয়। যদি আমার বোঝাপড়াটি সঠিক হয় তবে এটি প্রশ্নের ধরণের সমস্যাগুলিও ঠিক করে দেয়। বেশ আকর্ষণীয় প্রকল্প, এর পিছনে ব্যক্তি গণিতবিদ এটি ডঃ জন গুস্তাফসন । পুরো জিনিসটি ওপেন সোর্স, সি / সি ++, পাইথন, জুলিয়া এবং সি # ( https://hastlayer.com/arithmetics ) এর অনেকগুলি বাস্তব বাস্তবায়ন সহ ।


3

এটি আসলে বেশ সহজ। আপনার যদি বেস 10 সিস্টেম থাকে (আমাদের মতো), এটি কেবলমাত্র ভগ্নাংশ প্রকাশ করতে পারে যা বেসের একটি প্রধান উপাদান ব্যবহার করে। 10 এর প্রধান গুণকগুলি 2 এবং 5 হয়। সুতরাং 1/2, 1/4, 1/5, 1/8, এবং 1/10 সমস্ত পরিষ্কারভাবে প্রকাশ করা যেতে পারে কারণ ডিনোটেটররা 10 এর প্রধান উপাদান ব্যবহার করে বিপরীতে, 1 / 3, 1/6, এবং 1/7 সমস্তই দশমিক পুনরাবৃত্তি কারণ তাদের ডিনোমিনেটর 3 বা 7 এর একটি মৌলিক গুণক ব্যবহার করে বাইনারি (বা বেস 2) এ একমাত্র প্রধান ফ্যাক্টর 2 তাই আপনি কেবল ভগ্নাংশ পরিষ্কারভাবে প্রকাশ করতে পারবেন যা একটি প্রধান উপাদান হিসাবে কেবল 2 থাকে। বাইনারি, 1/2, 1/4, 1/8 সবই দশমিক হিসাবে পরিষ্কারভাবে প্রকাশ করা হবে। যখন, 1/5 বা 1/10 দশমিক পুনরাবৃত্তি হবে। সুতরাং 0.1 এবং 0.2 (1/10 এবং 1/5) যখন বেস 10 সিস্টেমে পরিষ্কার দশমিকগুলি, বেস 2 সিস্টেমে দশমিকগুলি পুনরাবৃত্তি করছে কম্পিউটারটি কাজ করছে When আপনি যখন এই পুনরাবৃত্তি দশমিকগুলিতে গণিত করেন,

Https://0.30000000000000004.com/ থেকে


3

যেমন ডেসিমাল সংখ্যা 0.1, 0.2এবং 0.3বাইনারি ঠিক প্রতিনিধিত্ব নেই ফ্লোটিং পয়েন্ট ধরনের এনকোড। জন্য অনুমান এর সমষ্টি 0.1এবং 0.2জন্য ব্যবহৃত পড়তা থেকে পৃথক 0.3, অত এর মিথ্যা 0.1 + 0.2 == 0.3হিসাবে আরো পরিষ্কারভাবে এখানে দেখা যাবে:

#include <stdio.h>

int main() {
    printf("0.1 + 0.2 == 0.3 is %s\n", 0.1 + 0.2 == 0.3 ? "true" : "false");
    printf("0.1 is %.23f\n", 0.1);
    printf("0.2 is %.23f\n", 0.2);
    printf("0.1 + 0.2 is %.23f\n", 0.1 + 0.2);
    printf("0.3 is %.23f\n", 0.3);
    printf("0.3 - (0.1 + 0.2) is %g\n", 0.3 - (0.1 + 0.2));
    return 0;
}

আউটপুট:

0.1 + 0.2 == 0.3 is false
0.1 is 0.10000000000000000555112
0.2 is 0.20000000000000001110223
0.1 + 0.2 is 0.30000000000000004440892
0.3 is 0.29999999999999998889777
0.3 - (0.1 + 0.2) is -5.55112e-17

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

_Decimal32, _Decimal64এবং _Decimal128ধরনের আপনার সিস্টেমে উপলব্ধ হতে পারে (উদাহরণস্বরূপ, জিসিসি তাদের উপর সমর্থন নির্বাচিত লক্ষ্যমাত্রা কিন্তু ঝনঝন তাদের উপর সমর্থন করে না OS X এর )।


1

ম্যাথ.সাম (জাভাস্ক্রিপ্ট) .... অপারেটর প্রতিস্থাপনের ধরণ

.1 + .0001 + -.1 --> 0.00010000000000000286
Math.sum(.1 , .0001, -.1) --> 0.0001

Object.defineProperties(Math, {
    sign: {
        value: function (x) {
            return x ? x < 0 ? -1 : 1 : 0;
            }
        },
    precision: {
        value: function (value, precision, type) {
            var v = parseFloat(value), 
                p = Math.max(precision, 0) || 0, 
                t = type || 'round';
            return (Math[t](v * Math.pow(10, p)) / Math.pow(10, p)).toFixed(p);
        }
    },
    scientific_to_num: {  // this is from https://gist.github.com/jiggzson
        value: function (num) {
            //if the number is in scientific notation remove it
            if (/e/i.test(num)) {
                var zero = '0',
                        parts = String(num).toLowerCase().split('e'), //split into coeff and exponent
                        e = parts.pop(), //store the exponential part
                        l = Math.abs(e), //get the number of zeros
                        sign = e / l,
                        coeff_array = parts[0].split('.');
                if (sign === -1) {
                    num = zero + '.' + new Array(l).join(zero) + coeff_array.join('');
                } else {
                    var dec = coeff_array[1];
                    if (dec)
                        l = l - dec.length;
                    num = coeff_array.join('') + new Array(l + 1).join(zero);
                }
            }
            return num;
         }
     }
    get_precision: {
        value: function (number) {
            var arr = Math.scientific_to_num((number + "")).split(".");
            return arr[1] ? arr[1].length : 0;
        }
    },
    sum: {
        value: function () {
            var prec = 0, sum = 0;
            for (var i = 0; i < arguments.length; i++) {
                prec = this.max(prec, this.get_precision(arguments[i]));
                sum += +arguments[i]; // force float to convert strings to number
            }
            return Math.precision(sum, prec);
        }
    }
});

ধারণাটি হ'ল ফ্ল্যাটের ত্রুটিগুলি এড়াতে পরিবর্তে অপারেটরগুলি ম্যাথ ব্যবহার করা

ম্যাথ.সুম ব্যবহারের জন্য নির্ভুলতা সনাক্ত করে

ম্যাথ.সুম যেকোন সংখ্যক যুক্তি গ্রহণ করে


1
আমি নিশ্চিত না যে আপনি এই প্রশ্নের উত্তর দিয়েছেন, "যদিও এই ভুলগুলি ঘটে? "
ওয়াই হা লি

একরকম আপনি ঠিক বলেছেন তবে আমি এই সমস্যাটি সম্পর্কে জাভাস্ক্রিপ্টের এক অদ্ভুত আচরণ থেকে এসেছি ... আমি কেবল
একধরণের

0

আমি কেবল এই আকর্ষণীয় ইস্যুটি ভাসমান পয়েন্টগুলির আশেপাশে দেখেছি:

নিম্নলিখিত ফলাফল বিবেচনা করুন:

error = (2**53+1) - int(float(2**53+1))
>>> (2**53+1) - int(float(2**53+1))
1

আমরা স্পষ্টভাবে একটি ব্রেকপয়েন্ট দেখতে পারি যখন 2**53+1- সমস্তক্ষণ অবধি কার্যকর থাকে 2**53

>>> (2**53) - int(float(2**53))
0

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

ডাবল-স্পষ্টতা বাইনারি কারণে এটি ঘটে: আইইইই 754 ডাবল-স্পষ্টতা বাইনারি ভাসমান-পয়েন্ট ফর্ম্যাট: বাইনারি 64

ডাবল-স্পষ্টতা ভাসমান-পয়েন্ট বিন্যাসের জন্য উইকিপিডিয়া পৃষ্ঠা থেকে :

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

  • সাইন বিট: 1 বিট
  • ঘোষক: 11 বিট
  • উল্লেখযোগ্য নির্ভুলতা: 53 বিট (52 স্পষ্টত সঞ্চিত)

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

প্রদত্ত পক্ষপাতিত্বকারী এক্সপোনেন্ট এবং 52-বিট ভগ্নাংশ সহ একটি প্রদত্ত 64-বিট ডাবল-স্পষ্টতা ডেটাম দ্বারা ধরে নেওয়া আসল মানটি

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

অথবা

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

আমাকে এটি নির্দেশ করার জন্য @a_guest কে ধন্যবাদ।


-1

এটির একটি সদৃশ হিসাবে একটি অন্য প্রশ্নের নাম দেওয়া হয়েছে:

সি ++ এ, cout << xকোনও ডিবাগার যে মানটি দেখায় তার থেকে আলাদা ফলাফল কেন x?

xপ্রশ্নে একটি হল floatপরিবর্তনশীল।

একটি উদাহরণ হবে

float x = 9.9F;

ডিবাগারটি দেখায় 9.89999962, coutঅপারেশন আউটপুট হয় 9.9

উত্তরটি সেই coutডিফল্ট নির্ভুলতার জন্য পরিণত হয়েছেfloat 6 হয়, সুতরাং এটি 6 দশমিক সংখ্যায় গোল হয়।

রেফারেন্সের জন্য এখানে দেখুন


1
আইএমও - এখানে পোস্ট করা ভুল পদ্ধতি ছিল। আমি জানি এটি হতাশার, তবে যাদের মূল প্রশ্নের উত্তর প্রয়োজন (আপাতদৃষ্টিতে মুছে ফেলা হয়েছে!) তারা এখানে পাবেন না here যদি আপনি সত্যিই অনুভব করেন যে আপনার কাজটি সংরক্ষণের যোগ্য, তবে আমি পরামর্শ দেব: 1) অন্য প্রশ্নটির সন্ধান করা যা এর প্রকৃত উত্তর দেয়, ২) একটি স্ব-উত্তরযুক্ত প্রশ্ন তৈরি করা।
স্টিফেন সি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.