বাইট + বাইট = ইন… কেন?


365

এই সি # কোডটি দেখছেন:

byte x = 1;
byte y = 2;
byte z = x + y; // ERROR: Cannot implicitly convert type 'int' to 'byte'

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

byte z = (byte)(x + y); // this works

আমি যা ভাবছি তা কেন? এটি কি স্থাপত্যিক? দার্শনিক?

আমাদের আছে:

  • int+ int=int
  • long+ long=long
  • float+ float=float
  • double+ double=double

তাই কেন না:

  • byte+ byte=byte
  • short+ short= short?

কিছুটা পটভূমি: আমি "স্বল্প সংখ্যায়" (অর্থাত্ <8) গণনার দীর্ঘ তালিকা সম্পাদন করছি এবং মধ্যবর্তী ফলাফলগুলি একটি বৃহত অ্যারেতে সংরক্ষণ করছি। বাইট অ্যারে ব্যবহার করা (কোনও int অ্যারের পরিবর্তে) দ্রুত (ক্যাশে হিটগুলির কারণে ) is তবে কোডের মাধ্যমে ছড়িয়ে থাকা বিস্তৃত বাইট-কাস্টগুলি এটিকে আরও বেশি অপঠনযোগ্য করে তুলেছে।



10
এটি এখানে কার্যকর হবে এমন স্ট্যান্ডার্ড সম্পর্কে এরিকের জ্ঞান নয় - এটি ভাষার নকশা সম্পর্কে তাঁর জ্ঞান ; কেন না। তবে হ্যাঁ, এরিকের উত্তরটি বেশ নির্ধারিত হবে :)
জন স্কিটি

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

28
@ এরিক: এটি বাইটের জন্য অনেক অর্থবোধ করে, তবে সংক্ষিপ্ত / ইউএসোর্টের পক্ষে সম্ভবত এতটা বোধগম্য নয়।
জন স্কিটি

23
@ এরিক: এগুলি byte1 | byte2সংখ্যা হিসাবে মোটেও আচরণ করে না। এটি বিটের নিদর্শন হিসাবে তাদের সাথে নিখুঁতভাবে আচরণ করছে। আমি আপনার দৃষ্টিকোণটি বুঝতে পারি, তবে এটি ঠিক তাই ঘটে যায় যে প্রতিবার আমি সি # তে বাইটগুলিতে কোনও পাটিগণিত করেছি, আমি আসলে তাদের সংখ্যা হিসাবে নয়, বিট হিসাবে গণ্য করি এবং এই আচরণটি সর্বদা পথে থাকে।
রোমান স্টারকভ

উত্তর:


228

আপনার কোড স্নিপেটের তৃতীয় লাইন:

byte z = x + y;

আসলে মানে

byte z = (int) x + (int) y;

সুতরাং, বাইটগুলিতে কোনও + অপারেশন নেই, বাইটগুলি প্রথমে পূর্ণসংখ্যায় কাস্ট করা হয় এবং দুটি পূর্ণসংখ্যা যোগ করার ফলাফলটি একটি (32-বিট) পূর্ণসংখ্যা হয়।


আমি নীচে কোড চেষ্টা করেছি তবে এটি এখনও কাজ করছে না। বাইট z = (বাইট) x + (বাইট) y;
বেনামে

10
এটি কারণ বাইটগুলির জন্য কোনও + অপারেশন নেই (উপরে দেখুন)। বাইট z = (বাইট) ((
অন্তর্

35
এটি সবচেয়ে সঠিক এবং সংক্ষিপ্ত উত্তর হতে পারে be বাইটগুলির মধ্যে যোগ করার জন্য কোনও অপারেন্ড নেই, সুতরাং "দুটি বাইট যুক্ত করা" কেন কাজ করে বা না তা ব্যাখ্যা করার পরিবর্তে ( এটি কখনই ঘটেনি ), এটি পরিষ্কারভাবে দেখায় যে ফলাফলটি কোন ইনট কেন, কারণ ঘটে যাওয়া একমাত্র জিনিসটি 2 টি ইনট সংযোজন
রিচার্ডকিকি

2
অন্যান্য উত্তরগুলি পড়ে মিটমিট হয়ে গেলাম (মিঃ জোন স্কিটের কোনও অপরাধ নেই)। এটি আমি সবচেয়ে সহজ উত্তর হিসাবে পেয়েছি যা হুডের নীচে কী চলছে তা সঠিকভাবে বর্ণনা করে। ধন্যবাদ!
রাইরিং

আমি অন্য কোথাও লিখেছি এমন একটি উত্তর যা এই সংকলক-চালিত স্বয়ংক্রিয় প্রচার কখন intঘটছে তা সনাক্ত করার জন্য একটি প্রোগ্রাম রয়েছে : stackoverflow.com/a/43578929/4561887
গ্যাব্রিয়েল স্ট্যাপলস

172

"কেন এটি একেবারেই হয়" এর পরিপ্রেক্ষিতে এটি কারণ অন্যরা যেমন বলেছেন, বাইট, এসবিট, সংক্ষিপ্ত বা ushort সহ পাটিগণিতের জন্য সি # দ্বারা সংজ্ঞায়িত কোনও অপারেটর নেই। এই উত্তরটি কেন এই অপারেটরগুলি সংজ্ঞায়িত হয় না।

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

আমি মনে করি এনোটোটেড সি # মানের একটিতে এটি উল্লেখ করা হয়েছে। অনুসন্ধান করা হচ্ছে ...

সম্পাদনা: বিরক্তিকরভাবে, আমি এখন এ্যানোটেটেড ইসিএমএ সি # 2 স্পেস, এ্যানোটেটেড এমএস সি # 3 স্পেস এবং টীকাগুলি সিএলআই স্পেকটি দেখেছি এবং এর মধ্যে কেউই যতদূর আমি দেখতে পাচ্ছি তা উল্লেখ করেনি । আমি নিশ্চিত যে উপরে বর্ণিত কারণটি আমি দেখেছি তবে আমি কোথায় জানি যদি আমার গা ঘেমে যায়। দুঃখিত, রেফারেন্স ভক্ত :(


14
আমি এটি বলার জন্য দুঃখিত, তবে আমি এটির সেরা উত্তর খুঁজে পাই না।
ভিভিএস

42
আপনি downvoted আছে যে উত্তর আপনি সেরা এক হতে খুঁজে যে? ;)
জন স্কিটি

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

21
আমি শীর্ষে "সেরা" উত্তর পেতে ভোটদানকে একটি সরঞ্জাম হিসাবে ব্যবহার করি। আসলে আমি পেয়েছি আপনি নিজের উত্তরে তেমন কিছু বলেননি যা আমার ডাউনটাইটের মূল কারণ ছিল। ভোট দেওয়ার ক্ষেত্রে আপনার প্রতিনিধি আপনাকে একটি বড় বোনাস দেয় এবং আপনি "আরও ভাল" উত্তরের শীর্ষে পৌঁছে যাচ্ছেন এমন আরও একটি কারণ সম্ভবত আমার বিষয়গত অনুভূতি।
ভিভিএস

23
শীর্ষে "সেরা" উত্তর পাওয়ার সবচেয়ে ভাল উপায় আইএমও তা উজ্জীবিত করা। সত্যি কথা বলতে, আমি মনে করি এখানে সর্বাধিক তথ্যবহুল উত্তর হ'ল প্রশ্নের মধ্যে এরিকের মন্তব্য ... তবে এটির পরিবর্তে ডিজাইনের দৃষ্টিকোণের জন্য ("সংকলক কী করছে" দৃষ্টিভঙ্গির বিপরীতে) আমি মনে করি না অনেক কিছুই আছে "পারফরম্যান্স" এর বাইরে উত্তর দিন। বিশেষত, আমি সত্যিই "এটি ওভারফ্লো প্রতিরোধ করে" যুক্তি (17 ভোট) কিনি না কারণ এটি int + int = দীর্ঘ প্রস্তাব দেয় suggest
জন স্কিটি

68

আমি ভেবেছিলাম আমি এটি আগে কোথাও দেখেছি। এই নিবন্ধ থেকে , ওল্ড নিউ থিং :

মনে করুন আমরা একটি কল্পনাপ্রবণ জগতে বাস করি যেখানে 'বাইট' এর অপারেশনগুলির ফলে 'বাইট' তৈরি হয়েছিল।

byte b = 32;
byte c = 240;
int i = b + c; // what is i?

এই কল্পনার জগতে আমার মান হবে 16! কেন? কারণ + অপারেটরের দুটি অপারেন্ড উভয়ই বাইট, সুতরাং যোগফল "বি + সি" বাইট হিসাবে গণনা করা হয়, যা পূর্ণসংখ্যার ওভারফ্লোর কারণে 16 এ ফলাফল করে। (এবং যেমনটি আমি আগে উল্লেখ করেছি, পূর্ণসংখ্যার ওভারফ্লো হ'ল নতুন সুরক্ষা আক্রমণ আক্রমণকারী))

সম্পাদনা : রেমন্ড মূলত ডি এবং সি ++ এর পদ্ধতির প্রতিরক্ষা করছে। মন্তব্যে, তিনি এই সত্যটিকে সমর্থন করেন যে ভাষা # পশ্চাদপদ সামঞ্জস্যের ভিত্তিতে সি # একই পন্থা গ্রহণ করে।


42
পূর্ণসংখ্যার সাথে যদি আমরা সেগুলি যুক্ত করি এবং এটি উপচে পড়ে এটি স্বয়ংক্রিয়ভাবে এটি আলাদা ডেটাটাইপ হিসাবে কাস্ট করে না তবে এটি বাইট দিয়ে কেন করবেন?
রায়ান

2
Ints দিয়ে এটি উপচে পড়ে। যোগ করার চেষ্টা করুন। ম্যাক্সভ্যালু +1 আপনি 2147483648 এর পরিবর্তে -2147483648 পান
ডেভিড বাসরব

8
@ লংহর্ন213: হ্যাঁ, রায়ান যা বলেছিল তা হল: ইন্ট ম্যাথ গণিত উপচে পড়তে পারে, তবে ইন্ট ম্যাথ দীর্ঘস্থায়ী হয় না।
মাইকেল পেট্রোটা

28
যথাযথভাবে। এটি যদি কোনও সুরক্ষা ব্যবস্থা হিসাবে বোঝানো হয় তবে এটি খুব খারাপভাবে প্রয়োগ করা হয়েছে;)
জন স্কিটি

5
@ রায়ান: আদিম গণিতের মতো মৌলিক জিনিসের জন্য সি # ভাষা ডিজাইনারদের বিরুদ্ধে "অলস" হ'ল একটি দুর্দান্ত মাপকাঠি। আপনি যদি তাদের কোনওরকম অভিযোগ করতে চান তবে এটিকে "সি / সি ++ এর সাথে অতিরিক্ত পিছনের সামঞ্জস্য" করুন।
মাইকেল পেট্রোটা

58

সি শার্প

ইসিএমএ -৩৩৪ বলেছে যে সংযোজনটি কেবলমাত্র ইনট + ইনট, ইউন্ট + ইউিন্ট, লং + লম্বা এবং উলং + উলং (ইসিএমএ -৩৩৪ ১৪..4.৪) হিসাবে বৈধ হিসাবে সংজ্ঞায়িত করা হয়। এই হিসাবে, এগুলি 14.4.2 এর সাথে সম্মানের সাথে বিবেচিত প্রার্থীর ক্রিয়াকলাপ। যেহেতু বাইট থেকে ইনট, ইউিন্ট, লম্বা এবং আলং পর্যন্ত অন্তর্নিহিত কাস্টস রয়েছে, সমস্ত সংযোজন ফাংশন সদস্যরা 14.4.2.1 এর আওতায় প্রযোজ্য ফাংশনের সদস্য। আমাদের 14.4.2.3 এ বিধি দ্বারা সেরা অন্তর্নিহিত কাস্ট সন্ধান করতে হবে:

(সি 1) টু ইন্ট (টি 1) কাস্টিং (সি 2) থেকে ইউন্ট (টি 2) বা উলং (টি 2) এর চেয়ে ভাল কারণ কারণ:

  • যদি টি 1 ইনট হয় এবং টি 2 হ'ল ইউন্ট, বা উলং, সি 1 এর থেকে ভাল রূপান্তর।

Cালাই (সি 1) থেকে ইন্ট (টি 1) ingালাই (সি 2) থেকে দীর্ঘ (টি 2) করার চেয়ে ভাল কারণ সেখানে অন্তর্ থেকে দীর্ঘ পর্যন্ত একটি অন্তর্নিহিত কাস্ট রয়েছে:

  • যদি টি 1 থেকে টি 2 তে অন্তর্নিহিত রূপান্তর বিদ্যমান থাকে এবং টি 2 থেকে টি 1 তে কোনও সংক্রামিত রূপান্তর বিদ্যমান না থাকে তবে সি 1 হ'ল উত্তম রূপান্তর।

সুতরাং int + int ফাংশন ব্যবহার করা হয়, যা কোন int প্রদান করে।

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

CLI

সিএলআই কেবলমাত্র 6 টি ধরণের (ইন্ট 32, নেটিভ ইন্ট, ইনট 64, এফ, ও, এবং) চালিত করে। (ECMA-335 পার্টিশন 3 বিভাগ 1.5)

বাইট (ইনট 8) এই ধরণেরগুলির মধ্যে একটি নয় এবং সংযোজনের আগে স্বয়ংক্রিয়ভাবে একটি int32 এ জোর করা হয়। (ECMA-335 পার্টিশন 3 বিভাগ 1.6)


ইসিএমএ কেবলমাত্র সেই নির্দিষ্ট ক্রিয়াকলাপগুলি নির্দিষ্ট করে যে কোনও ভাষা অন্য নিয়মগুলি প্রয়োগ করতে বাধা দেয় না। VB.NET সহায়কভাবে অনুমতি দেবে byte3 = byte1 And byte2একটি রানটাইম ব্যতিক্রম যদি নিক্ষেপ করা হবে একটি ঢালাই ছাড়া কিন্তু unhelpfully int1 = byte1 + byte2উৎপাদনের 255 ওভার একটি মান আমি যদি থাকে ভাষায় সম্ভব হবে জানি না byte3 = byte1+byte2এবং যখন যে 255 ছাড়িয়ে গেছে একটি ব্যতিক্রম নিক্ষেপ, কিন্তু না একটি ব্যতিক্রম যদি নিক্ষেপ int1 = byte1+byte2উৎপাদনের 256-510 ব্যাপ্তির মান।
সুপারক্যাট

26

কিছু অদক্ষতার পরিচয় দেওয়া উত্তরগুলি বাইট যুক্ত করা এবং ফলাফলকে বাইটে ছাঁটাই করা ভুল। x86 প্রসেসরের 8-বিট পরিমাণে পূর্ণসংখ্যার ক্রিয়াকলাপের জন্য বিশেষভাবে নির্দেশিত নির্দেশাবলী রয়েছে।

প্রকৃতপক্ষে, x86 / 64 প্রসেসরের জন্য, 32-বিট বা 16-বিট ক্রিয়াকলাপ সম্পাদন করা অপারেণ্ড প্রিফিক্স বাইটের কারণে ডিকোড করতে হবে বলে 64-বিট বা 8-বিট অপারেশনগুলির চেয়ে কম দক্ষ। 32-বিট মেশিনে, 16-বিট ক্রিয়াকলাপ সম্পাদন করা একই পেনাল্টির অন্তর্ভুক্ত, তবে এখনও 8-বিট ক্রিয়াকলাপের জন্য ডেডিকেটেড অপকডগুলি রয়েছে।

অনেকগুলি আরআইএসসি আর্কিটেকচারের অনুরূপ স্থানীয় শব্দ / বাইট দক্ষ নির্দেশাবলী রয়েছে। যাঁদের সাধারণত কোনও বিট-দৈর্ঘ্যের কোনও স্টোর এবং রূপান্তর-তে-স্বাক্ষরিত-মান-হয় না।

অন্য কথায়, এই সিদ্ধান্তটি অবশ্যই বাইট ধরণের জন্য কী তা উপলব্ধির উপর ভিত্তি করে করা হয়েছিল, হার্ডওয়্যারের অন্তর্নিহিত অদক্ষতার কারণে নয়।


+1 টি; যদি আমি কখনই স্থানান্তরিত হয়েছি এবং সি # তে দুটি বাইট নিয়ে প্রতিবারই এই ধারণাটি ভুল না হত
রোমান স্টারকভ

ফলাফলটি কাটাতে কোনও কার্যকারিতা ব্যয় করা উচিত নয়। X86 অ্যাসেম্বলিতে এটি কেবলমাত্র রেজিস্ট্রারের বাইরে থেকে একটি বাইট বা চারটি বাইট নিবন্ধকের বাইরে অনুলিপি করার মধ্যে পার্থক্য।
জনাথন অ্যালেন

1
@ জোনাথন অ্যালেন ঠিক বিস্তৃত রূপান্তর সম্পাদন করার সময় কেবল তাত্পর্যপূর্ণভাবেই পার্থক্য । বর্তমান (হয় স্বাক্ষরিত বর্ধিত বা স্বাক্ষরবিহীন প্রসারিত।) নকশা একটি কার্যকারিতা শাস্তি প্রসার নির্দেশ চালানো incurs
reirab

" বাইট প্রকারটি কীসের জন্য তা উপলব্ধি " - এটি byte(এবং char) এর জন্য এই আচরণটি ব্যাখ্যা করতে পারে তবে shortশব্দার্থগতভাবে স্পষ্টভাবে একটি সংখ্যা নয়।
স্মল করে

13

আমার মনে আছে একবার জোন স্কিটের কাছ থেকে কিছু পড়ার পরে (এটি এখন খুঁজে পাচ্ছে না, আমি খুঁজতেই থাকব) কীভাবে বাইট আসলে + অপারেটরটিকে ওভারলোড করে না about প্রকৃতপক্ষে, আপনার নমুনায় দুটি বাইট যুক্ত করার সময়, প্রতিটি বাইটটি প্রকৃতপক্ষে স্পষ্টভাবে একটি ইনটকে রূপান্তরিত হচ্ছে। এর ফলাফল অবশ্যই একটি int হয়। এখন কেন এটি এইভাবে ডিজাইন করা হয়েছিল, আমি নিজেই জন স্কিটি পোস্ট করার জন্য অপেক্ষা করব :)

সম্পাদনা: এটি পাওয়া গেছে! এখানে এই খুব বিষয় সম্পর্কে দুর্দান্ত তথ্য ।


9

এটি ওভারফ্লো এবং বহন করার কারণে।

আপনি যদি দুটি 8 বিট সংখ্যা যুক্ত করেন তবে সেগুলি 9 তম বিটের মধ্যে উপচে পড়তে পারে।

উদাহরণ:

  1111 1111
+ 0000 0001
-----------
1 0000 0000

আমি নিশ্চিত জানি না, কিন্তু আমি মনে করি যে ints, longsআর doublesআরো স্থান দেওয়া হয় কারণ তারা চমত্কার বৃহৎ হিসাবে এটা হয়। এছাড়াও, এগুলি 4 এর গুণক, যা কম্পিউটারগুলি পরিচালনা করার জন্য আরও কার্যকর, কারণ অভ্যন্তরীণ ডেটা বাসের প্রস্থ 4 বাইট বা 32 বিট (64 বিট এখন আরও প্রচলিত হচ্ছে) প্রশস্ত wide বাইট এবং সংক্ষিপ্তটি আরও কিছুটা অদক্ষ, তবে তারা স্থান বাঁচাতে পারে।


23
তবে বৃহত্তর ডেটা ধরণগুলি একই আচরণ অনুসরণ করে না।
ইনিশির

12
উপচে পড়া বিষয়গুলি একপাশে। যদি আপনি নিজের যুক্তিটি গ্রহণ করেন এবং ভাষাতে এটি প্রয়োগ করেন, তবে সমস্ত ডেটা টাইপ সংখ্যক গাণিতিকের পরে আরও বড় ডেটা টাইপ প্রত্যাবর্তন করবে, যা সম্ভবত স্পষ্ট নয়। int + int = int, দীর্ঘ + দীর্ঘ = দীর্ঘ। আমি মনে করি প্রশ্নটি অসঙ্গতি সম্পর্কিত।
জোসেফ

এটি আমার প্রথম চিন্তা ছিল কিন্তু তারপরেও কেন int + int = দীর্ঘ হয় না? সুতরাং আমি "সম্ভাব্য ওভারফ্লো" যুক্তিটি কিনছি না ... এখনও <গ্রিন>।
রবার্ট কার্টেইনো

11
ওহ, এবং "সম্ভাব্য ওভারফ্লো" আর্গুমেন্ট সম্পর্কে, বাইট + বাইট = সংক্ষেপে কেন নয়?
রবার্ট কার্টেইনো

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

5

সি # ভাষার বৈশিষ্ট থেকে 1.6.7.5 7.2.6.2 বাইনারি সংখ্যার প্রচারগুলি এটি উভয় অপারেশনগুলিকে আন্তঃরূপে রূপান্তরিত করে যদি এটি বেশ কয়েকটি অন্যান্য বিভাগে ফিট করে না। আমার অনুমান যে তারা প্যারামিটার হিসাবে বাইট নিতে + অপারেটরটিকে ওভারলোড করেনি তবে এটি কিছুটা স্বাভাবিকভাবে কাজ করতে চায় যাতে তারা কেবল ইনট ডেটা টাইপ ব্যবহার করে।

সি # ভাষা স্পেক


4

আমার সন্দেহ হ'ল সি # আসলে operator+সংজ্ঞায়িতকে কল করছে int(যা intআপনি কোনও checkedব্লকের মধ্যে না থাকলে এটি প্রদান করে) এবং আপনার bytes/ shortsতে উভয়কেই স্পষ্টতই কাস্ট করছে ints। এই কারণেই আচরণটি অসঙ্গত বলে মনে হয়।


3
এটি স্ট্যাকের উপর উভয় বাইট চাপায়, তারপরে এটি "অ্যাড" কমান্ডটি কল করে। আইএল-এ, দুটি মান "খায়" যুক্ত করুন এবং তাদের কোনও int দিয়ে প্রতিস্থাপন করুন।
জোনাথন অ্যালেন

3

ভাষা ডিজাইনারদের পক্ষে এটি সম্ভবত ব্যবহারিক সিদ্ধান্ত ছিল। সর্বোপরি, কোনও int হল একটি আন্ত 32, 32-বিট স্বাক্ষরিত পূর্ণসংখ্যা। আপনি যখনই int এর চেয়ে ছোট কোনও ধরণের ইন্টিজার অপারেশন করেন তখন এটি কোনও 32 বিট সিপিইউ-তে কোনও 32 বিট স্বাক্ষরিত রূপান্তরিত হতে চলেছে। এটি, ছোট ছোট পূর্ণসংখ্যার উপচে পড়ার সম্ভাবনার সাথে মিলিত, সম্ভবত চুক্তিটি সিল করে। এটি আপনাকে অতিরিক্ত / নিম্ন-প্রবাহের জন্য অবিচ্ছিন্নভাবে পরীক্ষা করার কাজ থেকে বাঁচায় এবং যখন কোনও মধ্যবর্তী পর্যায়ে এটি সীমার বাইরে চলে যায় সত্ত্বেও, যখন বাইটগুলিতে কোনও এক্সপ্রেশনের চূড়ান্ত ফলাফলটি সীমার মধ্যে থাকে, আপনি একটি সঠিক পান ফলাফল.

আরেকটি চিন্তা: এই ধরণের ওভার / নিম্ন-প্রবাহকে সিমুলেশন করতে হবে, কারণ এটি সম্ভবত সম্ভাব্য টার্গেট সিপিইউতে প্রাকৃতিকভাবে ঘটে না n't কেন বিরক্ত হও?


2

এটি বেশিরভাগ অংশে আমার উত্তর যা এই বিষয়ের সাথে সম্পর্কিত, এখানে একটি অনুরূপ প্রশ্নের আগে জমা দেওয়া ।

ডিফল্টরূপে গণনার আগে ইন্ট 32 এর চেয়ে কম সংখ্যক অবিচ্ছেদ্য সংখ্যা সহ সমস্ত ক্রিয়াকলাপ 32 বিট পর্যন্ত গোল হয়। ফলাফলটি इंटো 32 হওয়ার কারণটি কেবল গণনার পরে যেমন হয় তেমনি রেখে দেওয়া। আপনি যদি এমএসআইএল গাণিতিক ওপকোডগুলি পরীক্ষা করেন তবে কেবলমাত্র অবিচ্ছেদ্য সংখ্যাসূচক প্রকারের সাথে তারা কাজ করে তা হ'ল ইনট 32 এবং ইন্টার 64। এটি "ডিজাইনের মাধ্যমে"।

আপনি যদি ইন্ট 16 ফর্ম্যাটে ফলাফলটি ফিরে পেতে চান তবে এটি আপেক্ষিক নয় যদি আপনি কোডটিতে কাস্ট সম্পাদন করেন বা সংকলক (অনুমানমূলক) "হুডের নীচে" রূপান্তরটি প্রকাশ করে।

উদাহরণস্বরূপ, Int16 গাণিতিক করতে:

short a = 2, b = 3;

short c = (short) (a + b);

দুটি সংখ্যা 32 বিট পর্যন্ত প্রসারিত হবে, যুক্ত হবে, তারপরে 16 বিটের মধ্যে ছাঁটা হবে, এমএস এটি কীভাবে এটি করতে চেয়েছিল।

সংক্ষিপ্ত (বা বাইট) ব্যবহারের সুবিধাটি মূলত আপনার ক্ষেত্রে প্রচুর পরিমাণে ডেটা (গ্রাফিকাল ডেটা, স্ট্রিমিং ইত্যাদি) সঞ্চিত থাকে storage


1

সংযোজন বাইট জন্য সংজ্ঞায়িত করা হয় না। সুতরাং তারা সংযোজন জন্য কাস্ট হয়। বেশিরভাগ গণিত ক্রিয়াকলাপ এবং বাইটের ক্ষেত্রে এটি সত্য। (নোট করুন এটি কীভাবে এটি প্রাচীন ভাষাগুলিতে ব্যবহৃত হত, আমি ধরে নিচ্ছি যে এটি আজ সত্য hold


0

আমি মনে করি এটি একটি ডিজাইনের সিদ্ধান্ত নিয়েছে যার ক্রিয়াকলাপটি আরও সাধারণ ছিল ... বাইট + বাইট = বাইট যদি সম্ভবত ফলাফলের জন্য কোনও ইন্টিরিটি আবশ্যক হয় তখন আরও বেশি মানুষ ইনট কাস্ট করার দ্বারা বিরক্ত হবে।


2
আমি একবারে অন্যভাবে বিরক্ত হয়েছি :) আমার সর্বদা বাইট ফলাফলের প্রয়োজন বলে মনে হয়, তাই আমাকে সর্বদা নিক্ষেপ করতে হবে।
রোমান স্টারকভ

ব্যতীত আপনাকে ইনট এ কাস্ট করতে হবে না। Castালাই অন্তর্নিহিত। কেবল অন্য উপায়টি স্পষ্ট।
নিকি

1
@ নিকি আমার মনে হয় আপনি আমার উত্তরটি বুঝতে পারেন নি। যদি দুটি বাইট যুক্ত করা একটি বাইট তৈরি করে, অতিরিক্ত প্রবাহ রোধ করার জন্য কাউকে সংযোজনের পূর্বে অপারেন্ডগুলি (ফলাফল নয়) নিক্ষেপ করতে হবে ।
ফরট্রান

0

.NET ফ্রেমওয়ার্ক কোড থেকে:

// bytes
private static object AddByte(byte Left, byte Right)
{
    short num = (short) (Left + Right);
    if (num > 0xff)
    {
        return num;
    }
    return (byte) num;
}

// shorts (int16)
private static object AddInt16(short Left, short Right)
{
    int num = Left + Right;
    if ((num <= 0x7fff) && (num >= -32768))
    {
        return (short) num;
    }
    return num;
}

সহজতর করা.NET 3.5 এবং উপরের সাথে :

public static class Extensions 
{
    public static byte Add(this byte a, byte b)
    {
        return (byte)(a + b);
    }
}

এখন আপনি করতে পারেন:

byte a = 1, b = 2, c;
c = a.Add(b);


0

আমি বাইট এবং int এর মধ্যে পারফরম্যান্স পরীক্ষা করেছি।
ইনট মান সহ:

class Program
{
    private int a,b,c,d,e,f;

    public Program()
    {
        a = 1;
        b = 2;
        c = (a + b);
        d = (a - b);
        e = (b / a);
        f = (c * b);
    }

    static void Main(string[] args)
    {
        int max = 10000000;
        DateTime start = DateTime.Now;
        Program[] tab = new Program[max];

        for (int i = 0; i < max; i++)
        {
            tab[i] = new Program();
        }
        DateTime stop = DateTime.Now;

        Debug.WriteLine(stop.Subtract(start).TotalSeconds);
    }
}

বাইট মান সহ:

class Program
{
    private byte a,b,c,d,e,f;

    public Program()
    {
        a = 1;
        b = 2;
        c = (byte)(a + b);
        d = (byte)(a - b);
        e = (byte)(b / a);
        f = (byte)(c * b);
    }

    static void Main(string[] args)
    {
        int max = 10000000;
        DateTime start = DateTime.Now;
        Program[] tab = new Program[max];

        for (int i = 0; i < max; i++)
        {
            tab[i] = new Program();
        }
        DateTime stop = DateTime.Now;

        Debug.WriteLine(stop.Subtract(start).TotalSeconds);
    }
}

এখানে ফলাফল:
বাইট: 3.57s 157mo, 3.71s 171mo, 3.74s 168mo সহ সিপিইউ ~ = 30%
ইনট্রি: 4.05 এস 298 মিমি, 3.92 এস 278 মিমি, সিপিইউ সহ 4.28 294 ম ~ = 27%
উপসংহার:
বাইটটি আরও সিপিইউ ব্যবহার করুন তবে এটি কম মেমোরি ব্যয় করে এবং এটি দ্রুত (সম্ভবত বরাদ্দ করার জন্য কম বাইট থাকায়)


-1

অন্যান্য সমস্ত দুর্দান্ত মন্তব্য ছাড়াও, আমি ভেবেছিলাম আমি একটি সামান্য জোয়ার যোগ করব। অনেকগুলি মন্তব্য আশ্চর্য হয়ে গেছে যে কোনও দীর্ঘ সংখ্যক টাইপও কেন এই নিয়মটি অনুসরণ করে না ... গাণিতিকের প্রতিক্রিয়ায় একটি "বৃহত্তর" প্রকারটি ফেরত দেয়।

পারফরম্যান্সের সাথে প্রচুর জবাব দিতে হয়েছে (ভাল, 32 বীট 8 বিটের চেয়ে দ্রুত হয়)। বাস্তবে, একটি 8 বিট নম্বর এখনও 32 বীট সিপিইউতে 32 বিবিট নম্বর .... আপনি যদি দুটি বাইট যোগ করেন, সিপিইউ পরিচালিত ডেটার বিভাজন নির্বিশেষে 32 বিট হতে চলেছে ... সুতরাং ইনট যুক্ত করা যাচ্ছে না দুটি বাইট যোগ করার চেয়ে যে কোনও "দ্রুত" হোন ... সিপিইউতে এটি সমস্ত একইরকম। এখনই, দুটি ইন্ট যুক্ত করা 32 বিট প্রসেসরে দুটি লম্বা যোগ করার চেয়ে দ্রুত হবে, কারণ প্রসেসরের শব্দের চেয়ে আরও বৃহত্তর সংখ্যার সাথে আপনি কাজ করছেন বলে দুটি লম্বা যুক্ত করার জন্য আরও মাইক্রোপ দরকার।

আমি মনে করি বাইট গাণিতিকের কারণ হিসাবে ইনটসের ফলস্বরূপ হ'ল মৌলিক কারণটি বেশ পরিষ্কার এবং সোজা সামনে: 8 বিট কেবল খুব বেশি দূরে যায় না! : ডি 8 বিট সহ, আপনার 0-255 এর স্বাক্ষরযুক্ত স্বাক্ষর রয়েছে। তা নয় পুরোপুরি কাজ করার মতো জায়গা ... পাটিগণিতের ক্ষেত্রে ব্যবহার করার সময় আপনি বাইটস সীমাবদ্ধতার মধ্যে চলে যাবেন এমন সম্ভাবনা খুব বেশি। যাইহোক, ইনটস, বা লম্বা, বা ডাবল ইত্যাদির সাথে কাজ করার সময় আপনি যে বিটগুলি সরিয়ে চলেছেন তা উল্লেখযোগ্যভাবে কম ... যথেষ্ট কম যে আমাদের খুব কমই বেশি প্রয়োজনের মুখোমুখি হয়।

বাইট থেকে ইনট এ স্বয়ংক্রিয় রূপান্তরটি যৌক্তিক কারণ বাইটের স্কেল এত ছোট। Int থেকে দীর্ঘ, ভাসমান দ্বিগুণ ইত্যাদিতে স্বয়ংক্রিয় রূপান্তর যুক্তিসঙ্গত নয় কারণ এই সংখ্যার উল্লেখযোগ্য স্কেল রয়েছে।


এটি এখনও কেন ব্যাখ্যা দেয় না যে তারা কীভাবে byte - byteফিরে আসে intবা কেন তারা কাস্ট করে না short...
KthProg

বিয়োগের চেয়ে আলাদা ধরণের ফিরিয়ে দেওয়ার জন্য আপনি সংযোজনটি কেন চান? যদি byte + byteরিটার্ন আসে int, কারণ 255 + কিছু বাইট হ'ল তার চেয়ে বড় যা বাইট মাইনাস থেকে অন্য কোনও বাইটকে রিটার্ন টাইপের ধারাবাহিকতা দৃষ্টিকোণ থেকে কোন int ছাড়া অন্য কোনও কিছু পাওয়া যায় না।
জ্রিস্টা

আমি করব না, এটি কেবল দেখায় যে উপরের কারণটি সম্ভবত সঠিক নয়। যদি ফলাফলটিতে "ফিটিং" এর সাথে এটি করতে হয়, তবে byteবিয়োগটি আবার ফিরে আসবে byteএবং বাইট সংযোজন একটি short( byte+ byteসর্বদা একটিতে মাপসই হবে short) ফিরে আসবে । এটি যদি আপনি বলে মত ধারাবাহিকতা নিয়ে থাকে shortতবে তারপরেও উভয় ক্রিয়াকলাপের জন্য যথেষ্ট int। স্পষ্টত কারণগুলির একটি মিশ্রণ রয়েছে, এগুলি সবগুলিই অগত্যা সুচিন্তিত নয়। বা, নীচে প্রদত্ত পারফরম্যান্সের কারণটি আরও সঠিক হতে পারে।
KthProg
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.