سلام
ویژوال بیسیک رو باز کنید.
این کد رو بنویسید و اجرا کنید:
x = 20000 + 20000
خیلی جالبه نه ؟! خطای سرریز میده !!!
حالا اینو اجرا کنید که معادل همون بالاییه:
x = 20000 / 20000 * 20000 + 20000
میبینید که اجرا میشه !!!!!
فکر میکنم درستش این باشه که طرفین عملگر ابتدا در متغییر ریخته بشن یعنی اینجوری:
a = 20000
b = 20000
x = a + b
ولی شاید خود a دارای عملیات باشه . اینجوری برنامه بیخود پیچیده میشه ...
ضمنا تست کردم به نوع متغییر ها هم مربوط نمیشه .
حالا یه چیز دیگه ، شاید به ذهنتون برسه که عمل جمع توانایی محاسبه اعداد بزرگ رو نداره ، پس به مثال های زیر توجه کنید:
x = 20 + 20
x = 200 + 200
x = 2000 + 2000
x = 20000 + 20000
x = 200000 + 200000
x = 2000000 + 2000000
x = 20000000 + 20000000
x = 200000000 + 200000000
x = 2000000000 + 2000000000
x = 20000000000 + 20000000000
ملاحظه میکنید که تنها خطوطی که با رنگ قرمز است اجرا نمیشه ! و در مورد اعداد بزرگتر یا کوچکتر مشکلی نیست ....
نتیجه همون موضوع تاپیکه !!! درست نمیگم ؟
یادتونه قبلا یه تاپیک با نام "دیتا بیس جنی !!!" زده بودم ، در نهایت همه به این موضوع رسیدیم . حالا هم فکر میکنم مورد مشابه است !!!
خیلی عجیبه !
کسی میتونه توضیح بده این اشکال از کجا آب میخوره ؟!
و راه حلش چیه؟!
نبی
وقتي متغير تعريف نشه variant فرض ميشه.
احتمالا وقتي مينويسي x = 20000 + 20000 متغير رو variant فرض ميكنه ولي فضايي كه بهش ميده اندازه اينتيجره. ولي وقتي تقسيم ميذاري اندازه دوبل بهش فضا ميده.
x = 20 + 20
x = 200 + 200
x = 2000 + 2000
x = 20000 + 20000
x = 200000 + 200000
x = 2000000 + 2000000
x = 20000000 + 20000000
x = 200000000 + 200000000
x = 2000000000 + 2000000000
x = 20000000000 + 20000000000
در اين مورد ميخواستم بگم شايد مثلا تا موقعي كه اعداد 5 رقمين اندازه اينتجر فضا ميده. ولي تعداد اعداد كه زياد ميشه اندازه دوبل و لانگ فضا ميده. ولي اگه از همون اول x رو لانگ هم تعريف كنيد سر 20000+20000 خطاي سر ريز ميده.
جالب بود راست ميگي عجيبه.
يادمه تو پاسكال 6 هم وقتي يه آرايه بزرگ تعريف ميكردي - متغيري رو اگه بعد از اون آرايه تعريف ميكردي مقدار متغير هر لحظه عوض ميشد و مقدار دادن هم تاثير نداشت.
Payman62 نوشته است:وقتي متغير تعريف نشه variant فرض ميشه.
احتمالا وقتي مينويسي x = 20000 + 20000 متغير رو variant فرض ميكنه ولي فضايي كه بهش ميده اندازه اينتيجره. ولي وقتي تقسيم ميذاري اندازه دوبل بهش فضا ميده.
احتمالا اینطوره که شما میگید.
چون اتفاقا من یه تایمر در برنامم دارم که هر ثانیه یه شماره میندازه و مقدار ساعت و دقیقه و ثانیه رو به صورت رشته های جدا نشون میده ولی درون متغییر معادل ثانیه ای اون رو دخیره میکنه. برنامه خوب کار میکنه تا زمانی که 9 ساعت و 6 دقیقه و 7 ثانیه سپری میشه (اگر این رو به ثانیه برگردونید میشه 32767 که درست ماکزیمم مقدار متغییر integer است!) اما درست در لحظه ای که ثانیه یکی افزایش میابد، برنامه خطا میده ! این نشون میده مقدار حافظه تخصیص داده شده integer است. اما چرا زمانی متغییر رو از نوع long تعریف میکنم باز هم این مشکل بروز میکنه ! ظاهرا کاری نداره که متغییر چی باشه . مستقیما به عملگر نگاه میکنه و در صورتی که به اضافه باشه integer و در صورتی که به قول شما تقسیم باشه حافظه بیشتری تخصیص میده .. اما حالا اگر به عملگر نگاه میکنه پس چرا در صورت استفاده از متغییر مشکلی بروز نمیکنه !!! حتی در صورتی که اعداد دو طرف عملگر به صورت ثابت (Const) تعریف بشن به دلیل مطلق بودن اعداد باز هم برنامه خطا میده .
خلاصه هر جاش رو بگیریم یه جاش در میره .
البته من مشکل رو اینجوری حل کردم که مجبور شدم اعداد ثابتی که در عبارت ریاضیم وجود داشت از جمله اعداد 60 و 3600 رو به صورت متغییر long تعریف کردم (integer هم نشد!!!!) و در ابتدای برنامه این مقادیر رو به متغییرهاشون نسبت دادم و در عملیات ریاضی ازشون استفاده کردم . یعنی مثل یه متغییر باهاشون برخورد کردم و مشکل حل شد.
دلیلی هم که شما دوست عزیز ارائه دادید به نظرم خوب و منطقی بود . ولی این دلیل نمیشه که بیلی به دلیل این باگ های مسخره فحش نخوره !!!!!!
چاریم
نبی
اگه جنی باشه که جن گیر می خواد

ولی عدد 20000 یه signed int هست (یعنی اینتیجر علامت دار) و وقتی با خودش جمع بشه از یه Signed int می زنه بالاتر برای حل این مشکل تو سی از casting استفاده می کنن تو یه پرانتز نوع عدد رو مشخص می کنن مثلا (unsigned int) البته برای اعداد ثابت ته عدد هم یه چیز هایی اضافه می کنن مثل 123450000UL توی ویبی احتمالا باید نوع متغیر رو صراحتا مشخص کنی تا این مشکل پیش نیاد
برای اعداد بزرگتر هم که می دونید مثلا 200000 یه 3 بایتیه که احتمالا یه word شناسایی می شه و جمعش از word بیشتر نمی شه تا همون عدد قرمز دوم که خودش word ولی جمعش ار word بیشتر
Payman62 نوشته است:x = 20 + 20
x = 200 + 200
x = 2000 + 2000
x = 20000 + 20000
x = 200000 + 200000
x = 2000000 + 2000000
x = 20000000 + 20000000
x = 200000000 + 200000000
x = 2000000000 + 2000000000
x = 20000000000 + 20000000000
در اين مورد ميخواستم بگم شايد مثلا تا موقعي كه اعداد 5 رقمين اندازه اينتجر فضا ميده. ولي تعداد اعداد كه زياد ميشه اندازه دوبل و لانگ فضا ميده. ولي اگه از همون اول x رو لانگ هم تعريف كنيد سر 20000+20000 خطاي سر ريز ميده.
من که با استدلال شما مخالفم ! به خاطر اینکه مبنای کامپیوتر و برنامه های کامپیوتری تعداد ارقام نیست . بلکه بایت حافظه است. و به عنوان مثال فرضاً در مورد متغییر های integer اصلا ویژوال بیسیک تفاوتی بین 3 و 33 و 333 و 3333 قائل نیست چون در محدوده حافظه مجاز هستند و اونها رو مجاز میدونه ولی بین اونها و عدد 33333 تفاوت قائل میشه ، البته تفاوت ناشی از تعداد زیاد ارقام نیست! بلکه در میزان فضای غیر مجاز اشغالی است.
در مورد مثال بالا هم که بنده عرض کردم عجیب است! واقعا عجیب است!
تشکر
نبی
ashkan نوشته است:جالب بود راست ميگي عجيبه.
يادمه تو پاسكال 6 هم وقتي يه آرايه بزرگ تعريف ميكردي - متغيري رو اگه بعد از اون آرايه تعريف ميكردي مقدار متغير هر لحظه عوض ميشد و مقدار دادن هم تاثير نداشت.
پس شما هم در مورد جنی بودن این اعداد با بنده هم عقیده هستند ;)
منتظر موارد جنی دیگر ویژوال بیسیک باشید.
نبی
ha_60 نوشته است:اگه جنی باشه که جن گیر می خواد 
ولی عدد 20000 یه signed int هست (یعنی اینتیجر علامت دار) و وقتی با خودش جمع بشه از یه Signed int می زنه بالاتر برای حل این مشکل تو سی از casting استفاده می کنن تو یه پرانتز نوع عدد رو مشخص می کنن مثلا (unsigned int) البته برای اعداد ثابت ته عدد هم یه چیز هایی اضافه می کنن مثل 123450000UL توی ویبی احتمالا باید نوع متغیر رو صراحتا مشخص کنی تا این مشکل پیش نیاد
برای اعداد بزرگتر هم که می دونید مثلا 200000 یه 3 بایتیه که احتمالا یه word شناسایی می شه و جمعش از word بیشتر نمی شه تا همون عدد قرمز دوم که خودش word ولی جمعش ار word بیشتر
کسی فهمید حامد چی گفت ؟!
اشتباه برداشت نشه . اشکال کار از IQ بنده است. شرمنده ....
پ.ن: راستی مبارکه میبینم که مدیر انجمن موبایل شدی . جدی جدی حالا خوره ای تو این زمینه ؟ من میخوام برا p910i برنامه بنویسم میتونی کمکم کنی؟
چاکریم
این وی بی هم مسخرش رو در آورده !
برید سراغ سی ++
وی بی به قول معروف بچه دلخوش کنکه
روش نمی شه حساب کرد
به نظر من این عبارت را فکر میکنم از نوع رشته در نظر میگیرد .
چون دقیقا این عمل برای رشته نیز میتواند انجام شود .
راه حل :x=val(20000)+val(20000) میباشد همین .
علامت تقسیم : سبب میشود اعداد را به صورت رشته در نظر نگیرد .
به نظر من این مشکل نیست این بستگی به نوع طراح کامپایلر دارد .
که اعداد را چگونه تشخیص دهد .
در ضمن بیلی سلطان برنامه نویسی جهان میباشد هر برنامه نویس
وظیفه دارد به او احترام بگذارد.
اگر standard Programming را رعایت کنیم هیچ وقت این مشکلات پیش نمی آید.