نمایش نتایج 1 تا 11 از 11

نام تاپیک: سرریزی غیر عادی داده های عددی

  1. #1
    کاربر دائمی
    تاریخ عضویت
    شهریور 1387
    محل زندگی
    کاشان
    پست
    809

    سرریزی غیر عادی داده های عددی

    سلام دوستان

    تو برنامه با مشکلی مواجه شدم که خودم تعجب کردم آخه قبلا چنین مشکلی نداشتم .

    هنگامی که دستور زیر را اجرا می کنم نتیجه نمایش دادن نمیشه و جالب اینجاست که قبلا ها که یک ماشین حساب با دلفی 7 نوشته بودم این دستور رو اجرا میکنه و کدها مو نمی زنند .

    دستور

    Procedure TFrmMain.Button1Click(Sender:TObject);
    var
    KB:LongLong; // Int64 or Extended or Cardinal have OverFlow
    Const GigaByteInbyte=1073741824;
    begin
    GB:=3;
    KB:=(GigaByteInbyte*GB);
    LblShowKB.Caption:=intToStr(KB);
    end;

  2. #2

    نقل قول: سرریزی غیر عادی داده های عددی

    بايد كد رو به صورت زير بنويسي:
    procedure TForm1.btn1Click(Sender: TObject);
    var
    KB: LongLong;
    GB: Integer;
    Const
    GigaByteInbyte: Int64 = 1073741824;
    begin
    GB := 3;
    KB := (GigaByteInbyte * GB);
    LblShowKB.Caption := IntToStr(KB);
    end;

    توضيح: مشكل از تعريف KB نيست، بلكه از تعريف ثابت GigaByteInbyte است. چون دلفي به طور پيش فرض براي تعريف ثابتهاي عددي از نوع Integer استفاده مي كند، در كد شما به همين دليل در قسمت مربوط به تعريف اين ثابت يك سرريزي رخ مي دهد و در نتيجه در اين ثابت عددي برخلاف ميل شما يك عدد منفي جاي مي گيرد و در نتيجه حاصل محاسبات شما اشتباه از آب در مي آيد!!!
    (البته از دوستان حرفه اي تر مي خواهم كه درباره اين مشكل بيشتر توضيح بدن، چون خودم هم در اين باره با مسايل ضد و نقيضي برخورد كردم)
    آخرین ویرایش به وسیله BORHAN TEC : پنج شنبه 13 اسفند 1388 در 00:54 صبح

  3. #3
    کاربر دائمی
    تاریخ عضویت
    شهریور 1387
    محل زندگی
    کاشان
    پست
    809

    نقل قول: سرریزی غیر عادی داده های عددی

    ممنون مشکل حل شد ولی من قبلش کدم رو هم به این شکل نوشته بودم .


    procedure TForm1.Button1Click(Sender: TObject);
    var
    KB: LongLong;
    GB: Integer;
    begin
    GB := 3;
    KB := (1073741824 * GB);
    LblShowKB.Caption := IntToStr(KB);
    end;


    که جالب بود باز هم overflow میشد !!!

  4. #4

    نقل قول: سرریزی غیر عادی داده های عددی

    اگه دليلش رو فهميدي به ما هم بگو، چون براي من هم خيلي عجيبه!!!

  5. #5

    نقل قول: سرریزی غیر عادی داده های عددی

    درود :
    شما به جای LongLong از Int64 استفاده کن .
    برای دستور تبدیل ( IntToStr ) از اونی استفاده کن که Int64 رو پشتیبانی می کنه .

  6. #6
    کاربر دائمی
    تاریخ عضویت
    شهریور 1387
    محل زندگی
    کاشان
    پست
    809

    نقل قول: سرریزی غیر عادی داده های عددی

    نقل قول نوشته شده توسط pezhvakco مشاهده تاپیک
    برای دستور تبدیل ( IntToStr ) از اونی استفاده کن که Int64 رو پشتیبانی می کنه .
    از چه دستوری استفاده کنم به غیر از IntToStr ؟

  7. #7

    نقل قول: سرریزی غیر عادی داده های عددی

    از چه دستوری استفاده کنم به غیر از IntToStr ؟
    UIntToStr؛ البته اگر مقادیر مورد نظر شما فقط مثبت هستند.

    در هر حال، مشکل کد شما در بالا به خاطر IntToStr هست، چون اون تابع مقدار ورودی را به Integer تبدیل میکنه، و چون مقدار ورودی شما بیشتر از حد مجاز Integer هست، Overflow رخ میده.


    وَ سَيَعْلَمُ الَّذِينَ ظَلَمُوا [آل محمد حقهم] أَيَّ مُنْقَلَبٍ يَنْقَلِبُونَ - الشعراء (227)
    و ظالمین [حق آل محمد (ص) ] به زودی خواهند دانست که به کدام بازگشتگاه بازخواهند گشت.

  8. #8
    کاربر دائمی
    تاریخ عضویت
    شهریور 1387
    محل زندگی
    کاشان
    پست
    809

    نقل قول: سرریزی غیر عادی داده های عددی

    آقای کشاورز ممنون ولی من از این تعجب می کنم که چرا وقتی متغیر GB رو با عدد صحیح 1073741824 ضرب می کنم سرریزی رخ میده ولی وقتی عدد 1073741824 رو با یه ثابت از نوع Int64 تعریف میکنم (البته راهنمایی دوست عزیز آقای Ashayeri)وبعد ثابت رو با GB ضرب می کنم مشکل حل میشه .

    لطفا تصاویر رو نگاه کنید

    حالت Overflow و صحیح
    عکس های ضمیمه عکس های ضمیمه

  9. #9

    نقل قول: سرریزی غیر عادی داده های عددی

    وقتی می خوای از دستور تبدیل مقدار عددی به رشته ای استفاده کنی، IntToStr دو نوع داره که با زدن کلید های ترکیبی Ctrl+Space مقدار ورودی قابل قبول هر کدوم رو مشخص کرده .
    شما از اونی که Int64 پشتیبانی می کنه استفاده کن .

  10. #10
    کاربر دائمی
    تاریخ عضویت
    شهریور 1387
    محل زندگی
    کاشان
    پست
    809

    نقل قول: سرریزی غیر عادی داده های عددی

    نقل قول نوشته شده توسط pezhvakco مشاهده تاپیک
    وقتی می خوای از دستور تبدیل مقدار عددی به رشته ای استفاده کنی، IntToStr دو نوع داره که با زدن کلید های ترکیبی Ctrl+Space مقدار ورودی قابل قبول هر کدوم رو مشخص کرده .
    شما از اونی که Int64 پشتیبانی می کنه استفاده کن .
    دوست عزیز مشکل از تبدیل حل شد (پست آقای کشاورز)
    مشکل سر عدد 1073741824 هست که وقتی عدد رو در متغیری از نوع Int64 مقدار دهی نمی کنم حاصل سرریز میشه ؛ همین

    در مورد تابع IntToStr هم حق با شماست دوتا Overload داره که یکی از نوع Integer و یکی از نوع Int64 به عنوان پارامتر ورودی قبول میکنه.

  11. #11

    نقل قول: سرریزی غیر عادی داده های عددی

    مشکل سر عدد 1073741824 هست که وقتی عدد رو در متغیری از نوع Int64 مقدار دهی نمی کنم حاصل سرریز میشه ؛ همین
    علتش اینه که اون ثابت عددی هنوز در محدوده Integer هست، پس کامپایلر آن را به عنوان Integer در نظر میگیره. وقتی در 3 ضرب میشه، از محدوده Integer خارج میشه. هر دو عامل محاسبه Integer هستند، پس نتیجه محاسبه هم Integer خواهد بود. بعد از انجام محاسبه (و Overflow شدن)، نتیجه به Int64 تبدیل میشه، چون شما دارید نتیجه را به یک متغیر Int64 نسبت میدید.

    وقتی ثابت عددی را خودتان صراحتا از نوع Int64 تعریف می کنید، چون یکی از عامل های محاسبه Int64 هست، و یکی دیگه Integer، کامپایلر به طور خودکار نتیجه را به صورت Int64 برگشت میده؛ سپس این مقدار Int64 به متغیر KB که آن هم Int64 هست، اختصاص داده میشه.


    وَ سَيَعْلَمُ الَّذِينَ ظَلَمُوا [آل محمد حقهم] أَيَّ مُنْقَلَبٍ يَنْقَلِبُونَ - الشعراء (227)
    و ظالمین [حق آل محمد (ص) ] به زودی خواهند دانست که به کدام بازگشتگاه بازخواهند گشت.

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •