PDA

View Full Version : خطا های غیرمنطقی کامپایلر



asadsheidaharzand
جمعه 11 تیر 1395, 16:08 عصر
سلام دوستان,در طول برنامه نویسی اخیرا به مواردی برخورد کردم که کد ها رو وقتی به صورتی دستی تریس میکردم اصلا مشکلی نداشتن ولی خروجی کامپایلر کاملا غیر منطقی بود.
مثلا این کد:
#include <iostream>
int main()
{
for (int i = 0; i < 300; i++)
std::cout << i << " " << i * 12345678 << std::endl;
}

یا این کد :
#include <iostream>
#include<stdio.h>
#include <map>
#include <string>
#include<math.h>
#include <stdlib.h>
using namespace std;
int main()
{
long long n, m, a, b, xm, ans[500],d;
cin >> n >> m >> a >> b;
xm = 0;
while (0<= (n - xm*m) )
{
ans[xm] = xm*b + (n - xm*m)*a;
xm++;
cout << ans[xm]<<" "<<xm << endl;
}
d = ans[0];
while (xm >= 0)
{
if (ans[xm] < d)
d = ans[xm];
xm--;
}
cout << d;
return 0;
}
مشکل چیه؟آیا کامپالر میاد کدام رو optimize کنه ولی به جای کمک کردن کد رو دچار اختلال میکنه یا مشکل یه چیز دیگس؟چه جوری میشه درستش کرد؟

AliAskari1375
جمعه 11 تیر 1395, 18:49 عصر
سلام. علتش اینه که از نوع حافظه های مناسب استفاده نمی کنید
مثلا کد اول رو باید به شکل زیر بنویسید:



#include <iostream>


int main()
{
for (unsigned long long int i = 0; i < 300; i++)
std::cout << i << " " << i * 12345678ull << std::endl;




return 0;
}

asadsheidaharzand
جمعه 11 تیر 1395, 19:21 عصر
سلام. علتش اینه که از نوع حافظه های مناسب استفاده نمی کنید
مثلا کد اول رو باید به شکل زیر بنویسید:



#include <iostream>


int main()
{
for (unsigned long long int i = 0; i < 300; i++)
std::cout << i << " " << i * 12345678ull << std::endl;




return 0;
}



شما یه جورایی صورت سوال رو پاک کردید اشکال کد اول sign overflow هست که دلیلش رو میدونم ولی میخوام بدونم دقیقا چرا این اتفاق میفته.

AliAskari1375
جمعه 11 تیر 1395, 19:48 عصر
ببینید i که از نوع int هست و اندازه ش 4 بایته
عدد 12345678 هم به صورت پیش فرض int در نظر گرفته میشه

جواب حاصل ضرب int * int توی C++‎‎‎‎‎‎‎‎‎‎‎‎ ، خودش از نوع int خواهد بود

حالا ما بزرگترین مقدار i طی اجرای حلقه که 299 هست رو در 12345678 ضرب میکنیم ، جواب میشه 3691357722
اما بزرگترین مقداری که میشه توی حافظه ی int ذخیره کرد 2147483647 هستش
چون عدد حاصل ضرب از ظرفیت int بزرگتره کامپیوتر میاد و طبق قانون زبان C++‎‎‎‎‎‎‎‎‎‎‎‎ ، مقدار

4294967295 - 3691357722
رو چاپ میکنه

4294967295 هم بزرگترین مقداری است که unsigned int ذخیره میکند

asadsheidaharzand
جمعه 11 تیر 1395, 20:19 عصر
ببینید i که از نوع int هست و اندازه ش 4 بایته
عدد 12345678 هم به صورت پیش فرض int در نظر گرفته میشه

جواب حاصل ضرب int * int توی C++‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ، خودش از نوع int خواهد بود

حالا ما بزرگترین مقدار i طی اجرای حلقه که 299 هست رو در 12345678 ضرب میکنیم ، جواب میشه 3691357722
اما بزرگترین مقداری که میشه توی حافظه ی int ذخیره کرد 2147483647 هستش
چون عدد حاصل ضرب از ظرفیت int بزرگتره کامپیوتر میاد و طبق قانون زبان C++‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ، مقدار

4294967295 - 3691357722
رو چاپ میکنه

4294967295 هم بزرگترین مقداری است که unsigned int ذخیره میکند
و کد دوم؟!

ciavosh
جمعه 25 تیر 1395, 12:52 عصر
خروجی کامپیوتر بنا به تعریف نمیتونه غیر منطقی باشه. ولی ممکنه اون چیزی مورد انتظار کاربر هست نباشه.