দ্বিগুণ হিসাবে নির্ধারিত হওয়ার পরে কেন দুটি ইন্টি বিভাজনে সঠিক মান পাওয়া যায় না?


110

নীচের স্নিপেটে এটি কীভাবে আসে

int a = 7;
int b = 3;
double c = 0;
c = a / b;

cযেমনটি প্রত্যাশা করা হয় তেমনি ২.৩৩৩৩ এর পরিবর্তে মান ২ থাকা শেষ করে। যদি aএবং bডাবল হয় তবে উত্তরটি ২.৩৩৩ এ পরিণত হবে। তবে অবশ্যই কারণ এটি c ইতিমধ্যে একটি ডাবল এটি পূর্ণসংখ্যার সাথে কাজ করা উচিত ছিল?

তাহলে কীভাবে int/int=doubleকাজ হয় না?


উত্তর:


161

এটি কারণ আপনি ইন্টিজার বিভাগের সংস্করণটি ব্যবহার করছেন operator/যা 2 intটি সময় নেয় এবং একটি প্রদান করে intdoubleসংস্করণটি ব্যবহার করতে , যা একটি দেয় double, কমপক্ষে একটির intস্পষ্টভাবে একটিতে কাস্ট করতে হবে double

c = a/(double)b;

9
আমি সুস্পষ্টভাবে উভয়কে রূপান্তর করতে aএবং কেবল স্বচ্ছতার জন্য পছন্দ করতে চাই , তবে এটি আসলে কোনও ব্যাপার নয়। bdouble
জন ডিবলিং

31
যেহেতু প্রশ্নটি সি ++ ট্যাগ করা হয়েছে আমি সি কাস্টের চেয়ে স্ট্যাটিক_কাস্ট <> দেখতে পছন্দ করব।
মার্টিন ইয়র্ক

16
ব্যক্তিগতভাবে, আমি অনুভব করি যে সি স্টাইলের বর্ণগুলি আরও পরিষ্কার (বেশিরভাগ সাধারণ ভাষায় কাস্টিং সি স্টাইল পদ্ধতিতে করা হয়)। static_cast<>সবসময় আমার কাছে দীর্ঘ বায়ু মনে হয়েছিল। আদিমদের ক্ষেত্রে, বাস্তবে মিশে যাওয়া static_cast<>এবং reinterpret_cast<>মিশে যাওয়ার কোনও আশঙ্কা নেই ।
চাদ লা গার্ডিয়া

6
@ টাক্স-ডি: পাটিগণিতের জন্য? আমি static_castএই ক্ষেত্রে এড়াতে পছন্দ করব এবং পরিবর্তে সি-স্টাইলের কাস্ট ব্যবহার করব। এখানে সি ++ - স্টাইলের কাস্ট ব্যবহার করার কোনও সুবিধা নেই এবং তারা কোডটি সি-স্টাইলের ক্যাসেটের চেয়ে অনেক বেশি বিশৃঙ্খলা করে। গাণিতিক castালাই হুবহু প্রসঙ্গ যেখানে সি-স্টাইলের ক্যাসেটগুলি যথাযথভাবে উপযুক্ত এবং অন্যান্য জাতির তুলনায় আসলে আরও উপযুক্ত more
এন্টি

19
কখনও কখনও আপনি লেখার মাধ্যমে "নো সি-স্টাইল-কাস্ট" ভাবেনকেও ছাড়িয়ে যেতে পারেন double(b)। তারা সর্বদা উপলব্ধি করে না যে এটি একটি রূপান্তর, কারণ এটি সুস্পষ্ট নির্মাতাদের কল হিসাবে একই দেখায়।
স্টিভ জেসপ

12

এটা এখানে:

ক) দু'ভাগে intবিভাজন সর্বদা পূর্ণসংখ্যা বিভাগ সম্পাদন করে। সুতরাং a/bআপনার ক্ষেত্রে ফলাফল শুধুমাত্র একটি হতে পারে int

আপনি রাখতে চান aএবং bযেমন intS, এখনো তাদের সম্পূর্ণরূপে ভাগ, আপনি দ্বিগুণ তাদের অন্তত এক নিক্ষেপ করতে হবে: (double)a/bবা a/(double)bবা (double)a/(double)b

খ) cহ'ল একটি double, সুতরাং এটি অ্যাসিগিনমেন্টের কোনও মান গ্রহণ করতে পারে int: intস্বয়ংক্রিয়ভাবে রূপান্তরিত হয় doubleএবং এতে নির্ধারিত হয় c

গ) ডানদিকে অভিব্যক্তি মনে রাখবেন যে assignement উপর =নির্ণয় করা হয় প্রথম উপরে (নিয়ম (ক অনুযায়ী), এবং বাঁদিকে ভেরিয়েবলের ব্যাপারে ছাড়া =) এবং তারপর বাম এর পরিবর্তনশীল নির্ধারিত =(অনুযায়ী ( খ) উপরে)। আমি বিশ্বাস করি এটি চিত্র সম্পূর্ণ করে।


11

খুব অল্প ব্যতিক্রম (আমি কেবল একটি সম্পর্কে ভাবতে পারি) দিয়ে, সি ++ এক্সপ্রেশন থেকেই তার একটি অভিব্যক্তির পুরো অর্থ (বা উপ-প্রকাশ) নির্ধারণ করে। আপনি এক্সপ্রেশন ফলাফল সঙ্গে কি করবেন তা বিবেচ্য নয়। আপনার ক্ষেত্রে, অভিব্যক্তিতে a / b, এখানে কোনও doubleদর্শন নেই; সব কিছু int। সুতরাং সংকলকটি পূর্ণসংখ্যা বিভাগ ব্যবহার করে। কেবলমাত্র একবার এর ফলাফল পেলে এটি এর সাথে কী করবে তা বিবেচনা করে এবং এতে রূপান্তর করে double


3
পয়েন্টার নেওয়ার সময় আমি যে ব্যতিক্রমটির কথা ভাবতে পারি তা হ'ল ফাংশন ওভারলোড চয়ন করা - &funcnameআপনি কী ধরণের এটিকে ফেলেছেন তার মান নির্ভর করে।
স্টিভ জেসোপ

2
@ স্টিভ জেসোপ এটিই কেবল ব্যতিক্রম I (তবে স্ট্যান্ডার্ডের আকার এবং জটিলতা দেখে আমি শপথ করতে চাই না যে আমি
কোনওটিই

6

cএকটি doubleপরিবর্তনশীল, তবে এর জন্য নির্ধারিত intমানটি একটি মান কারণ এটি দুটি intএর বিভাজন থেকে ফলাফল , যা আপনাকে "পূর্ণসংখ্যা বিভাগ" দেয় (বাকী অংশটি বাদ দেয়)। তাই সেখানে কি ঘটছে লাইন c=a/bহয়

  1. a/b একটি অস্থায়ী টাইপ তৈরি করে মূল্যায়ন করা হয় int
  2. অস্থায়ী মান cটাইপ রূপান্তর পরে নির্ধারিত হয় double

মানটি a/bতার প্রসঙ্গে (অ্যাসাইনমেন্ট double) উল্লেখ না করে নির্ধারিত হয় ।


6

আপনি যখন দুটি পূর্ণসংখ্যা ভাগ করেন, ফলাফলটি একটি পূর্ণসংখ্যার হতে পারে, নির্বিশেষে আপনি এটি একটি দ্বিগুণ রেখেছেন।


5

সি ++ ভাষায় স্যুবএক্সপ্রেসিসনের ফলাফল কখনই পার্শ্ববর্তী প্রসঙ্গে (কিছু বিরল ব্যতিক্রম সহ) প্রভাবিত হয় না। ভাষাটি সাবধানতার সাথে অনুসরণ করে এমন একটি নীতি। এক্সপ্রেশন c = a / bএকটি স্বতন্ত্র এক্সপ্রেসশন ধারণ করে a / b, যা যে subexpression বাইরের কিছু থেকে স্বাধীনভাবে ব্যাখ্যা করা হয়। ভাষাটি পরোয়া করে না যে আপনি পরে ফলাফলটি একটিতে নির্ধারণ করবেন doublea / bএকটি পূর্ণসংখ্যা বিভাগ অন্য যে কোনও কিছুতেই কিছু যায় আসে না। আপনি ভাষা নীতিটির বিভিন্ন কোণে এই নীতিটি অনুসরণ করবেন। এটি সি ++ (এবং সি) কীভাবে কাজ করে তা হ'ল।

আমি উপরে বর্ণিত একটি ব্যতিক্রমের একটি উদাহরণ হ'ল ফাংশন ওভারলোডিংয়ের পরিস্থিতিতে ফাংশন পয়েন্টার অ্যাসাইনমেন্ট / ইনিশিয়েশন

void foo(int);
void foo(double);

void (*p)(double) = &foo; // automatically selects `foo(fouble)`

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


4

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


2

এটি প্রযুক্তিগতভাবে একটি ভাষা-নির্ভর, তবে প্রায় সমস্ত ভাষাই এই বিষয়টিকে একই রকম মনে করে। যখন একটি অভিব্যক্তিতে দুটি ডেটা ধরণের মধ্যে কোনও প্রকারের অমিল থাকে, তখন বেশিরভাগ ভাষা =পূর্বনির্ধারিত নিয়মের একটি সেট অনুসারে অপরদিকে ডেটা মেলানোর জন্য একদিকে ডেটা কাস্ট করার চেষ্টা করবে ।

একই ধরণের দুটি সংখ্যার বিভাজন করার সময় (পূর্ণসংখ্যা, ডাবলস ইত্যাদি) ফলাফল সর্বদা একই ধরণের হবে (সুতরাং 'অন্তর্নিহিত / অন্তর্নিহিত' সর্বদা ইন্টের ফলস্বরূপ)।

double var = integer result এক্ষেত্রে আপনার কাছে কোনটি পূর্বে পূর্ণসংখ্যার ফলাফল গণনার পরে দ্বিগুণ হয়ে যায় যার ক্ষেত্রে ভগ্নাংশের ডেটা ইতিমধ্যে হারিয়ে যায়। (বেশিরভাগ ভাষাগুলি কোনও ব্যতিক্রম বা ত্রুটি না বাড়িয়ে ধরণের ভুল-ত্রুটি রোধ করতে এই castালাইটি করবে)।

আপনি যদি ফলাফলটিকে দ্বিগুণ হিসাবে রাখতে চান তবে আপনার নিজের মতো পরিস্থিতি তৈরি করতে চান double var = double result

এটি করার সবচেয়ে সহজ উপায় হ'ল সমীকরণের ডান পাশে অভিব্যক্তিটি দ্বিগুণ করতে বাধ্য করা:

c = a/(double)b

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

উজানের পরে, aদ্বিগুণ হিসাবে বাতাস চলবে এবং এখন আপনার দ্বিগুণের মধ্যে বিভাগ রয়েছে। এটি পছন্দসই বিভাগ এবং অ্যাসাইনমেন্ট তৈরি করবে।

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


এই প্রশ্নটিকে [সি ++] ট্যাগ করা হয়েছে এবং সি ++ স্ট্যান্ডার্ড ঠিক কীভাবে এটি কাজ করে তা নির্দেশ করে। "ভাষা নির্দিষ্ট" দ্বারা আপনি কী বোঝেন তা নিশ্চিত নন এবং এটি অবশ্যই সংকলক-নির্দিষ্ট নয়, অনুমান করে যে কোনও সংকলক বর্ধিত অংশ নিযুক্ত নেই।
জন ডিবলিং

এছাড়াও এটি বলাও ভুল যে "ডাবল ভার = পূর্ণসংখ্যার ফলাফল যা ডাবল ভেরিটকে ইনট পর্যন্ত ফেলে"। ডাবল একটি int- এ কাস্ট করা হয় না। ইন্ট রেজাল্টটি ডাবলে রূপান্তরিত হয়।
জন ডিবলিং

আমি সংকলক এক্সটেনশনের সম্ভাবনার জন্য অনুমতি দিচ্ছিলাম (আমার পরিবেশটি "ভুল-কাস্টিং" ফলাফলের ফলাফল হয়েছিল এবং আমি কেন এটি বুঝতে পারি না) এবং ফলাফল ভাষা নির্দিষ্ট যেমন কিছু ভাষায় একই কাস্টিং বিধি অনুসরণ করে না। আমি বিবেচনা করি নি যে এটি একটি সি ++ নির্দিষ্ট ট্যাগ। আপনি "ডাবল ভার = পূর্ণসংখ্যার ফলাফল" মন্তব্য সম্পর্কে ঠিক বলেছেন। যে প্রতিফলিত সম্পাদিত। ধন্যবাদ!
ম্যাথেজুদ্দনাম

0

গুরুত্বপূর্ণ জিনিস হ'ল গণনার অন্যতম উপাদান হ'ল ফ্লোট-ডাবল টাইপ। তারপরে ডাবল ফলাফল পেতে আপনাকে এই উপাদানটি নীচের মত দেখাচ্ছে:

c = static_cast<double>(a) / b;

বা সি = এ / স্ট্যাটিক_কাস্ট (খ);

অথবা আপনি এটি সরাসরি তৈরি করতে পারেন ::

c = 7.0 / 3;

নোট করুন যে গণনার একটি উপাদানের একটি পূর্ণসংখ্যার দ্বারা ভাসা-দ্বৈত প্রকারের বিভাগ নির্দেশ করতে অবশ্যই '.0' থাকতে হবে। অন্যথায়, সি ভেরিয়েবলটি দ্বিগুণ হওয়া সত্ত্বেও ফলাফলটিও শূন্য হবে।


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