عد

عدد صحیح در C#

7 تمرین

درباره‌ی عدد صحیح

C# مانند بسیاری از زبان‌های دارای سیستم نوع ایستا، چندین نوع را برای نمایش اعداد صحیح ارائه می‌دهد که هر کدام محدوده‌ی مقادیر خود را دارند. در پایین‌ترین سر این طیف، نوع sbyte کمینه‌ای برابر -128 و بیشینه‌ای برابر 127 دارد. مانند همه‌ی انواع عدد صحیح، این مقادیر در قالب <type>.MinValue و <type>.MaxValue در دسترس‌اند. در بالاترین سر طیف، نوع long کمینه‌ای برابر -9,223,372,036,854,775,808 و بیشینه‌ای برابر 9,223,372,036,854,775,807 دارد و میان این دو، نوع‌های short و int قرار می‌گیرند.

هر یک از نوع‌های بالا یک معادل بدون علامت هم دارد: sbyte/byte، short/ushort، int/uint و long/ulong. در همه‌ی این موارد، محدوده‌ی مقادیر از صفر تا دو برابر بیشینه‌ی علامت‌دار منفی به‌علاوه‌ی یک است.

مقادیر نوع‌های عدد صحیح بدون علامت با یک نمایش ساده‌ی مبنای ۲ نشان داده می‌شوند. مقادیر نوع‌های علامت‌دار از نمایش اعداد علامت‌دار با متمم ۲ استفاده می‌کنند.

وجود این تعداد زیاد نوع عدد صحیح، بازتاب‌دهنده‌ی معماری ماشین‌هاست: اندازه‌ی رجیسترها، اندازه‌ی آرگومان‌های دستورالعمل‌های CPU و نحوه‌ی برخورد با علامت در CPU. یک مقدار از نوع long از ۶۴ بیت استفاده می‌کند، در حالی که یک مقدار از نوع sbyte ۸ بیت است. در برخی موارد این موضوع بر کارایی CPU، مصرف حافظه و حتی مصرف دیسک تأثیر می‌گذارد (انتخاب یک نوع عدد صحیح کوچک‌تر معمولاً به‌صرفه‌تر است). انتخاب type عدد صحیح می‌تواند راهی سرانگشتی هم باشد برای انتقال اطلاعات به سایر توسعه‌دهنده‌ها درباره‌ی محدوده‌ی مقادیر مورد انتظار. نوع int به‌طور گسترده به‌عنوان نوع پیش‌فرض به کار می‌رود، یعنی جایی که ویژگی خاصی درباره‌ی کاربرد مورد نظر شناسایی نشده است. از long یا ulong هم به‌طور گسترده به‌عنوان یک شناسه‌ی ساده استفاده می‌شود. اندازه‌ی نوع بر حسب بایت، محدوده‌ی مقادیر را تعیین می‌کند.

نوع‌هایی که تا اینجا بحث شدند، انواع اولیه هستند. هر کدام از آن‌ها یک نام مستعار struct دارد که فیلدها (مانند MinValue) و متدها (مانند ToString()) مرتبط با آن نوع را پیاده‌سازی می‌کند.

نوع ساختار عرض کمینه بیشینه
sbyte SByte ۸ بیت -128 +127
short Int16 ۱۶ بیت -32_768 +32_767
int Int32 ۳۲ بیت -2_147_483_648 +2_147_483_647
long Int64 ۶۴ بیت -9_223_372_036_854_775_808 +9_223_372_036_854_775_807
byte Byte ۸ بیت 0 +255
ushort UInt16 ۱۶ بیت 0 +65_535
uint UInt32 ۳۲ بیت 0 +4_294_967_295
ulong UInt64 ۶۴ بیت 0 +18_446_744_073_709_551_615

تبدیل نوع

یک متغیر (یا عبارت) از یک نوع را می‌توان به‌راحتی به نوع دیگری تبدیل کرد. برای نمونه، در یک عمل انتساب، اگر نوع مقداری که انتساب داده می‌شود (سمت راست، rhs) تضمین کند که آن مقدار در محدوده‌ی نوع مقصد (سمت چپ، lhs) جا می‌شود، آن‌گاه یک انتساب ساده کافی است:

ulong ul;
uint ui = uint.MaxValue;
ul = ui;    // no problem

از طرف دیگر، اگر محدوده‌ی نوع مبدأ زیرمجموعه‌ای از محدوده‌ی مقادیر نوع مقصد نباشد، آن‌گاه حتی اگر مقدار خاص مورد نظر در محدوده‌ی مقصد قرار داشته باشد، به یک عمل تبدیل نوع () نیاز است:

uint ui;
short s = 42;
ui = (uint)s;

در مثال بالا، اگر آن مقدار به‌جای این بیرون از محدوده‌ی مقصد قرار می‌گرفت، سرریز رخ می‌داد. به overflow مراجعه کنید.

لزوم تبدیل نوع بر اساس دو نوع درگیر تعیین می‌شود، نه بر اساس یک مقدار خاص.

پاراگراف‌های زیر به تبدیل نوع انواع عدد صحیح می‌پردازند. (به casting مراجعه کنید) که بحث گسترده‌تری درباره‌ی تبدیل نوع و تبدیل داده ارائه می‌دهد. برای بحث درباره‌ی تبدیل بین انواع عدد صحیح و اعداد اعشاری، char و bool، به همان مستندات مراجعه کنید.

تبدیل انواع اولیه، ضمنی

سیستم نوع C# تا حدی سخت‌گیرانه‌تر از سیستم نوع C یا Javascript است و در نتیجه، عمل‌های تبدیل نوع محدودترند. تبدیل نوع ضمنی بین دو نوع عددی رخ می‌دهد، به‌شرطی که نوع «مقصد» بتواند مقیاس و علامت مقدار نوع «مبدأ» را حفظ کند.

تبدیل نوع ضمنی با هیچ نحوه‌ی نگارش خاصی نشان داده نمی‌شود.

تبدیل انواع اولیه، صریح

جایی که نوع‌های عددی را نمی‌توان به‌صورت ضمنی تبدیل کرد، معمولاً می‌توانید از عملگر تبدیل نوع صریح استفاده کنید.

اگر نوع مقصد نتواند مقدار در حال تبدیل را نمایش دهد، چون به‌اندازه‌ی کافی بزرگ نیست یا تعارض علامت وجود دارد، ممکن است استثنای سرریز پرتاب شود.

تبدیل انواع اولیه، مثال‌ها
int largeInt = Int32.MaxValue;
int largeNegInt = Int32.MinValue;
ushort shortUnsignedInt = ushort.MaxValue;

// implicit cast
int from_ushort = shortUnsignedInt;          // 65535
float from_int = largeInt;                   // -21474836E+09

// explicit cast
uint from_largeInt = (uint)largeInt;         // 2147483647
uint from_neg = (uint) largeNegInt;          // 2147483648 or OverflowException is thrown (if checked)

تبدیل بیت

کلاس BitConverter روشی راحت برای تبدیل نوع‌های عدد صحیح به آرایه‌های بایت و برعکس فراهم می‌کند.

منابع
ویرایش از طریق GitHub این پیوند در پنجره یا زبانه‌ی جدیدی باز می‌شود

عدد صحیح را یاد بگیرید

تمرین کردن قفل شده است

برای تمرین عدد صحیح قفل 5 تمرین دیگر را باز کنید