কেন একাধিকবার ০.০ যোগ করলে ক্ষতিহীন থাকে?


152

আমি জানি 0.1দশমিক সংখ্যাটি সীমাবদ্ধ বাইনারি সংখ্যার ( ব্যাখ্যা ) দিয়ে সঠিকভাবে উপস্থাপন করা যায় না , সুতরাং double n = 0.1কিছু নির্ভুলতা হারাবে এবং ঠিক হবে না 0.1। অন্যদিকে 0.5ঠিক তাই প্রতিনিধিত্ব করা যেতে পারে কারণ এটি 0.5 = 1/2 = 0.1b

এই বলে যে এটি বোধগম্য যে 0.1 তিনবার যুক্ত করা ঠিক 0.3নীচের কোডের মুদ্রণগুলি দেয় না false:

double sum = 0, d = 0.1;
for (int i = 0; i < 3; i++)
    sum += d;
System.out.println(sum == 0.3); // Prints false, OK

কিন্তু তারপরে এটি কীভাবে 0.1 পাঁচবার যুক্ত করলে ঠিক দেবে 0.5? নিম্নলিখিত কোড মুদ্রণ true:

double sum = 0, d = 0.1;
for (int i = 0; i < 5; i++)
    sum += d;
System.out.println(sum == 0.5); // Prints true, WHY?

যদি 0.1যথাযথভাবে উপস্থাপন করা যায় না, তবে এটি কীভাবে এটি 5 বার যুক্ত করলে ঠিক 0.5যা সঠিকভাবে উপস্থাপিত হতে পারে তা দেয় ?


7
আপনি যদি সত্যই এটি গবেষণা করেন তবে আমি নিশ্চিত যে আপনি এটি নির্ধারণ করতে পারবেন তবে ভাসমান পয়েন্টটি "আশ্চর্য" দিয়ে বোঝায় এবং কখনও কখনও অবাক হয়ে তাকানো আরও ভাল।
হট লিকস

3
আপনি একটি গাণিতিক উপায়ে এটি সম্পর্কে চিন্তা করছেন। ভাসমান পয়েন্ট শৈল্পিকতা কোনওভাবেই গণিত নয়।
জাকব

13
@ হটলিক্স যা খুব বেশি ভুল দৃষ্টিভঙ্গি রাখে।
hobbs

2
@ রাসেলবোরোগোভ এমনকি এটি অপ্টিমাইজড হয়ে গেলেও, এটি কেবলমাত্র বৈধ অপ্টিমাইজেশন হতে পারে যদি sumএকই চূড়ান্ত মানটি লুপটিকে বাস্তবায়িত করা হয়। সি ++ স্ট্যান্ডার্ডে এটিকে "যেমন-নিয়ম" বা "একই পর্যবেক্ষণযোগ্য আচরণ" বলা হয়।
hobbs

7
@ জাকব মোটেও সত্য নয়। ভাসমান-পয়েন্ট পাটিগণিতকে ত্রুটি সীমা এবং এর মতো ভাল গাণিতিক চিকিত্সার সাথে কঠোরভাবে সংজ্ঞায়িত করা হয়। এটি কেবলমাত্র অনেক প্রোগ্রামারই হয় বিশ্লেষণটি অনুসরণ করতে রাজি নয় বা তারা ভুল করে বিশ্বাস করে যে "ভাসমান-বিন্দুটি নিখুঁত" এটি যা আছে তা জানা এবং বিশ্লেষণটি বিরক্ত করার মতো নয়।
hobbs

উত্তর:


155

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

উদাহরণ হিসেবে বলা যায় 0.1ঠিক নয় 0.1অর্থাৎ new BigDecimal("0.1") < new BigDecimal(0.1)কিন্তু 0.5ঠিক1.0/2

এই প্রোগ্রামটি আপনাকে জড়িত প্রকৃত মান দেখায়।

BigDecimal _0_1 = new BigDecimal(0.1);
BigDecimal x = _0_1;
for(int i = 1; i <= 10; i ++) {
    System.out.println(i+" x 0.1 is "+x+", as double "+x.doubleValue());
    x = x.add(_0_1);
}

কপি করে প্রিন্ট

0.1000000000000000055511151231257827021181583404541015625, as double 0.1
0.2000000000000000111022302462515654042363166809082031250, as double 0.2
0.3000000000000000166533453693773481063544750213623046875, as double 0.30000000000000004
0.4000000000000000222044604925031308084726333618164062500, as double 0.4
0.5000000000000000277555756156289135105907917022705078125, as double 0.5
0.6000000000000000333066907387546962127089500427246093750, as double 0.6000000000000001
0.7000000000000000388578058618804789148271083831787109375, as double 0.7000000000000001
0.8000000000000000444089209850062616169452667236328125000, as double 0.8
0.9000000000000000499600361081320443190634250640869140625, as double 0.9
1.0000000000000000555111512312578270211815834045410156250, as double 1.0

দ্রষ্টব্য: এটি 0.3সামান্য বন্ধ, তবে আপনি যখন 0.4বিটগুলি পৌঁছান তখন 53-বিট সীমাতে ফিট করার জন্য একটিকে নীচে স্থানান্তর করতে হয় এবং ত্রুটিটি বাতিল করা হয়। আবার, একটি ত্রুটি শিহরণ জন্য ব্যাক 0.6এবং 0.7কিন্তু 0.8করতে 1.0ত্রুটি বাতিল করা হয়।

এটি 5 বার যুক্ত করার ফলে ত্রুটিটি কমিয়ে দেওয়া উচিত, এটি বাতিল করা উচিত নয়।

ত্রুটি হওয়ার কারণ সীমিত নির্ভুলতার কারণে। অর্থাৎ 53-বিট। এর অর্থ হ'ল সংখ্যাটি বড় হওয়ার সাথে সাথে আরও বিট ব্যবহার করে, বিটগুলি শেষের দিকে ফেলে দিতে হবে। এই ক্ষেত্রে গোলাকার কারণ যা আপনার পক্ষে রয়েছে causes
একটি ছোট সংখ্যা যেমন 0.1-0.0999= => পেয়ে গেলে আপনি বিপরীত প্রভাব পেতে পারেন 1.0000000000000286E-4 এবং আপনি আগের চেয়ে আরও ত্রুটি দেখতে পাচ্ছেন।

জাভা in-এ ম্যাথ.াউন্ডে কেন (0.49999999999999994) ফিরে আসে এর একটি উদাহরণ 1 এই ক্ষেত্রে গণনায় কিছুটা ক্ষতি হ'ল উত্তরে বড় পার্থক্য দেখা দেয়।


1
এটি কোথায় বাস্তবায়িত হয়?
এপিকপান্ডাফোরস

16
@ জুইনডেন সিপিইউ আইইইই -754 মান অনুসরণ করে। জাভা আপনাকে অন্তর্নিহিত সিপিইউ নির্দেশাবলী অ্যাক্সেস দেয় এবং এতে জড়িত হয় না। en.wikedia.org/wiki/IEEE_floating_Point
পিটার ল্যারি

10
@ পিটারলাউরে: সিপিইউ করার দরকার নেই। সিপিইউতে ফ্লোটিং পয়েন্ট ছাড়াই একটি মেশিনে (এবং কোনও পৃথক এফপিইউ ব্যবহারের প্রয়োজন নেই), আইইইই গণিত সফ্টওয়্যার দ্বারা সম্পাদিত হবে। এবং যদি হোস্ট সিপিইউতে ভাসমান পয়েন্ট থাকে তবে এটি আইইইই প্রয়োজনীয়তার সাথে সামঞ্জস্য না করে, আমি মনে করি যে সিপিইউয়ের জন্য একটি জাভা বাস্তবায়নও নরম ভাসা ব্যবহার করতে বাধ্য হবে ...
আর .. গিটিহাব স্টপ হেল্পিং আইসিই

1
@ আর .. এমন ক্ষেত্রে আমি জানি না যদি আপনি strictfp সময় বিবেচনা করে নির্দিষ্ট পয়েন্ট পূর্ণসংখ্যার বিবেচনা করতে চান তবে আমি কী করব। (বা বিগডিসিমাল)
পিটার

2
@ ইউজিন মূল সমস্যাটি হ'ল সীমিত মানগুলি যা ভাসমান পয়েন্ট উপস্থাপন করতে পারে। এই সীমাবদ্ধতার ফলে তথ্য হারাতে পারে এবং সংখ্যাটি ত্রুটির ক্ষতি হ্রাস করতে পারে। এটি রাউন্ডিং ব্যবহার করে তবে এই ক্ষেত্রে, গোলগুলি ডাউন হয় তাই ০.১ কিছুটা বড় হওয়ায় সামান্য পরিমাণে খুব বড় এমন একটি সংখ্যার কী হত, সঠিক মানে পরিণত হয়। ঠিক 0.5
পিটার লরি

47

ওভারফ্লো ছাড়া, ফ্লোটিং পয়েন্ট এ, x + x + xঠিক সঠিকভাবে বৃত্তাকার (অর্থাত নিকটতম) ফ্লোটিং পয়েন্ট বাস্তব 3 * সংখ্যা x, x + x + x + xঠিক 4 * হয় x, এবং x + x + x + x + xআবার 5 * জন্য সঠিকভাবে বৃত্তাকার ফ্লোটিং পয়েন্ট পড়তা হয় x

প্রথম ফলাফলটি হ'ল x + x + xসত্য থেকে উদ্ভূত x + xx + x + xএইভাবে কেবল একটি রাউন্ডিংয়ের ফলাফল।

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

তৃতীয় ফলাফল, " x + x + x + x + xসঠিকভাবে গোলাকার", দ্বিতীয়টির একই পদ্ধতিতে প্রাপ্ত হয় ঠিক যেমনটি প্রথম থেকে প্রাপ্ত হয় x + x


দ্বিতীয় ফলাফলটি কেন 0.1 + 0.1 + 0.1 + 0.1ভাসমান-পয়েন্ট সংখ্যাটি ঠিক তা বোঝায় 0.4: 1-10 এবং 4/10 এ যুক্তিযুক্ত সংখ্যাগুলি একইভাবে আপেক্ষিক ত্রুটিযুক্ত হয়ে ভাসমান-বিন্দুতে রূপান্তরিত হওয়ার সাথে সাথে সমান হয়। এই ভাসমান-পয়েন্ট সংখ্যাগুলির মধ্যে ঠিক 4 এর অনুপাত থাকে। প্রথম এবং তৃতীয় ফলাফলটি দেখায় 0.1 + 0.1 + 0.1এবং 0.1 + 0.1 + 0.1 + 0.1 + 0.1নিখুঁত ত্রুটি বিশ্লেষণ দ্বারা অনুমান করা হতে পারে তার চেয়ে কম ত্রুটি হওয়ার আশা করা যেতে পারে তবে তারা নিজেরাই কেবল যথাক্রমে ফলাফলগুলি সম্পর্কিত করে 3 * 0.1এবং 5 * 0.1নিকট হতে পারে বলে আশা করা যেতে পারে তবে অগত্যা অভিন্ন নয় 0.3এবং 0.5

আপনি যদি 0.1চতুর্থ সংযোজনের পরে যোগ করা চালিয়ে যান , আপনি অবশেষে গোলাকার ত্রুটিগুলি পর্যবেক্ষণ করবেন যা " 0.1নিজের মধ্যে n বার যোগ করা" থেকে ডাইভার্জ করে n * 0.1এবং এন / 10 থেকে আরও বেশি ডাইভারেজ করে। আপনি যদি এন এর ক্রিয়াকলাপ হিসাবে "০.১ নিজেই যোগ হয়েছিলেন" এর মানগুলি প্লট করতে থাকেন তবে আপনি বিনয়েড দ্বারা ধ্রুবক opeালের রেখাগুলি পর্যবেক্ষণ করবেন (নবম সংযোজনের ফলাফলের সাথে সাথে কোনও নির্দিষ্ট বিনেডে পড়ার নিয়ত হবে, সংযোজনের বৈশিষ্ট্যগুলি পূর্বের সংযোজনগুলির অনুরূপ হতে পারে যা একই বাইনাদে ফলাফল তৈরি করেছিল)। একই বাইনাদে ত্রুটিটি হয় বাড়বে বা সঙ্কুচিত হবে। আপনি যদি বিনেদ থেকে বিনেদ পর্যন্ত opালুগুলির ক্রমটি দেখতে চান তবে আপনি পুনরাবৃত্ত সংখ্যাগুলি চিনতে পারবেন0.1কিছু সময়ের জন্য বাইনারি মধ্যে। এর পরে, শোষণ শুরু হয়ে যায় এবং বক্রটি সমতল হয়।


1
প্রথম লাইনে আপনি বলছেন যে এক্স + এক্স + এক্স ঠিক সঠিক, তবে প্রশ্নের উদাহরণ থেকে এটি নয়।
আলবোজ

2
@ আলবোজ আমি বলছি এটি x + x + xহ'ল আসল 3 * এর সঠিকভাবে গোলাকার ভাসমান-পয়েন্ট নম্বর x। "সঠিকভাবে গোলাকার" এর অর্থ এই প্রসঙ্গে "নিকটতম"।
পাস্কেল কুয়াক

4
+1 এটি গ্রহণযোগ্য উত্তর হওয়া উচিত। এটি প্রকৃতপক্ষে অস্পষ্ট সাধারণতার চেয়ে বরং কী চলছে তার ব্যাখ্যা / প্রমাণ সরবরাহ করে।
আর .. গিথহাব থামিয়ে দিন IEL

1
@ আলবোজ (সমস্ত কিছুই প্রশ্ন দ্বারা কল্পনা করা হয়)। তবে এই উত্তরটি যা ব্যাখ্যা করে তা হ'ল কীভাবে ত্রুটিগুলি সবচেয়ে খারাপ ক্ষেত্রে।
hobbs

1
@ চেবস ০.০ হ'ল 0x1.99999999999999999999999… হেক্সাডেসিমালে পি -4 (অঙ্কগুলির একটি অসীম অনুক্রম)। এটি 0x1.99999ap-4 হিসাবে ডাবল-নির্ভুলতায় আনুমানিক। 0.2 হেক্সাডেসিমালে 0x1.99999999999999999999999… পি -3। 0.1 একই কারণে 0x1.99999ap-4 হিসাবে, 0.2 0x1.99999ap-3 হিসাবে সন্নিবেশিত হয়। এদিকে 0x1.99999ap-3 হ'ল 0x1.99999ap-4 + 0x1.99999ap-4 is
পাস্কেল কুয়াক

-1

রাউন্ডিংয়ের জন্য কয়েকটি অতিরিক্ত বিটগুলি সহ ফ্লোটিং পয়েন্ট সিস্টেমগুলি বিভিন্ন যাদু করে। সুতরাং 0.1 এর নিখুঁত প্রতিনিধিত্বের কারণে খুব ছোট ত্রুটি 0.5 টি থেকে গোল হয়ে শেষ হয়।

সংখ্যাগুলি উপস্থাপনের জন্য ভাসমান পয়েন্টটিকে দুর্দান্ত তবে INXACT উপায় হিসাবে ভাবেন। সমস্ত সম্ভব সংখ্যা কম্পিউটারে সহজেই প্রতিনিধিত্ব করা হয় না। পিআই এর মতো অযৌক্তিক সংখ্যা। অথবা এসকিউআরটি (2) এর মতো। (প্রতীকী গণিত সিস্টেমগুলি সেগুলি উপস্থাপন করতে পারে তবে আমি "সহজেই" বলেছি))

ভাসমান পয়েন্ট মানটি খুব নিকটে হতে পারে তবে সঠিক নয়। এটি এত কাছাকাছি হতে পারে যে আপনি প্লুটোতে নেভিগেট করতে পারেন এবং মিলিমিটার দ্বারা বন্ধ হয়ে যেতে পারেন। তবে এখনও গাণিতিক দিক থেকে সঠিক নয়।

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

মুদ্রার জন্য বিগডিসিমাল ব্যবহার করা ভাল কাজ করে কারণ অন্তর্নিহিত উপস্থাপনা একটি পূর্ণসংখ্যার হলেও একটি বৃহত্তর।

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

অ্যাপ্লিকেশন গণনা করার জন্য (অ্যাকাউন্টিং সহ) পূর্ণসংখ্যা ব্যবহার করুন। গেটের মধ্য দিয়ে যায় এমন লোকের সংখ্যা গণনা করার জন্য, আন্ত বা দীর্ঘ ব্যবহার করুন।


2
প্রশ্নটি ট্যাগ করা [জাভা]। জাভা ভাষার সংজ্ঞায় কেবলমাত্র কয়েকটি অতিরিক্ত ব্যয়কারী বিটের জন্য "নির্ভুলতার কয়েকটি অতিরিক্ত বিট" দেওয়ার বিধান নেই (এবং এটি আপনি ব্যবহার না করলেই হয় strictfp)। আপনি কিছু বোঝার জন্য ত্যাগ করেছেন বলেই এর অর্থ এই নয় যে এটি অনুপযুক্ত এবং অন্যরাও এটি বোঝার জন্য ত্যাগ করা উচিত নয়। দেখুন stackoverflow.com/questions/18496560 লেন্থ জাভা বাস্তবায়নের ভাষার সংজ্ঞা (যা অতিরিক্ত স্পষ্টতা বিট জন্য কোন বিধান কিংবা, সঙ্গে অন্তর্ভুক্ত নয় বাস্তবায়ন করার জন্য যেতে হবে একটি উদাহরণ হিসাবে strictfp, কোন অতিরিক্ত মেপুঃ বিট জন্য)
পাসকাল Cuoq
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.