সি # তে পূর্ণসংখ্যা বিভাগ কেন পূর্ণসংখ্যা ফেরত দেয় এবং ভাসমান নয়?


131

কেউ কি জানেন যে কেন সি # তে পূর্ণসংখ্যা বিভাগ একটি পূর্ণসংখ্যা দেয় এবং একটি ভাসা না কেন? এর পিছনে কী ধারণা? (এটি কি কেবলমাত্র সি / সি ++ এর উত্তরাধিকার?)

সি # তে:

float x = 13 / 4;   
//== operator is overridden here to use epsilon compare
if (x == 3.0)
   print 'Hello world';

এই কোডের ফলাফল হবে:

'Hello world'

কড়া কথায় বলতে গেলে, পূর্ণসংখ্যা বিভাগের মতো কিছুই নেই (সংজ্ঞা অনুসারে বিভাগ এমন একটি ক্রিয়াকলাপ যা যৌক্তিক সংখ্যা তৈরি করে, পূর্ণসংখ্যার একটি খুব ছোট উপসেট হয়))


46
কারণ এটি integerবিভাজন নয় floating point
হান্টার ম্যাকমিলেন

এটিতে (ভিবি.নেটে) এটি প্রাকৃতিক গাণিতিক উপায়ে ভিন্নভাবে প্রয়োগ করা হয় যেখানে বিভাগ পরিচালনার সমস্ত ফলাফল একটি অযৌক্তিক সংখ্যা।
ব্যান্ডিতোবানি

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

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

উত্তর:


96

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

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

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

এগুলি (এবং অন্যান্য সম্পর্কিত) কারণে, পূর্ণসংখ্যা বিভাগের ফলে পূর্ণসংখ্যার ফলাফল হয়। আপনি যদি দুটি পূর্ণসংখ্যার ভাসমান পয়েন্ট বিভাগ পেতে চান তবে আপনাকে কেবল একটি double/ float/ এ কাস্ট করার কথা মনে রাখতে হবে decimal


5
ভিবি.নেটে। নেট আর্কিটেক্টরা আরও একটি সিদ্ধান্ত নিয়েছিলেন: / - সর্বদা একটি ফ্লোট বিভাগ, \ - পূর্ণসংখ্যা বিভাগ, সুতরাং এটি একধরণের অসঙ্গত, যদি আপনি সি ++ উত্তরাধিকার বিবেচনা করেন;
ব্যান্ডিটোবানি

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

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

8
@ পেলেসেল যেহেতু এটি করা একটি বিশাল ব্রেকিং পরিবর্তন হবে যার জন্য একটি জ্যোতির্বিজ্ঞানের সংখ্যাগরিষ্ঠ প্রোগ্রামগুলি ভেঙে যাবে আমি সম্পূর্ণ আত্মবিশ্বাসের সাথে বলতে পারি যে এটি সি # তে কখনই ঘটবে না। এটি 1 দিনের প্রথম দিন থেকে কোনও ভাষায় করা উচিত বা একেবারেই নয়।
পরিবেশন করুন

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

77

সি # স্পেসিফিকেশন দেখুন । বিভাগ অপারেটর তিন ধরণের আছে

  • পূর্ণসংখ্যা বিভাগ
  • ভাসমান পয়েন্ট বিভাগ
  • দশমিক বিভাগ

আপনার ক্ষেত্রে নিম্নলিখিত বিধি প্রয়োগ সহ আমাদের পূর্ণসংখ্যা বিভাগ রয়েছে:

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

আমি মনে করি যে সি # এই ধরণের বিভাগটি পূর্ণসংখ্যার জন্য ব্যবহার করে (কিছু ভাষাগুলি ভাসমান ফলাফল প্রত্যাবর্তন করে) হার্ডওয়্যার - পূর্ণসংখ্যা বিভাগটি দ্রুত এবং সহজ।


কোন ভাষাগুলি ভাসমান ফলাফল ফেরত দেয়? @ সার্জিবিরেজভস্কি
ইলারিয়ার

40

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

int x = 13;
int y = 4;
float x = (float)y / (float)z;

বা, আপনি যদি আক্ষরিক ব্যবহার করছেন:

float x = 13f / 4f;

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


1
+1 উল্লেখ করার জন্য যে ভাসমান পয়েন্ট বিভাগ তৈরি করতে শুধুমাত্র একটি টার্মের ভাসমান হওয়া প্রয়োজন।
জিনারিজ

স্পষ্টতই নির্ভুলতা সম্পর্কে আপনার বক্তব্যটি শেখার প্রসঙ্গে এবং এটি বুঝতে জটিল হওয়া না তৈরি করার ক্ষেত্রে সঠিক। আমাদের কাজের ক্ষেত্রে যতটা সম্ভব যথাযথ হওয়া দরকার তাই আমি এখনও স্পষ্টতা নিয়ে স্পষ্ট করে বলতে চাই: আইইই 754-1985 অনুসারে আপনি একটি সঠিক ফলাফল পেতে পারেন (যদিও এটি বেশিরভাগ ক্ষেত্রে হয় না)। আপনি একটি সুনির্দিষ্ট ফলাফল পেতে পারেন, যখন গণনার মানগুলি যথাযথভাবে উপস্থাপিত হয়েছিল এবং ফলাফলটি হ'ল - সহজ ভাষায় - 2 এর শক্তির সমষ্টি, যদিও এই বিশেষ ক্ষেত্রে সেই নির্ভুলতার উপর নির্ভর করা ভাল অনুশীলন হতে পারে না।
এল। মন্টি

নির্ভুলতার সাথে সংযোজন: ফলাফল 1 বা -1 এর কাছাকাছি হওয়ায় সঠিক ফলাফল পাওয়ার সম্ভাবনা তাত্পর্যপূর্ণভাবে উন্নত হয়। এটি কিছুটা বিভ্রান্তিকর হতে পারে যে এই সম্ভাব্যতাটি এখনও 0 রয়ে গেছে কারণ এখানে অসীম সংখ্যা এবং সীমাবদ্ধ ফলাফল রয়েছে যা সঠিকভাবে উপস্থাপন করা যেতে পারে। :)
এল মন্টি

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

দশমিকগুলি অনর্থক, একই কারণে যে ভাসমান; এটি কেবলমাত্র ভাসমানগুলি বেস -2 এবং দশমিকগুলি বেস -10 হয়। উদাহরণস্বরূপ, একটি দশমিক প্রকার নির্ভুলভাবে 1/3 এর সঠিক মান ধরে রাখতে পারে না।
স্টিভেন ডগগার্ট

11

যেহেতু আপনি কোনও প্রত্যয় ব্যবহার করেন না, আক্ষরিক 13এবং 4পূর্ণসংখ্যা হিসাবে ব্যাখ্যা করা হয়:

ম্যানুয়াল :

আক্ষরিক কোন প্রত্যয় থাকে, তবে তাতে এই ধরনের যা এর মান প্রতিনিধিত্ব করা যেতে পারে প্রথম আছে: int, uint, long, ulong

সুতরাং, যেহেতু আপনি 13পূর্ণসংখ্যা হিসাবে ঘোষণা করেন, পূর্ণসংখ্যা বিভাগ সম্পাদন করা হবে:

ম্যানুয়াল :

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

পূর্বনির্ধারিত বিভাগ অপারেটরগুলি নীচে তালিকাভুক্ত রয়েছে। অপারেটররা সকলেই x এবং y এর ভাগফল গণনা করে।

পূর্ণসংখ্যা বিভাগ:

int operator /(int x, int y);
uint operator /(uint x, uint y);
long operator /(long x, long y);
ulong operator /(ulong x, ulong y);

এবং সুতরাং গোলাকার ডাউন ঘটে:

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

আপনি যদি নিম্নলিখিতটি করেন:

int x = 13f / 4f;

আপনি একটি সংকলক ত্রুটি পাবেন, যেহেতু একটি ভাসমান-পয়েন্ট বিভাগ ( /অপারেটর 13f) এর ফলে একটি ভাসমান হয়, যা অন্তর্নিহিতভাবে অন্তর্ভুক্ত করা যায় না।

আপনি যদি বিভাগটি একটি ফ্লোটিং পয়েন্ট বিভাগ হতে চান তবে আপনাকে ফলাফলটি একটি ভাসমান হতে হবে:

float x = 13 / 4;

লক্ষ্য করুন যে আপনি এখনও পূর্ণসংখ্যাগুলি বিভক্ত করবেন, যা স্পষ্টতই ভাসতে কাস্ট করা হবে: ফলাফল হবে 3.0fপ্রত্যয়টি ( 13f, 4f) ব্যবহার করে অপারেশনগুলিকে স্পষ্টরূপে ফ্লোট হিসাবে ঘোষণা করতে ।


আপনার কাছে উত্তরটি একটি ভাসমান হিসাবে থাকতে পারে তবে এখনও পূর্ণসংখ্যা বিভাগ করতে পারেন তা বোঝানোর জন্য +1। তদ্ব্যতীত, আমি ভাসমান পয়েন্ট বিভাগকে বাধ্য করার জন্য আর একটি সাধারণ উপায় হ'ল বিভাগের প্রথম মেয়াদকে গুণ করে 1.0
জিনারিজ

8

এটি কেবল একটি প্রাথমিক অপারেশন

মনে রাখবেন কখন আপনি বিভাজন করতে শিখলেন। শুরুতেই আমরা সমাধান করেছি 9/6 = 1 with remainder 3

9 / 6 == 1  //true
9 % 6 == 3 // true

% -Operator এর সাথে সম্মিলিত / -operator এই মানগুলি পুনরুদ্ধার করতে ব্যবহৃত হয়।


6

দরকারী হতে পারে:

double a = 5.0/2.0;   
Console.WriteLine (a);      // 2.5

double b = 5/2;   
Console.WriteLine (b);      // 2

int c = 5/2;   
Console.WriteLine (c);      // 2

double d = 5f/2f;   
Console.WriteLine (d);      // 2.5

দয়া করে আপনার উত্তরের জন্য কিছু ব্যাখ্যা যুক্ত করার চেষ্টা করুন
নেটস্টার্টার

শেষ অভিব্যক্তি উত্পাদন করবে 2.5, না 2
লাসে ভি কার্লসেন

হ্যাঁ, ভুল বানান। ধন্যবাদ।
11:25 এ এজেট করুন

4

ফলাফল সর্বদা টাইপযুক্ত থাকে যার মধ্যে আরও বেশি সংখ্যার এবং ডিনোমিনেটরের পরিসীমা থাকে। ব্যতিক্রমগুলি বাইট এবং সংক্ষিপ্ত, যা int (অন্তর্গত 32) উত্পাদন করে।

var a = (byte)5 / (byte)2;  // 2 (Int32)
var b = (short)5 / (byte)2; // 2 (Int32)
var c = 5 / 2;              // 2 (Int32)
var d = 5 / 2U;             // 2 (UInt32)
var e = 5L / 2U;            // 2 (Int64)
var f = 5L / 2UL;           // 2 (UInt64)
var g = 5F / 2UL;           // 2.5 (Single/float)
var h = 5F / 2D;            // 2.5 (Double)
var i = 5.0 / 2F;           // 2.5 (Double)
var j = 5M / 2;             // 2.5 (Decimal)
var k = 5M / 2F;            // Not allowed

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

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