برای به دست آوردن بیشترین مقدار uint256 در سالیدیتی، میتوان از عبارت type(uint256).max
استفاده کرد. مقدار خروجی این عبارت به صورت زیر است:
1 |
115792089237316195423570985008687907853269984665640564039457584007913129639935 |
یا به زبان ریاضی معادل 2^256 - 1
خواهد بود. با این حال، استفاده از type(uint256).max
راهی تمیزتر و ایمنتر است. همین روش برای انواع صحیح علامتدار (signed integers) نیز قابل استفاده است:
1 2 3 4 5 |
//57896044618658097711785492504343953926634992332820282019728792003956564819967 type(int256).max; //-57896044618658097711785492504343953926634992332820282019728792003956564819968 type(int256).min; |
محاسبه ریاضی بیشترین مقدار در انواع صحیح علامت دار و بدون علامت
در انواع صحیح بدون علامت (unsigned integers)، میتوان از فرمول 2^n - 1
استفاده کرد. کافی است این عبارت را در محیط خط فرمان زبان برنامه نویسی مورد علاقه خود وارد کنید، که در آن n
تعداد بیت های نوع داده است (مثلاً uint128
یا uint32
). حتی مقادیر نادری مثل uint208
نیز معتبر هستند. وقتی نوع دادهای مانند uintN
تعریف میکنید، یعنی عدد شما با N
بیت نمایش داده میشود، و زمانی که همه بیت ها برابر با ۱ باشند، آن عدد به بیشترین مقدار خود میرسد.
در مقابل، ماشین مجازی اتریوم (EVM) برای نمایش اعداد صحیح علامتدار از سیستم مکمل دویی (Two’s Complement) استفاده میکند. بنابراین، بیشترین مقدار در اعداد علامتدار برابر است با 2^(n-1) – 1 و کمترین مقدار (بیشترین مقدار منفی ممکن) برابر است با -2^(n-1).
روشهای غیرمرسوم برای دسترسی به بیشترین مقدار uint256
شما میتوانید بیشترین مقدار uint256 در سالیدیتی را با استفاده از نمایش هگزادسیمال (مبنای ۱۶) نیز مشخص کنید. این روش از نظر ظاهری کمی مرتبتر از نمایش دهدهی (مبنای ۱۰) است، اما همچنان فضای زیادی اشغال میکند و احتمال بروز خطا در آن زیاد است. مثال:
1 |
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff |
f
است—اشتباه نکنید! عدد ۶۴ از تقسیم ۲۵۶ بیت بر ۸ به دست میآید (برای تبدیل به بایت)، که نتیجه آن ۳۲ بایت است. هر بایت نیز در مبنای ۱۶ با 0xff
نمایش داده میشود. بنابراین وقتی ۳۲ بار 0xff
را پشت سر هم بنویسید، همان بیشترین مقدار ممکن برای uint256
به دست میآید.
استفاده از عملگر معکوس بیتها (~
)
یک روش دیگر برای به دست آوردن بیشترین مقدار uint256
استفاده از عملگر ~
است. این عملگر تمام بیتهای یک عدد را برعکس میکند؛ یعنی هر بیت صفر را به یک و هر بیت یک را به صفر تبدیل میکند.
1 |
type(uint256).max == ~uint256(0) // this will return true |
uint256(0)
عددی است که تمام بیتهای آن صفر هستند. وقتی عملگر ~
روی آن اعمال میشود، تمام این صفرها به یک تبدیل میشوند و دقیقاً عددی به دست میآید که تمام ۲۵۶ بیت آن برابر با یک است—یعنی همان بیشترین مقدار ممکن برای نوع uint256
.
یک روش نامناسب: ایجاد حالت زیرریز (underflow)
1 2 3 |
function maximum() public pure returns(uint256) { unchecked { return uint256(0) - uint256(1); } } |
unchecked
اجازه داده میشود که نتیجه به حالت زیرریز برود. در نهایت، مقدار بهدستآمده همان uint256.max
خواهد بود.
روش زیر هرچند درست کار میکند، ولی شفاف نیست و استفاده از آن توصیه نمیشود:
1 2 3 |
function maxUint() public pure returns (uint256) { return 2**256 - 1; } |
این تابع نیز مقدار درستی بازمیگرداند، که میتوان آن را با کد زیر تأیید کرد:
1 |
assert(2**256 - 1 == type(uint256).max); |
نکته مهم این است که اگر عبارت 2**256
را بهتنهایی در کد سالیدیتی بنویسید، کامپایلر با خطا مواجه خواهد شد، چون این مقدار از محدوده نوع uint256
خارج است. اما اگر بلافاصله بعد از آن عبارت - 1
را اضافه کنید، کامپایلر متوجه میشود که نتیجه نهایی در محدوده مجاز قرار دارد و اجازه اجرای برنامه را میدهد.
uint256(-1)
دیگر قابل استفاده نیست
در نسخههای قدیمیتر سالیدیتی، برنامه نویسان با نوشتن uint256(-1)
میتوانستند به بیشترین مقدار uint256
دست پیدا کنند. اما نسخههای جدید سالیدیتی این روش را پشتیبانی نمیکنند و هنگام کامپایل با خطا مواجه میشوند. برای جلوگیری از این مشکلات، بهتر است مستقیماً از عبارت type(uint256).max
استفاده کنید.
عدد 2^256 – 1
واقعاً چقدر بزرگ است؟
برای اینکه بتوانید اندازه این عدد را بهتر درک کنید، کافی است آن را با تعداد تقریبی اتمهای موجود در کل جهان شناختهشده مقایسه کنیم—که چیزی در حدود 10^80
برآورد میشود. حالا این دو عدد را کنار هم ببینید:
1 2 3 |
115792089237316195423570985008687907853269984665640564039457584007913129639935 100000000000000000000000000000000000000000000000000000000000000000000000000000000 |
این مقایسه نشان میدهد که حدود ۱۰۰۰ عدد متغیر uint256
میتوانند تمام اتم های جهان شناخته شده را شمارهگذاری کنند. چون بیشتر چیزهایی که برای ما اهمیت دارند از تعداد بسیار بیشتری از ۱۰۰۰ اتم تشکیل شدهاند، یک عدد uint256
به راحتی میتواند هر مجموعهای از اشیای مفید را شمارهگذاری کند و حتی فضای اضافه هم باقی بگذارد.
در نتیجه، وقتی دو مقدار uint256
را بهصورت تصادفی انتخاب میکنیم—مثل خروجی تابع keccak256
—از نظر عملی احتمال برخورد (collision) بین آنها تقریباً صفر است.
راستی! برای دریافت مطالب جدید در کانال تلگرام یا پیج اینستاگرام سورس باران عضو شوید.
- انتشار: ۳ خرداد ۱۴۰۴
دسته بندی موضوعات
- آموزش ارز دیجیتال
- آموزش برنامه نویسی
- آموزش متنی برنامه نویسی
- اطلاعیه و سایر مطالب
- پروژه برنامه نویسی
- دوره های تخصصی برنامه نویسی
- رپورتاژ
- فیلم های آموزشی
- ++C
- ADO.NET
- Adobe Flash
- Ajax
- AngularJS
- apache
- ARM
- Asp.Net
- ASP.NET MVC
- AVR
- Bootstrap
- CCNA
- CCNP
- CMD
- CSS
- Dreameaver
- EntityFramework
- HTML
- IOS
- jquery
- Linq
- Mysql
- Oracle
- PHP
- PHPMyAdmin
- Rational Rose
- silver light
- SQL Server
- Stimulsoft Reports
- Telerik
- UML
- VB.NET&VB6
- WPF
- Xml
- آموزش های پروژه محور
- اتوکد
- الگوریتم تقریبی
- امنیت
- اندروید
- اندروید استودیو
- بک ترک
- بیسیک فور اندروید
- پایتون
- جاوا
- جاوا اسکریپت
- جوملا
- دلفی
- دوره آموزش Go
- دوره های رایگان پیشنهادی
- زامارین
- سئو
- ساخت CMS
- سی شارپ
- شبکه و مجازی سازی
- طراحی الگوریتم
- طراحی بازی
- طراحی وب
- فتوشاپ
- فریم ورک codeigniter
- فلاتر
- کانستراکت
- کریستال ریپورت
- لاراول
- معماری کامپیوتر
- مهندسی اینترنت
- هوش مصنوعی
- یونیتی
- کتاب های آموزشی
- Android
- ASP.NET
- AVR
- LINQ
- php
- Workflow
- اچ تی ام ال
- بانک اطلاعاتی
- برنامه نویسی سوکت
- برنامه نویسی موبایل
- پاسکال
- پایان نامه
- پایتون
- جاوا
- جاوا اسکریپت
- جی کوئری
- داده کاوی
- دلفی
- رباتیک
- سئو
- سایر کتاب ها
- سخت افزار
- سی اس اس
- سی پلاس پلاس
- سی شارپ
- طراحی الگوریتم
- فتوشاپ
- مقاله
- مهندسی نرم افزار
- هک و امنیت
- هوش مصنوعی
- ویژوال بیسیک
- نرم افزار و ابزار برنامه نویسی
- وردپرس