+0 এবং -0 ইনট এবং ফ্লোট ডেটার জন্য আলাদা আচরণ দেখায়


16

আমি এই পোস্টটি নেতিবাচক এবং ধনাত্মক শূন্যটি পড়েছি ।

আমার বোঝার জন্য নিম্নলিখিত কোডটি দেওয়া উচিত true এবং true আউটপুট হিসাবে।

তবে এটি দিচ্ছে falseএবং trueআউটপুট হিসাবে।

আমি ধনাত্মক শূন্যের সাথে নেতিবাচক শূন্যের তুলনা করছি।

public class Test {
     public static void main(String[] args) {
            float f = 0;
            float f2 = -f;
            Float F = new Float(f);
            Float F1 = new Float(f2);
            System.out.println(F1.equals(F));

            int i = 0;
            int i2 = -i;
            Integer I = new Integer(i);
            Integer I1 = new Integer(i2);
            System.out.println(I1.equals(I));
      }
  }

আমরা 0 জন্য এর জন্য বিভিন্ন আচরণ কেন আছে Integerএবং Float?


11
আপনি যদি জাভাডোকগুলি পরীক্ষা করেন, ডকসস.অরাকল .com/ জাভাসে / ৮ / ডকস / এপি / জাভা / লং .… সংজ্ঞা হ্যাশ টেবিলগুলি সঠিকভাবে কাজ করতে দেয় allows এছাড়াও, কোনও -0 পূর্ণসংখ্যা নেই।
ম্যাট

@ ম্যাট যদি -0 সংখ্যাসূচক না হয় তবে এটি মিথ্যা হিসাবে মূল্যায়ন করা উচিত ...
জোকার

3
আপনি যখন বলবেন i2 = -i; i2 i এর সঠিক বিট উপস্থাপনা নেয়, সেগুলি সনাক্ত করার কোনও উপায় নেই। iএবং i2ঠিক একই। তারপরে আপনি যখন নতুন Integerগুলি তৈরি করেন তখন এগুলি উভয়ই একই মানটি জড়ান। I1.equals(I)সত্য হবে।
ম্যাট

1
চেষ্টা করুন int i = Integer.MIN_VALUE, i2 = -i;...
হোলার

1
উপায় দ্বারা, newএখানে মোড়কের ধরণের জন্য ব্যবহার করার কোনও কারণ নেই। কেবল ব্যবহার করুন, যেমনInteger i = 0, i2 = -i; System.out.println(i.equals(i2)); Float f1 = 0f, f2 = -f1; System.out.println(f1.equals(f2));
হলগার

উত্তর:


19

ইনটস এবং ফ্লোটগুলি জাভাতে বেশ ভিন্ন জন্তু। Ints দুটি এর পরিপূরক হিসাবে এনকোড করা হয় , যার একক 0 মান রয়েছে। ফ্লোটগুলি আইইইই 754 ব্যবহার করে ( ফ্লোটগুলির জন্য 32-বিট ভেরিয়েন্ট এবং ডাবলসের জন্য 64-বিট )। আইইইই 754 কিছুটা জটিল, তবে এই উত্তরের উদ্দেশ্যে, আপনাকে কেবল এটি জানতে হবে যে এর তিনটি বিভাগ রয়েছে, যার প্রথমটি একটি সাইন বিট। এর অর্থ কোনও ফ্লোটের জন্য, ইতিবাচক এবং নেতিবাচক বৈকল্পিক রয়েছে ¹ এর মধ্যে 0 অন্তর্ভুক্ত রয়েছে, সুতরাং ফ্লোটগুলির আসলে দুটি "শূন্য" মান, +0 এবং -0 থাকে।

একপাশে, দু'টির পরিপূরক যা অন্তরঙ্গ ব্যবহার করে তা কম্পিউটার বিজ্ঞানে পূর্ণসংখ্যার এনকোড করার একমাত্র উপায় নয়। অন্যান্য পদ্ধতি রয়েছে , যেমনগুলির পরিপূরক , তবে তাদের গোঁজ থাকে - যেমন একটি +0 এবং -0 উভয় পৃথক মান হিসাবে। ;-)

আপনি যখন ফ্লোট আদিম (এবং দ্বিগুণ) তুলনা করেন, জাভা +0 এবং -0 সমান হিসাবে বিবেচনা করে। আপনি যখন সেগুলি বাক্স করেন, জাভা তাদের সাথে আলাদাভাবে আচরণ করে, যেমন বর্ণিত Float#equals। এটি সমান পদ্ধতিটি তাদের hashCodeবাস্তবায়নের সাথে সামঞ্জস্য করতে দেয় (পাশাপাশি compareTo), যা কেবলমাত্র ফ্লোটের বিটগুলি ব্যবহার করে (সেই স্বাক্ষরিত মান সহ) এবং সেগুলিকে যেমন কোনও আন্তঃরূপে সরিয়ে দেয়।

তারা সমান / হ্যাশকোড / তুলনা করার জন্য অন্য কিছু বিকল্প বেছে নিতে পারে, কিন্তু তারা তা করেনি। আমি নিশ্চিত নই যে সেখানে নকশার বিবেচনাগুলি কী ছিল। তবে কমপক্ষে একটি ক্ষেত্রে, Float#equalsসর্বদা ভাসমান আদিম থেকে সরে যেতে চলেছিল ==: আদিমগুলিতে NaN != NaN, তবে সমস্ত বস্তুর o.equals(o)ক্ষেত্রেও অবশ্যই সত্য হতে হবে । এর অর্থ হ'ল যদি আপনার ছিল Float f = Float.NaN, তবে f.equals(f)যদিও f.floatValue() != f.floatValue()


¹ NaN (একটি-সংখ্যা নয়) মানগুলির একটি সাইন বিট থাকে তবে অর্ডার দেওয়ার পরিবর্তে এর কোনও অর্থ হয় না এবং জাভা এটিকে উপেক্ষা করে (এমনকি অর্ডার দেওয়ার জন্যও)।


10

এটি ফ্লোট সমান ব্যতিক্রমগুলির মধ্যে একটি

দুটি ব্যতিক্রম আছে:

যদি f1 + 0.0f প্রতিনিধিত্ব করে যখন f2 -0.0f বা তার বিপরীতে উপস্থাপন করে, সমান পরীক্ষার মান মিথ্যা থাকে

কেন এটি বর্ণনা করা হয়:

এই সংজ্ঞা হ্যাশ টেবিলগুলি সঠিকভাবে পরিচালনা করতে দেয়।

-0 এবং 0 ফ্লোটের বিট 31 ব্যবহার করে আলাদাভাবে উপস্থাপন করবে:

বিট 31 (যে বিটটি মাস্ক 0x80000000 দ্বারা নির্বাচিত হয়েছে) ভাসমান-পয়েন্ট সংখ্যার চিহ্নটি উপস্থাপন করে।

এই ক্ষেত্রে হয় না Integer


প্রশ্ন কেন? এই কঠোর এবং দ্রুত নিয়মটি কি আমাদের ক্র্যাম করতে হবে :(
জোকার

@ জোকার যুক্ত উদ্ধৃতিটি হ্যাশ টেবিলগুলি সঠিকভাবে পরিচালিত করার অনুমতি দেয়
user7294900

4
এই জবাবটি (এবং জাভাদোক) উল্লেখ না করে এমন একটি মূল অংশটি হ'ল পার্থক্যটি হ'ল ফ্লোটে, +0 এবং -0 বিভিন্ন মান হয় - সমান, তবে ভিন্ন। মূলত, ভাসমানগুলির তিনটি অংশ থাকে এবং প্রথম অংশটি একক বিট যা ফ্লোটটি ইতিবাচক বা নেতিবাচক কিনা তা বলে। এটা না ints জন্য কেস (জাভা প্রতিনিধিত্ব হিসাবে), যা শুধুমাত্র একটি একক 0 মান রয়েছে।
ysavit

@ শাবিট ধন্যবাদ, আপনি কি উত্তর হিসাবে একই ভাগ করতে পারেন
জোকার

3
@ জোকার বিট 31 (মাস্ক 0x80000000 দ্বারা নির্বাচিত বিট) ভাসমান-পয়েন্ট সংখ্যার চিহ্নটি উপস্থাপন করে।
user7294900

5

পূর্ণসংখ্যার জন্য, পূর্ণসংখ্যার জন্য -0 এবং 0 এর মধ্যে কোনও পার্থক্য নেই কারণ এটি টুইসের প্রশংসা উপস্থাপনা ব্যবহার করে । সুতরাং আপনার পূর্ণসংখ্যা উদাহরণ iএবং i1ঠিক একই।

ফ্লোটগুলির জন্য, এখানে একটি -0 উপস্থাপনা রয়েছে এবং এর মান 0 এর সমান, তবে বিটের উপস্থাপনাটি আলাদা। সুতরাং নতুন ফ্লোট (0 এফ) এবং নতুন ফ্লোট (-0f) এর বিভিন্ন উপস্থাপনা থাকবে।

আপনি বিট উপস্থাপনার মধ্যে পার্থক্য দেখতে পারেন।

System.out.println(Float.floatToIntBits(-0f) + ", " + Float.floatToIntBits(0f));

-2147483648, 0

এবং যদি আপনি ঘোষণাটি ছেড়ে fদেন -0fতবে এটি একটি পূর্ণসংখ্যা হিসাবে বিবেচিত হবে এবং আপনি আউটপুটটিতে কোনও পার্থক্য দেখতে পাবেন না।


এবং তবুও আদিম ভাসমানটি এটির সাথে ভাল কাজ করে বলে মনে হচ্ছে। যে 0.0f == -0.0f। সুতরাং বিভিন্ন আচরণ শুধুমাত্র হয় java.lang.Float
ivant

3
আইআইইই 75৫৪ অনুসারে আইভ্যান্ট, "সাধারণ তুলনা অপারেশনগুলি তবে এনএএনদেরকে বিনা নিয়ন্ত্রিত হিসাবে বিবেচনা করে এবং and0
অ্যান্ডি টার্নার

@ অ্যান্ডি টনার, হ্যাঁ আমি এটি বুঝতে পারি। আমি কেবল ইঙ্গিত করছি যে জাভাতে আদিম ধরণের মধ্যে আচরণের মধ্যে পার্থক্য রয়েছে float, যা এই ক্ষেত্রে আইইইই 7575৫ এর সাথে সামঞ্জস্য করে এবং java.lang.Floatযা তা নয়। সুতরাং বিট উপস্থাপনার মধ্যে পার্থক্যটি এটি ব্যাখ্যা করার জন্য যথেষ্ট নয়।
ivant
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.