این تمرین رفتار انواع مختلف عددی را هنگام سرریز نشان میدهد؛ یعنی زمانی که ظرفیتشان برای نگهداشتن مقداری که از محاسبهای مانند یک عمل حسابی یا تبدیل نوع حاصل میشود کافی نیست.
byte، ushort، uint، ulong) به صفر دور میزنند (بیشترین مقدار نوع بهعلاوهی ۱ به عنوان پیمانه عمل میکند)، مگر آنکه به طور کلی درون یک بلوک checked قرار بگیرند که در آن صورت نمونهای از OverflowException پرتاب میشود. int و long هم رفتار مشابهی دارند، با این تفاوت که به ترتیب به int.MinValue و long.minValue دور میزنند.int one = 1;
checked
{
int expr = int.MaxValue + one; // overflow exception is thrown
}
// or
int expr2 = checked(int.MaxValue + one); // overflow exception is thrown
checked فقط به عبارتهایی اعمال میشود که مستقیماً درون بلوک هستند. وضعیتهای سرریز در توابع فراخوانیشده گرفته نمیشوند.float و double به وضعیتی به نام بینهایت درمیآیند که میتوان آن را با float.IsInfinity() و موارد مشابه آزمایش کرد.double d = double.MaxValue;
d *= 2d;
Double.IsFinite(d)
// => false
decimal باعث پرتاب نمونهای از OverflowException میشوند.unchecked برای مواقعی وجود دارد که میخواهید اثر unchecked را درون یک بلوک checked خنثی کنید یا زمانی که تنظیم کامپایلر به کار رفته است.سرریزهایی که بدون پرتاب «استثنا» رخ میدهند میتوانند مشکلساز باشند، چون به طور کلی هرچه زودتر بتوان یک وضعیت خطا را گزارش کرد، بهتر است.
مشکلات سرریز در int و float را میتوان با انتساب نتیجه به متغیری از نوع long، decimal یا double کاهش داد.
اگر اعداد صحیح بزرگ برای کدتان ضروریاند، استفاده از نوع BigInteger یک گزینه است.
طبیعتاً مواقعی هم هست که دور زدن یک عدد صحیح مجاز است، به ویژه در مورد مقادیر بدون علامت. نمونهی کلاسیک آن کدهای هش است که از عرض عدد صحیح به عنوان نوعی پیمانه استفاده میکنند.
معمولاً در کدبیسها میبینید که وقتی uint یا ulong به عنوان شناسه به کار میرود، غالباً بررسیای انجام نمیشود، چون ارزش دردسرش را ندارد. این موضوع در جایی هم صدق میکند که از دامنهی مسئله روشن است که مقادیر خیلی بزرگ پیش نخواهد آمد. اما برای عبرت این را ببینید.