(I == i + 1) - forever forever চিরকালের জন্য লুপ করার সময় আমার কোন মানটির জন্য?


120

আমি যুক্তরাজ্যের একটি ইউনিভার্সিটি পরীক্ষায় একটি উন্নত প্রোগ্রামিং কোর্স থেকে এই পাজলারের পাশ কাটিয়েছি

নিম্নলিখিত লুপটি বিবেচনা করুন, যেখানে আমি এখনও অবধি অঘোষিত:

while (i == i + 1) {}

iএই লুপটির পূর্ববর্তী সংজ্ঞাটি সন্ধান করুন , যেমন লুপটি চিরকাল অব্যাহত থাকে।

পরবর্তী প্রশ্ন, যা এই কোড স্নিপেটের জন্য একই প্রশ্ন জিজ্ঞাসা করেছিল:

while (i != i) {}

আমার কাছে স্পষ্ট ছিল অবশ্যই এই অন্যান্য পরিস্থিতিতে এটি তবে NaNতবে আমি সত্যিই পূর্বেরটির সাথে আটকে আছি। ওভারফ্লো এর সাথে কি এই সম্পর্ক আছে? জাভাতে চিরকালের জন্য এ জাতীয় লুপের কারণ কী হবে?


3
.equals()পদ্ধতিতে ওভাররাইডের কোনও সম্ভাবনা ? যেহেতু আমি অঘোষিত, তাই আমরা যা চাই তার যে কোনও শ্রেণি ব্যবহার করতে পারি।
জেনো চেন

7
@ রেয়েডওয়াল্ড "অলাভজনক" কোড অধ্যয়ন আপনাকে আরও "পেশাদার" করে তুলেছে, তাই ... যাইহোক, এটি একটি ভাল প্রশ্ন
অ্যান্ড্রু টবিলকো

12
মজার বিষয়, সি # এই এছাড়াও nullable সাংখ্যিক ধরনের যার মান জন্য কাজ করে null, কারণ null == nullসত্য, এবং null + 1হয় null
এরিক লিপার্ট

4
@ এরিকডুমিনিল: পরিস্থিতি আপনার কল্পনার চেয়ে অনেক খারাপ। অনেক ভাষায়, ভাসমান পয়েন্ট গণিতটি অবশ্যই একটি ডাবল দ্বারা নির্দিষ্ট কমপক্ষে b৪ বিটের মধ্যে সম্পন্ন করতে হবে, যার অর্থ এটি কম্পাইলারের ঝাঁকুনিতে উচ্চতর নির্ভুলতার সাথে করা যেতে পারে এবং বাস্তবে এটি ঘটে । আমি আপনাকে সি # প্রোগ্রামারদের কাছ থেকে এই সাইটে এক ডজন প্রশ্নে ইঙ্গিত করতে পারি যারা ভাবছেন যে 0.2 + 0.1 == 0.3সংকলক সেটিংস, চাঁদের ধাপ এবং এর উপর নির্ভর করে কেন এর মান পরিবর্তন করে।
এরিক লিপার্ট

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

উত্তর:


142

প্রথমত, যেহেতু while (i == i + 1) {}লুপটির মান পরিবর্তন হয় না i, তাই এই লুপটিকে অসীম করে তোলা iসেই সন্তুষ্টির মান চয়ন করার সমতুল্য i == i + 1

এ জাতীয় অনেক মান রয়েছে:

আসুন "বিদেশী" দিয়ে শুরু করুন:

double i = Double.POSITIVE_INFINITY;

অথবা

double i =  Double.NEGATIVE_INFINITY;

এই মানগুলি সন্তুষ্ট করার কারণটি জেএলএস 15.18.2 তেi == i + 1 বর্ণিত হয়েছে
। সংখ্যার প্রকারের জন্য অ্যাডিটিভ অপারেটর (+ এবং -) :

একটি অসীম এবং একটি সীমাবদ্ধ মানের যোগফল অসীম অপারেন্ডের সমান।

এটি আশ্চর্যজনক নয়, যেহেতু অসীম মানটিতে একটি সীমাবদ্ধ মান যুক্ত হওয়ার ফলে একটি অসীম মান হওয়া উচিত।

এটি বলেছে iযে সন্তুষ্টির i == i + 1বেশিরভাগ মানগুলি কেবল বড় double(বা float) মানগুলি:

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

double i = Double.MAX_VALUE;

অথবা

double i = 1000000000000000000.0;

অথবা

float i = 1000000000000000000.0f;

doubleএবং floatধরনের সীমিত স্পষ্টতা আছে, তাই আপনি যদি একটি বৃহৎ যথেষ্ট নেওয়া doubleবা floatমান যোগ 1এটি একই মান স্থাপিত হবে।


10
বা (double)(1L<<53)- বাfloat i = (float)(1<<24)
dave_thompson_085

3
@ রুসলান: যে কোনও গণিতবিদ একমত নন। ভাসমান পয়েন্ট সংখ্যাগুলি খুব কম বোঝায়। এগুলি অ-সহযোগী, অ-প্রতিবিম্বিত (NaN! = NaN), এবং এমনকি প্রতিস্থাপনযোগ্যও নয় (-0 == 0, তবে 1/0! = 1 / -0)। তাই বীজগণিতের বেশিরভাগ যন্ত্রপাতি প্রয়োগযোগ্য নয়।
কেভিন

2
@ কেভিন যখন ভাসমান-পয়েন্ট সংখ্যাগুলি প্রকৃতপক্ষে খুব বেশি অর্থবোধ করতে পারেন না, তবে অসীমের আচরণ (যা এই বাক্যে বর্ণিত হয়েছে) বোঝার জন্য তৈরি করা হয়েছিল।
Ruslan

4
@ কেভিন ভাসমানদের কাছে ন্যায়সঙ্গত হওয়ার জন্য, আপনি যদি অসম্পূর্ণতা বা অপরিজ্ঞাত মানগুলির সাথে লেনদেন করেন তবে আপনি বীজগণিতের তালিকাভুক্ত বৈশিষ্ট্যগুলি ধরে নিতে পারবেন না।
ভু

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

64

এই ধাঁধাগুলি জোশুয়া ব্লচ এবং নীল গিটোয়ারের "জাভা পাজলার্স: ট্র্যাপস, পিটফলস এবং কর্নার কেসস" বইয়ে বিশদে বর্ণনা করা হয়েছে।

double i = Double.POSITIVE_INFINITY;
while (i == i + 1) {}

বা:

double i = 1.0e40;
while (i == i + 1) {}

উভয়ই একটি অসীম লুপের ফলশ্রুতি লাভ করবে, কারণ 1যথেষ্ট পরিমাণে বড় একটি ভাসমান-পয়েন্ট মান যুক্ত করা মানটি পরিবর্তন করতে পারে না, কারণ এটি তার উত্তরসূরি 1 এর সাথে "ব্যবধানটি পূরণ করে না" ।

দ্বিতীয় ধাঁধা সম্পর্কে একটি নোট (ভবিষ্যতের পাঠকদের জন্য):

double i = Double.NaN;
while (i != i) {}

এছাড়াও অসীম লুপের ফলাফল হয়, কারণ NaN নিজে 2 সহ কোনও ভাসমান-বিন্দু মানের সমান নয়


1 - জাভা পাজলার্স: ট্র্যাপস, পিটফলস এবং কর্নার কেসস (অধ্যায় 4 - লুপী পাজলারস)।

2 - জেএলএস §15.21.1



0

শুধু একটি ধারণা: বুলিয়ান সম্পর্কে কী?

bool i = TRUE;

এই ঘটনাটি কোথায় না i + 1 == i?


ভাষার উপর নির্ভর করে। অনেকগুলি ভাষা স্বতঃস্ফূর্তভাবে একত্রিত হয়ে স্বয়ংক্রিয়ভাবে বুলেটিকে অন্তরগুলিতে বাধ্য করে। অন্যরা আপনার পরামর্শ অনুসারে কাজ করে - একটি বুলিয়ানকে অন্তর্ভুক্ত করে।
কার্ল উইথফট

8
এই প্রশ্নটি একটি জাভা প্রশ্ন, এবং আপনার পরামর্শটি জাভাতে সংকলনটি পাস করবে না (যার কোনও +অপারেটর নেই যা একটি booleanএবং intঅপারেটস হিসাবে গ্রহণ করে )।
ইরান

@ ইরান: এটি অপারেটর ওভারলোডিংয়ের পুরো ধারণা। আপনি জাভা বুলিয়ানদের সি ++ এর মতো আচরণ করতে পারেন।
ডোমিনিক

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