مشاهده نسخه کامل
: نحوه بدست آوردن دقت اعداد ممیز
سلام
این رنج چطور بدست میاد؟
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ] ([ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ])
Approximate Range (-7.9 x 1028 to 7.9 x 1028) / (100 to 28)
Precision 28-29 significant digits
سلام
اگر منظورتان را درست متوجه شده باشم، توضیح کوتاهی میدهم...
نوع decimal یک متغییر عددی سفارشی 16 بایتی=128 بیتی است که نه کاملاً شبیه double است و نه long ...
حدوداً از این 16 بایت ، 4 بایت آن برای عدد توان علمی 10 و علامت توان و علامت عدد استفاده میشود (که البته چندبایتی هرز میرود) و 12 بایت باقی مانده برای ذخیره ذات عدد استفاده میشود که برابر 96 بایت میشود بر توان 2 گنجایش 79,228,162,514,264,337,593,543,950,336 را خواهد داشت. که میشود دقت 28 رقم قطعی و برخی اعداد 29 رقمی ... توجه کنید که محل نقطه اعشار اصلاً مهم نیست و جداگانه در آن 4 بایتی که گفته شد نگه داری میشود.
این یک نوع کاملاً خاص است و برعکس int و long و float و double استاندارد سخت افزاری ندارد و مستقیم توسط پردازنده (یا کمک پردازنده محاسبات عددی) پشتیبانی نمیشود...
این نوع در واقع از اعداد علمی مبنای ده پشتیبانی میکند و اعداد اعشاری و صحیح را به همان شکل انسانی آن میتواند حفظ کند.
(برخلاف double که ذات مبنای ده ندارد و امکان دارد در محاسبات اعشاری خروجی آن با چیزی که یک انسان روی کاغذ انجام میدهد برابر نباشد.)
به همین دلیل برای مبالغ پولی اعشار دار (در کشورهای دیگر) decimal کاندید خوبی برای نگه داری اعداد است یا یک سنت هم اختلاف مالی رخ ندهد....
و...
امیدوارم به جوابتان رسیده باشید.
موفق باشید.
سلام
ممنون بعد پیاده سازی نوع داده ها چگونه است؟هر نوع داده یک کلاس هست؟ int یک کلاس هست که در درون کامپایلر پیاده سازی شده؟
سلام
متاسفانه بازهم مطمئن نیستم منظورتان را درست درک کرده باشم ...
متغییرهای عددی ما همه Struct هستند (Class نیستند)
Struct و Class ها در تخصیص حافظه متفاوت عمل میکنند.
شما خودتان هم میتواند یک Struct یا Class جدید کدنویسی کنید و اپراتورهای +-*/ و... را برای آن بازتعریف کنید.
مثلاً یک Struct جدید برای نگه داری اعداد کسری به همان صورت خودشان بنویسید که امکان جمع و ضرب و... کسیری را بدهد.
تنها تفاوت کوچک int و long و byte و... آن است که این بازتعریف اپراتورها برای این ساختارها مستقیم توسط دستورات اتومیک cpu پشتیبانی میشود.
ولی همانطورکه گفته شد، درسایر موارد مانند decimal و BigInteger و آن struct سفارشی اعداد کسری، باید با کدهای #C متدهای مجزایی برای بازتعریف اپراتورهای جمع و ضرب و... نوشته شود.
در عمل برای کسی که میخواهد از decimal یا int استفاده کند، این حرف ها تفاوتی ندارد!
امیدوارم به جواب تان رسیده باشید.
موفق باشید.
سلام
ممنون از پاسخ شما.منظورم این هست که در پشت پرده int به جه صورت پیاده سازی شده؟ که ما رو محدود مثلا میکنه تا 16 بیت بیشتر داخلش نمیتونیم عدد بریزیم.خوب این بلاخره خود ماکروسافت داخل کامپایلر این رو یک طوری پیاده سازی کرده
int myInt = new int();
احتمالا باید کلاس یاشد و گرنه چطور سازنده رو صدا زدیم؟
مگر ایرادی دارد که struct سازنده داشته باشد؟ این ([ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ](v=vs.71).aspx) رو ببینید.
در مورد ساختار int می توانم اینگونه توضیح دهم:
کوچکترین واحد حافظه چیست؟ بایت.
پس بسته به اینکه چه تعداد خانه ی حافظه اختصاص می دهیم می توانیم مقادیر رو ذخیره سازی کنیم. با تعریف یک متغیر int32 شما 4 خانه از حافظه را اختصاص می دهید و الی آخر. این تعدادهنگام Runtime قابل تغییر نیست در نتیجه یک نوع همیشه ظرفیت ثابت خود را دارد و در صورتی که مقدار آن افزایش و در تعداد خانه های مورد نظر قرار نگیرد دوباره به صفر بر می گردد و حالت OverFlow ایجاد می شود.
بلی، خود کامپایلر این وظیفه را دارد. شما نوعی را که انتخاب می کنید در واقع به کامپایلر گفته اید که برای کار خود نیاز به مثلا 2 بایت فضا دارید(int16).
اگر قرار بود که طول مقادیر در زمان اجرا تغییر کند چه می شد؟
برای پاسخ به این مسئله دقت کنید:
عموما کامپایلر ها مقادیر متغیرهای عمومی را پشت سر هم قرار می دهند (خاصیت far و near و مدل های حافظه small ، Large و Huge و...) یعنی:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
در شکل بالا دو متغیر A و B را داریم.. حالا اگر قرار باشد که طول مقدار شما در متغیر A زیاد تر شود چه می شود؟ بایت ابتدایی متغیر B می رود در باقالی ها:n02:.
و این همان تداخل حافظه هست. در واقع کامپایلر با ایجاد محدودیت خطاهای اینگونه را از بین می برد. در صورتی هم که کامپایلر بیخیال شود سیستم عامل حالتون رو می گیره. و خطا هنگام اجرا به وجود می آید و پیغام هایی نظیر Access Violation و یا Memory corruption داده می شود و سیستم عامل برنامه را kill می کند.
در راستای توضیحات استاد بزرگ H2 :
در یک نگاه دیگر نیز با توجه به اینکه پردازنده ها محدودیت بیتی دارند( نظیر 32 بیت و 64 بیت) پس به طور مثال نمی توانند محاسبات را روی متغیر های 128 بیتیِ صحیح داشته باشند. پس کامپایلر چگونه جمع 128 بیتی را ایجاد می کند و هیچ خطایی وجود ندارد؟ در واقع این گونه متغیر ها به دو متغیر 64 بیتی تقسیم می شوند (در مدل 64بیت، در مدل 32 بیت به 4 متغیر 32 بیت) و محاسبات تک تک انجام شده و در نهایت حاصل نمایشی مجموع کنار هم قرار گرفتن این خانه های حافظه خواهد بود. یعنی 16 خانه از حافظه در کنار هم با ضریب شیفت 8 می شوند یک عدد 128 بیتی.
این کارهایی است که کامپایلر ها انجام می دهند (و از سال 1980 عموما خطایی مشاهده نشده است :n02:. )
----------
([ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ])در مورد این که یک int کلاس هست که جناب H2 پاسخ داده اند و struct بودن این دسته فقط به خاطر رفتار پردازنده نیست. این امر از رفتار حافظه ها نیز تاثیر گیر است.به این ([ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]) دقت کنید. یعنی struct ها مقادیرشان کنارشان است و هر زمان که cpu بخواهد می توان مستقیم به خانه ی حافظه دسترسی داشته و محاسبات را انجام دهد در صورتی که در کلاس ها پردازنده می بایست که یک jump به فضای heap بزند و سپس مقادیر را بردارد و این مخالف اصل بهینه سازی است. پس متغیر های عددی و یا هرچیزی که نیاز است عدد محور باشد struct تعریف می شوند.
موفق باشید.
برای تمرین و نحوه ی اینکه چه طور کامپایلر این کار ها را انجام می دهد می توانید یک تمرین با مضمون زیر حل کنید.
با استفاده از 4 متغیر نوع byte سعی کنید اعداد 5000 و 3000 رو باهم جمع کنید.
مطمئنا نه 5000 در Byte جا می شود و نه 3000 . حال رفتاری را پیاده سازی کنید که این عمل اتفاق بیافتد و بتوان این اعداد را با هم جمع کرد.
موفق باشید.
سلام
ممنون و سپاس گزار بابت توضیحات عالی هر دو دوست
در مورد گرفتم و پس دادن حافظه در سی شارپ چطور عمل میشه؟ آیا مثل c و c++ هست؟ با توجه به اینکه در سی شارپ اشاره گر نداریم عملا میتونیم هیپ بزنیم و پس بدیم حافظه رو؟ میشه یک توضیحی بدید ممنون میشم
سلام
در مورد گرفتم و پس دادن حافظه در سی شارپ چطور عمل میشه؟
با کلمه new میتوانید حافظه بگیرید ولی برای آزاد سازی اشیای خالص دات نتی نیاز به هیچ کار خاصی نیست، نهایت نهایتش میتوانید متغیر تخصیص داده شده را null کنید.
البته باید به قید "خالص دات نتی" دقت کنید.
چون برخی از اشیای از منابع خارج از مدیریت دات نت مصرف دارند... مانند Connection ها به دیتابیس ها، فایلها که اشاره گر فایل دارند، تصاویر که اشاره گری از gdi مانند hbitmap دارند، Socket ها و...
در مورد این اشیا و پس از مصرف و پایان کار باید متد Dispose شان را اجرا کنید.
چون باید منبعی در خارج از کنترل دات نت از پایان استفاده مطلع شود و آزاد سازی منابع را انجام دهد.
با توجه به اینکه در سی شارپ اشاره گر نداریم عملا میتونیم هیپ بزنیم و پس بدیم حافظه رو؟
پست ششم تاپیک زیر را مطالعه کنید
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
موفق باشید.
سلام
ممنون از زحمات دوستان
ما میگیم INT به طور مثال 32 بیت هست و 2 به توان 32 بیت عدد داخلش جا میشه.
یعنی مثلا 16 خواست داخل بره میشه 10000 و تک تک قرار میگیره داخل خانه ها
حالا این 16.364 خواست بره داخل چطوری قرار میگیره؟
سلام
حالا این 16.364 خواست بره داخل چطوری قرار میگیره؟
جواب شما عدد 0x40305d2f1a9fbe77 هگزادسیمال است.
01000000
00110000
01011101
00101111
00011010
10011111
10111110
01110111
ولی اگر میخواهید دلیلش را هم بدانید، نیاز است دو مطلب پیش نیاز ریاضی را بدانید و سپس ساختار و دید رایانه ای را هم داشته باشید و بدانید.
مطلب اول: اعداد اعشاری در مبنای 2 از دید ریاضی
الف) یادآوری مبانی مبنای 10
10 عدد پایه وجود دارد (0~9) و یک سری جایگاه عدد که کلیه اعداد دیگر از ترکیب اینها ساخته میشود.
میدانیم 9 بزرگتر از 5 است!
ولی در عدد 509 ارزش 5 بیش از 9 است چون در جایگاه بالاتری قرار دارد، چیزی که در فارسی معمولاً با لفظ "گان" استفاده میشود.
جایگاه هایی مانند: یکان، دهگان، صدگان و...
اینها توان های صفر و مثبت عدد 10 هستند.
-ما برای اعشار جایگاه های توان منفی 10 را داریم: یکدهم گان، یکصدم گان و...
(اجازه دهید از لفظ "گان" همچنان استفاده کنم تا مشخص شود در مورد جایگاه عددی صحبت میکنیم)
ب) مبانی اعشار در مبنای 2
کافیست به جای 10 در جملات بالا 2 قرار دهید!
یعنی در سمت اعداد صحیح ارزش های یکان، دوگان، چهارگان، هشت گان و... داریم (توان های صفر و مثبت 2)
برای اعشار جایگاه های عدد یکدوم گان، یک چارم گان و... را داریم.
مثال:
عدد 11 باینری، یکی در ارزش مگانی "یکان" و یکی هم در ارزش مکانی "دوگان" دارد که در مجموع برابر عدد 3 در مبنای 10 خودمان میشود.
عدد 1.1 باینری، یکی در ارزش مگانی "یکان" و یکی هم در ارزش مکانی "یکدوم گان" دارد که در مجموع برابر عدد 1.5 در مبنای 10 خودمان میشود.
(((
دقت کنید همانطور که در مبنای 10 یک شیفت رقمی ارزش 10 برابری دارد در مبنای 2 هم یک شیفت عدد ارزش 2 برابری دارد...
همانطور که درمبنای ده، 9870 ده برابر 987 است و 987 ده برابر 98.7 است،
همانطور هم در مبنای دو، 110 دو برابر 11 است و 11 هم دو برابر 1.1 است.
)))
یا 1.01 باینری برابر 1.25 در دسیمال است.
یا 1.11 باینری برابر 1.75 در دسیمال است.
و...
پایان پیش نیاز اول.
انشاا... فردا جمعه جواب تان را تکمیل خواهم کرد.
سلام
مطلب دوم: اعداد علمی در مبنای 2 از دید ریاضی
الف) یادآوری مبانی مبنای 10
برای تبدیل یک عدد به عددعلمی باید آن را در ضرایب 10 ، ضرب یا تقسیم کرد تا عدد به صورت یک رقم صحیح (1 یا بزرگتر) و کسری اعشاری گردد (که طبیعتاً در توانی از 10 ضرب خواهد شد تا مقدار نهایی ثابت بماند)
مثال
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
ب) مبانی عددعلمی در مبنای 2
در مبنای 2 هم مشابه همین وضعیت وجود دارد، هر عدد باینری باید به صورت یک پایه تک رقمی (فقط عدد 1 چون باید از 1 بزرگتر باشد و از طرفی در مبنای 2 فقط 0 و 1 داریم پس تنها عدد مجاز 1 خواهد بود) ضرب در توانی از 2
مثال
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
مطلب سوم: فرمت ذخیره سازی متغییر double و float در رایانه
این متغییرهای اعداد را به صورت عدد علمی مبنای دو ذخیره میکنند.
و حاوی اطلاعات "علامت عدد" "توان علمی عدد" "عدد پایه" است.
- بیت علامت اگر 0 باشد به معنی عدد مثبت و اگر 1 باشد به معنی عدد منفی خواهد بود.
- عدد توان علمی با قانون میانه خاصی ذخیره میشود که برابر جمع عدد توان با عدد 2Pow(bits-1)-1 خواهد بود.
- همانطورکه قبلاً بیان شد، "عدد پایه" در اعداد علمی مبنای دو همواره یا 1 شروع میشوند، درنتیجه در ذخیره سازی جهت صرفه جویی این 1 ثابت ذخیره نمیشود.
متغییر double حجم 64 بیت و برابر 8 بایت دارد که
1 بیت علامت عدد
11 بیت برای توان علمی عدد (جمع عدد با 1023)
52 بیت برای ذخیره سازی پایه عدد
متغییر float حجم 32 بیت و برابر 4 بایت دارد که
1 بیت علامت عدد
8 بیت برای توان علمی عدد (جمع عدد با 127)
23 بیت برای ذخیره سازی پایه عدد
مثال ذخیره 14.5 در double
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
مثال ذخیره عدد +16.364 در double
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
موفق باشید.
vBulletin , Copyright ©2000-2025, Jelsoft Enterprises Ltd.