صفحه 1 از 2 12 آخرآخر
نمایش نتایج 1 تا 40 از 47

نام تاپیک: جابجایی دو متغییر بدون استفاده از متغییر کمکی

  1. #1

    جابجایی دو متغییر بدون استفاده از متغییر کمکی

    سلام

    خواستم به داغ شدن این تایک کمکی کرده باشم . چیزی تو ذهنم نبود . این موضوع رو که در فروم قدیمی هم آورده بودم دوباره اینجا می نویسم. بنابراین برای دوستان قدیمی نیست :wink:
    چطور جای دو متغییر را بدون استفاده از متغییر سوم عوض کنیم?
    جواب یک الگوریتم ساده ( و خوشگل) .

  2. #2
    با عرض ادب:
    این جور سوالات خیلی حال می ده این یکی از سوالاتیه که هر بار که برنامه نویسی جایی درس می دم می گم. اینم جواب:
    a+b->a
    a-b->b
    a-b->a

    حالا این رو بگید: بدون استفاده از if در «برنامه خودتان» برنامه ای بنویسید که از بین دو عدد کوچکتر و بزرگتر را پیدا کند.(تمام عملگر ها و توابع ریاضی در کامپایلر تعریف شده اند)

    اگه از این ها دارید باز هم بگید :)

    یه عشق برنامه نویسی خفن

  3. #3
    کاربر دائمی
    تاریخ عضویت
    مرداد 1382
    محل زندگی
    تهران
    پست
    484
    برای جابجا کردن دو تا متغیر با هر اندازه و هر نوعی:
    A <- A xor B
    B <- A xor B
    A <- A xor B


    shaniaki جان بهتره موضوع جدید رو در تاپیک جدید عنوان کنیم.

  4. #4
    نقل قول نوشته شده توسط shaniaki
    حالا این رو بگید: بدون استفاده از if در «برنامه خودتان» برنامه ای بنویسید که از بین دو عدد کوچکتر و بزرگتر را پیدا کند.(تمام عملگر ها و توابع ریاضی در کامپایلر تعریف شده اند)
    به وسیله GwBasic

    10 INPUT "INPUT (a, b) ?",A,B
    20 PRINT -((A>B)*A+(B>A)*B)

    به وسیله Pascal

    Program demo;
    var
    a,b :integer;
    begin
    readln(a,b);
    writeln(ord(a>b)*a+ord(b>a)*b& #41;;
    end.


    :idea: در این برنامه از این خاصیت استفاده شده است که مقایسه A>B در پاسکال True یا Falseو در زبانهای Basicبرای درست مقدار 1- (منفی یک) و اشتباه 0 برمی گرداند :P

  5. #5


    جالب بود

    اما قابل قبول نیست علیرضا جان.
    اگر سورس تابع ord را برای مثال نگاه کنی نزدیک به 40 یا 50 تا IF چاق و چله می بینی :)

    اگر از تابع بخوای استفاده کنی اونم نبایئ IF داشته باشه.
    ( البته اونطوری که مد نظر دوستمون بود :wink: )

  6. #6
    کاربر دائمی
    تاریخ عضویت
    بهمن 1381
    محل زندگی
    Iran-Tehran
    پست
    175
    سلام
    این هم جوابش :
      max=((a + b) + abs(a - b)) / 2                                                
    min=((a + b) - abs(a - b)) / 2

    البته منظور از abs قدر مطلق است.

  7. #7
    نقل قول نوشته شده توسط v_shalchian
      max=((a + b) + abs(a - b)) / 2                                                
    min=((a + b) - abs(a - b)) / 2

    البته منظور از abs قدر مطلق است.
    دوست عزیز اصلاٌ قبول نیست :mrgreen:
    چون توی زبانهای برنامه نویسی فکر کنم برای تابع قدر مطلق از if استفاده می کند و بنا به گفته آقا امید قبول نیست :!:
    :idea: باید برای قدر مطلق کردن بدون IF یک راه بگی :mrgreen:

  8. #8
    نقل قول نوشته شده توسط (امید)
    اگر سورس تابع ord را برای مثال نگاه کنی نزدیک به 40 یا 50 تا IF چاق و چله می بینی :)

    اگر از تابع بخوای استفاده کنی اونم نبایئ IF داشته باشه.
    دوست عزیز
    در مورد Ord من بورلند پاسکال الان ندارم که ببینم تابع Ord داخل یونیتSystem از If
    استفاده کرده یا نه
    ولی تا جایی که یادم می یاد این یونیت با زبان ماشین نوشته شده و زبان ماشین If ندارد! :lol:
    :!: توی یونیتSystem دلفی هم تعریف این تابع را ندیدم
    ولی در ابتدای آن نوشته:

    unit System; { Predefined constants, types, procedures, }
    { and functions (such as True, Integer, or }
    { Writeln) do not have actual declarations.}
    { Instead they are built into the compiler }
    { and are treated as if they were declared }
    { at the beginning of the System unit. }


    که فکر کنم تابع ord جزء این هااست! :mrgreen:
    ولی باشه این هم یک راه دیگه
    اگه باز هم IF داشت بگو

    Program demo;
    var
    a,b :integer;
    begin
    readln(a,b);
    writeln(integer(a>b)*a+integer(b>a )*b);
    end.

  9. #9
    کاربر دائمی
    تاریخ عضویت
    مرداد 1382
    محل زندگی
    تهران
    پست
    484
    برای پایان دادن به این اختلاف نظرها صورت مسئله‌‌ رو به این صورت در نظر بگیرید:

    از بین دو عدد A و B کوچکترین و بزرگترین عدد را بدون استفاده از هرگونه مقایسه ضمنی یا عینی تعیین کنید.

  10. #10
    کاربر دائمی
    تاریخ عضویت
    مرداد 1382
    محل زندگی
    تهران
    پست
    484
    نقل قول نوشته شده توسط ali11ali112000
    ... این یونیت با زبان ماشین نوشته شده و زبان ماشین If ندارد! ...
    ماشینهایی محاسبی که در گروه کامپیوترها قرار می‌گیرند حداقل یک دستور انشعاب شرطی دارند.

  11. #11
    کاربر دائمی
    تاریخ عضویت
    بهمن 1381
    محل زندگی
    Iran-Tehran
    پست
    175
    نقل قول نوشته شده توسط ali11ali112000

    دوست عزیز اصلاٌ قبول نیست :mrgreen:
    چون توی زبانهای برنامه نویسی فکر کنم برای تابع قدر مطلق از if استفاده می کند و بنا به گفته آقا امید قبول نیست :!:
    :idea: باید برای قدر مطلق کردن بدون IF یک راه بگی :mrgreen:
    اینم یه روش ابداعی خودم برای محاسبه قدر مطلق بدون if:
     abs=(2*floor(atan(atan(atan(x&  #41;)))+1)*x 

    منظور از floor جزء صحیح و منظور از atan آرکتانژانت است.

  12. #12
    نقل قول نوشته شده توسط v_shalchian
     abs=(2*floor(atan(atan(atan(x&  #41;)))+1)*x 

    منظور از floor جزء صحیح و منظور از atan آرکتانژانت است.
    دوست عزیز این دیگه بد تر شد که ! :wink:

  13. #13
    کاربر دائمی
    تاریخ عضویت
    بهمن 1381
    محل زندگی
    Iran-Tehran
    پست
    175
    دوست عزیز این دیگه اصلا هم بدتر نشد چون کاملا درسته و هیچ دستور if هم به کار نرفته


    abs=(2*floor(0.5*(atan(x))  )+1)*x 

  14. #14
    نقل قول نوشته شده توسط v_shalchian
    دوست عزیز این دیگه اصلا هم بدتر نشد چون کاملا درسته و هیچ دستور if هم به کار نرفته


    abs=(2*floor(atan(0.5*(atan(x&  #41;)))+1)*x 
    خوب دوست عزیز تابع arctan و جزء صحیح بنویس که داخلش if نباشه :oops:
    چون توی زبانهای برنامه نویسی برای نوشتن این توابع فکر کنم از if استفاده می کنند :oops:
    و بنا به گفته آقا امید ...

  15. #15
    نقل قول نوشته شده توسط DelphiArea
    ماشینهایی محاسبی که در گروه کامپیوترها قرار می‌گیرند حداقل یک دستور انشعاب شرطی دارند.
    من زبان ماشین بلد نیستم ولی به بخش
    <span dir=ltr>80x86 Instructions</span>
    از کتاب
    <span dir=ltr>
    the 80x86 IBM PC
    and Compatible
    Computers
    (Volume I)
    Assembly Language
    Programing on the IBM PC,
    PS,and Compatibles

    Muhammad Ali Mazidi
    Janice Gillispie Mazidi</span>
    نگاه کردم ولی if ندیدم!
    و پاسکال هم Compatible 80x86

  16. #16
    نقل قول نوشته شده توسط DelphiArea
    از بین دو عدد A و B کوچکترین و بزرگترین عدد را بدون استفاده از هرگونه مقایسه ضمنی یا عینی تعیین کنید.
    این هم یک روش :
    البته برای زمانی که دادهها از نوع Longint باشد :lol: (و بدون متغییر کمکی :lol: :lol: :lol: )

    program minmaxd2;
    &#123;$APPTYPE CONSOLE&#125;
    uses
    SysUtils;
    var
    a,b&#58;longint;
    begin
    readln&#40;a,b&#41;;
    writeln&#40;'max=',&#40;2*a-&#40;&#40;a-b&#41; shr 31&#41;*2*&#40;a-b&#41;&#41; shr 1&#41;;
    writeln&#40;'min=',&#40;2*b+&#40;&#40;a-b&#41; shr 31&#41;*2*&#40;a-b&#41;&#41; shr 1&#41;;
    readln;
    end.

    اگر به این برنامه خوب دقت کنید از روش جناب v_shalchian استفاده شده + یک کم تغییرات برای abs

    //***************************
    :!: البته دوست دارم دیگر دوستان در این باره نظر بدهند
    و راه حل های دیگری ارائه بدهند
    و هیچ کس از اینکه درباره جوابش نظر بدهیم ناراحت نشود

    موفق باشید

  17. #17


    احسنت به این برنامه نویسهای خوب(علیرضا و v_shalchian و لاغیر ... ) 8)

    علیرضا جان تابع ord رو می تونی سورسش رو تو خود دلفی ببینی.

    writeln(integer(a>b)*a+integer(b>a)*b);
    راه حل خیلی قشنگیه ولی تابع integer هم IF داره ( بالای 30 تا :) )

    برای راه حل آخری هر کار کردم IF ی پیدا نکردم :D .
    حالا باید دید آقای شنیکی چه الگوریتمی رو در نظر دارن.

    :)

  18. #18
    کاربر دائمی
    تاریخ عضویت
    مرداد 1382
    محل زندگی
    تهران
    پست
    484
    نقل قول نوشته شده توسط ali11ali112000
    نقل قول نوشته شده توسط DelphiArea
    ماشینهایی محاسبی که در گروه کامپیوترها قرار می‌گیرند حداقل یک دستور انشعاب شرطی دارند.
    من زبان ماشین بلد نیستم ولی به بخش
    <span dir=ltr>80x86 Instructions</span>
    از کتاب
    <span dir=ltr>
    the 80x86 IBM PC
    and Compatible
    Computers
    (Volume I)
    Assembly Language
    Programing on the IBM PC,
    PS,and Compatibles

    Muhammad Ali Mazidi
    Janice Gillispie Mazidi</span>
    نگاه کردم ولی if ندیدم!
    و پاسکال هم Compatible 80x86
    مسلما در یک زبان ماشین نمی‌توانید دستورات زبانهای سطح بالا یا متوسط را به همان شکل ببینید. در اکثر موارد یک دستور از زبانهای سطح بالا به چندین دستور ماشین ترجمه می‌شوند اما بطور استثنا دستورالعمل اگر٬ مترادف خود به عنوان پرش شرطی را در زبان ماشین دارد.

  19. #19
    با عرض ادب:

    الگوریتم جالبی است فقط تنها مورد آن همان طور که اشاره کردید خاص بودن آن برای یک نوع داده است که با کمی تغییر به دیگر داده ها نیز قابل تعمیم است.
    به طور کلی چون اساس شرط گیت های منطقی است فکر نمی کنم از راه محاسباتی صرف یک راه حل کلی برای تمامی حالات(هر ماشینی و هر زبانی) بتوان داد اما یک راه آن همانطور که اشاره شد تقریب تابع با استفاده از توابع و محاسبات ریاضی ابتدایی است. راهی که گفته ششدتقریب با استفاده از atan بود که فکر جالبی بود با استفاده از بسط ها(تیلور و ...) هم می توان به آن نزدیک شد.
    البته من چون به این جا ها رسیده بودم سعی کردم سوال را طوری مطرح کنم که همان جواب اول( با abs) منظور نظر باشد ولی حالا که به این جا رسیده ایم اگر کسی راه حل بهتری سراغ دارد بگوید ما که تا همین جا متوقف شدیم.

    یه عشق برنامه نویسی خفن.

  20. #20
    در زبان اسمبلی برای درست کردن یک شرط از دو دستور Cmp و Jump استفاده میشه و برای فهمیدن آن شما یک تیکه برنامه بنویسید مثل زیر :

    procedure TForm1.FormCreate&#40;Sender&#58; TObject&#41;;
    var
    a,b&#58;Integer;
    begin
    a&#58;=1;
    b&#58;=1;
    if a=b then begin
    beep;
    end;
    end;


    و بعد روی خطی که if قرار دارد Berakpoint بگذارید و برنامه را اجرا کنید و وقتی برنامه روی Breakpoint ایستاد به منوی View\Debug Winodws بروید و CPU رو انتخاب کنید و اونجا میتونید همزمان هم Assembly و هم زبان ماشین هر دستور Delphi رو ببینید !
    و حتی دستوراتی که شما سورس شو ندارید (مثل Kernel Windows )رو به زبان ماشین و اسمبلی ببینید !

    BA 01 00 00 00  mov edx,$00000001
    3B D0 cmp edx,dax
    7505 jnz &#40;+$05&#41;
    E8 25 F1 Fb FF call Beep
    C3 ret


    و اگر شما از F8 استفاده کنید Step Over جلو میره (داخل Call نمیشود)
    و اگر از F7 استفاده کنید Trace into جلو میره و داخل Call هم میره!

  21. #21
    نقل قول نوشته شده توسط Anonymous
    سلام دوستان
    برای اجرای این کد یک Button و دو Editbox روی فرمتون قرار بدید. داخل ادیت باکسها اعدادی رو که قصد مقایسه داریر رو بنویسید.تابع ماکزیمم دو عدد رو برمیگردونه بدون کنترل شرطی.اگر خطی رو که جلوش // هست رو هم به برنامه برگردونید، مقدار مینیمم دو عدد برگشت داده میشه.


    procedure TForm1.Button1Click&#40;Sender&#58; TObject&#41;;
    var
    buf&#58; array&#91;0..1&#93;of integer;
    i,a,b&#58; Word;
    begin
    a &#58;= StrToInt&#40;Edit1.Text&#41;;
    b &#58;= StrToInt&#40;Edit2.Text&#41;;
    buf&#91;0&#93; &#58;= StrToInt&#40;Edit1.Text&#41;;
    buf&#91;1&#93; &#58;= StrToInt&#40;Edit2.Text&#41;;
    asm
    push ax
    push bx
    push cx
    push dx
    xor a,$8000
    xor b,$8000
    mov ax,a
    xor ax,b
    mov dx,0
    mov cx,16
    clc
    @aa&#58;
    mov bx,0
    shl ax,1
    jc @carry_sets
    inc dl
    loop @aa
    @carry_sets&#58;
    inc dl
    mov cl,16
    sub cl,dl
    mov ax,a
    xor ax,b
    mov bx,a
    shr bx,cl
    shr ax,cl
    and ax,1
    and bx,1
    xor bx,ax
    // xor bx,1
    mov i,bx
    pop dx
    pop cx
    pop bx
    pop ax
    end;
    Caption &#58;= IntToStr&#40;buf&#91;i&#93;&#41;;
    end;

    اگر قصد تغییر کد رو دارید، به هیچ وجه Push و Pop ها رو از کد برندارید.
    ای بابا. این همه زور زدم اینو نوشتم آخر سر بنام مهمان پست شد. :cry: :wink:

  22. #22
    کاربر دائمی
    تاریخ عضویت
    مرداد 1382
    محل زندگی
    تهران
    پست
    484
    نقل قول نوشته شده توسط SyntaxCheck
    نقل قول نوشته شده توسط Anonymous
    سلام دوستان
    برای اجرای این کد یک Button و دو Editbox روی فرمتون قرار بدید. داخل ادیت باکسها اعدادی رو که قصد مقایسه داریر رو بنویسید.تابع ماکزیمم دو عدد رو برمیگردونه بدون کنترل شرطی.اگر خطی رو که جلوش // هست رو هم به برنامه برگردونید، مقدار مینیمم دو عدد برگشت داده میشه.


    procedure TForm1.Button1Click&#40;Sender&#58; TObject&#41;;
    var
    buf&#58; array&#91;0..1&#93;of integer;
    i,a,b&#58; Word;
    begin
    a &#58;= StrToInt&#40;Edit1.Text&#41;;
    b &#58;= StrToInt&#40;Edit2.Text&#41;;
    buf&#91;0&#93; &#58;= StrToInt&#40;Edit1.Text&#41;;
    buf&#91;1&#93; &#58;= StrToInt&#40;Edit2.Text&#41;;
    asm
    push ax
    push bx
    push cx
    push dx
    xor a,$8000
    xor b,$8000
    mov ax,a
    xor ax,b
    mov dx,0
    mov cx,16
    clc
    @aa&#58;
    mov bx,0
    shl ax,1
    jc @carry_sets
    inc dl
    loop @aa
    @carry_sets&#58;
    inc dl
    mov cl,16
    sub cl,dl
    mov ax,a
    xor ax,b
    mov bx,a
    shr bx,cl
    shr ax,cl
    and ax,1
    and bx,1
    xor bx,ax
    // xor bx,1
    mov i,bx
    pop dx
    pop cx
    pop bx
    pop ax
    end;
    Caption &#58;= IntToStr&#40;buf&#91;i&#93;&#41;;
    end;

    اگر قصد تغییر کد رو دارید، به هیچ وجه Push و Pop ها رو از کد برندارید.
    ای بابا. این همه زور زدم اینو نوشتم آخر سر بنام مهمان پست شد. :cry: :wink:
    یک دونه اگر تو کدی که نوشتی وجود داره: jc @carry_sets که معادل کد زیر هست:

    c&#58; boolean;

    if c then goto carry_set;

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

    function Min&#40;A, B&#58; Integer&#41;&#58; Integer;
    asm
    mov eax, A
    cmp eax, B
    jl @finish
    mov eax, B
    @finish&#58;
    end;

    function Max&#40;A, B&#58; Integer&#41;&#58; Integer;
    asm
    mov eax, A
    cmp eax, B
    ja @finish
    mov eax, B
    @finish&#58;
    end;

  23. #23
    با عرض ادب:
    حق با جناب DelphiArea است.
    همانطور که گفتم اساس دستورات شرطی که در برنامه نویسی استفاده می کنیم گیت های منطقی پردازنده است و دستوراتی مانند xor و cmp همگی از این دسته اند.

    یه عشق برنامه نویسی خفن

  24. #24
    خوب خوشحالم که بحث و صحبت به اینجا رسید. دوستان بنده یه توضیح کوچولو راجع به دستورات مقایسه ای و انشعابی میدم. دسته اول JZ,JNZ,JO,JNO,JS,JNS,JC,JNC,JP,JNP و در نهایت دسته دوم با یک عضو JMP همگی جزو گروه دستورات خانواده انشعابها (Branches)هستند. JMP انشعاب قطعی(Unconditional Branch) هست و سری اول دستورات که ذکر کردم جزو انشعابات غیر قطعی.البته شرطی خواندن این دستورات انشعابی اصلا کار صحیحی نیست و اینها صرفا پرشهای انشعابی قطعی و یا غیر قطعی هستند. اما دستور شرطی به تنهایی در اسمبلی معنی نداره و به یک بلوک دستور ،ممکنه که شرط گفته بشه، زمانی که یک دستور مقایسه ای و یک دستور انشعابی همراه هم باشند. در زیر چند حالت ممکن رو برای روشن تر شدن منظورم ذکر میکنم:
    1) در ابتدای بلوک CMP انجام شود و سپس از دسته انشعابی اول برای جهش استفاده شود این حالت همون IF در زبانهای سطح بالاست.(که طبق راهی که دوست عزیز آقای مشاطان عرض کردند میتونید الگوریتم IF رو مشاهده کنید که یک دستور نیست و مجموعه ای از دو دستور CMP و یک دستور انشعابی هست)
    2) در ابتدای بلوک CMP انجام شود و از هیچ دستور انشعابی در ادامه استفاده نشود.این حالت مقایسه محض نام دارد و صرفا جهت تنظیم فلاگها برای مصارف بعدی کاربرد دارد.
    3) در بلوک صرفا از دستورات انشعابی(Branches) استفاده شود و در هیچ جای بلوک CMP انجام نشود. این حالت مانند انجام یک پرش از یک قسمت برنامه به یک قسمت دیگر برنامه ممکن است باشد.

    اما بنده هم به خوبی میدونم که با یک CMP و یک بلوک کوچیک میشه عدد Max و Min و بدست آورد اما وقتی مسئله مطرح شده توی این تاپیک رو دیدم این الگوریتم رو روش کار کردم که از فرض مسئله تبعیت بکنه.اما آقا کامبیز اگر مثال شما رو (if c then goto carry_set) نگاه کنیم به وضوح از IF در اون استفاده شده و الگوریتم پروسه ای که من نوشتم اصلا همچین کاری رو نمیکنه و یا مثال حضرتعالی با CMP.
    اما دوست عزیز آقای Shaniaki ، اساس بله اما خود دستور شرط نه.
    اما مسئله اصلی که گویا اصلا بهش توجهی نشده الگوریتم بکار رفته در این پروسه هست. من گفتم الان رفقا اینو که ببینن کلی راجع بهش صحبت میشه. اگر دو عدد رو به مبنای دو ببریم و اون دوتا رو با هم XOR کنیم آخرین بیت روشن جواب بیتی از دو عدد خواهد بود که معین کننده عدد Max و یا Min هست. بزارید با یه مثال بگم:

    01010111=87 عدد 0 ام
    01100101=101 عدد 1 ام
    _____________XOR
    00110010=50

    بیت سوم از سمت راست همون بیتی از 87و101 هست که اگر XOR همین بیت (1) با همین بیت از عدد اول یعنی (0) انجام بشه عدد 1 بدست میاد که این امر نشون دهنده اونه که مقدار MAX همون عدد 1 ام هست. حالا عملیاتی در ابتدا برای تصحیح بیت علامت انجام شده که برای اعداد اینتیجر همون XOR کردن با $8000 هست و یا برای برگشت مینیمم که XOR کردن جواب با 1 هست(خط //).

  25. #25
    کاربر دائمی
    تاریخ عضویت
    مرداد 1382
    محل زندگی
    تهران
    پست
    484
    نقل قول نوشته شده توسط SyntaxCheck
    خوب خوشحالم که بحث و صحبت به اینجا رسید. دوستان بنده یه توضیح کوچولو راجع به دستورات مقایسه ای و انشعابی میدم. دسته اول JZ,JNZ,JO,JNO,JS,JNS,JC,JNC,JP,JNP و در نهایت دسته دوم با یک عضو JMP همگی جزو گروه دستورات خانواده انشعابها (Branches)هستند. JMP انشعاب قطعی(Unconditional Branch) هست و سری اول دستورات که ذکر کردم جزو انشعابات غیر قطعی.البته شرطی خواندن این دستورات انشعابی اصلا کار صحیحی نیست و اینها صرفا پرشهای انشعابی قطعی و یا غیر قطعی هستند. اما دستور شرطی به تنهایی در اسمبلی معنی نداره و به یک بلوک دستور ،ممکنه که شرط گفته بشه، زمانی که یک دستور مقایسه ای و یک دستور انشعابی همراه هم باشند. در زیر چند حالت ممکن رو برای روشن تر شدن منظورم ذکر میکنم:
    1) در ابتدای بلوک CMP انجام شود و سپس از دسته انشعابی اول برای جهش استفاده شود این حالت همون IF در زبانهای سطح بالاست.(که طبق راهی که دوست عزیز آقای مشاطان عرض کردند میتونید الگوریتم IF رو مشاهده کنید که یک دستور نیست و مجموعه ای از دو دستور CMP و یک دستور انشعابی هست)
    2) در ابتدای بلوک CMP انجام شود و از هیچ دستور انشعابی در ادامه استفاده نشود.این حالت مقایسه محض نام دارد و صرفا جهت تنظیم فلاگها برای مصارف بعدی کاربرد دارد.
    3) در بلوک صرفا از دستورات انشعابی(Branches) استفاده شود و در هیچ جای بلوک CMP انجام نشود. این حالت مانند انجام یک پرش از یک قسمت برنامه به یک قسمت دیگر برنامه ممکن است باشد.

    اما بنده هم به خوبی میدونم که با یک CMP و یک بلوک کوچیک میشه عدد Max و Min و بدست آورد اما وقتی مسئله مطرح شده توی این تاپیک رو دیدم این الگوریتم رو روش کار کردم که از فرض مسئله تبعیت بکنه.اما آقا کامبیز اگر مثال شما رو (if c then goto carry_set) نگاه کنیم به وضوح از IF در اون استفاده شده و الگوریتم پروسه ای که من نوشتم اصلا همچین کاری رو نمیکنه و یا مثال حضرتعالی با CMP.
    اما دوست عزیز آقای Shaniaki ، اساس بله اما خود دستور شرط نه.
    اما مسئله اصلی که گویا اصلا بهش توجهی نشده الگوریتم بکار رفته در این پروسه هست. من گفتم الان رفقا اینو که ببینن کلی راجع بهش صحبت میشه. اگر دو عدد رو به مبنای دو ببریم و اون دوتا رو با هم XOR کنیم آخرین بیت روشن جواب بیتی از دو عدد خواهد بود که معین کننده عدد Max و یا Min هست. بزارید با یه مثال بگم:

    01010111=87 عدد 0 ام
    01100101=101 عدد 1 ام
    _____________XOR
    00110010=50

    بیت سوم از سمت راست همون بیتی از 87و101 هست که اگر XOR همین بیت (1) با همین بیت از عدد اول یعنی (0) انجام بشه عدد 1 بدست میاد که این امر نشون دهنده اونه که مقدار MAX همون عدد 1 ام هست. حالا عملیاتی در ابتدا برای تصحیح بیت علامت انجام شده که برای اعداد اینتیجر همون XOR کردن با $8000 هست و یا برای برگشت مینیمم که XOR کردن جواب با 1 هست(خط //).
    ممنون از توضیحات.

    منم در توضیح کد خودم اینو بگم که به جای دستور CMP میشه از دستور SUB هم استفاده کرد. تنها فرق ماهیتی که این دو دستور با هم دارند اینه که CMP رجیستر اول رو تغییر نمیده ولی SUB تغییر میده. یعنی کدی رو که در بالا نوشتم رو میشه بدون استفاده از CMP بصورت زیر هم نوشت:

    function Min&#40;A, B&#58; Integer&#41;&#58; Integer;
    asm
    mov eax, A &#123; eax &lt;- A &#125;
    sub eax, B &#123; eax &lt;- eax - B &#125;
    jl @finish &#123; if eax &lt; 0 goto finish &#125;
    xor eax, eax &#123; eax &lt;- 0 &#125;
    @finish&#58;
    add eax, B &#123; eax &lt;- eax + B &#125;
    end;

    function Max&#40;A, B&#58; Integer&#41;&#58; Integer;
    asm
    mov eax, A &#123; eax &lt;- A &#125;
    sub eax, B &#123; eax &lt;- eax - B &#125;
    ja @finish &#123; if eax > 0 goto finish &#125;
    xor eax, eax &#123; eax &lt;- 0 &#125;
    @finish&#58;
    add eax, B &#123; eax &lt;- eax + B &#125;
    end;

  26. #26
    سلام
    صحبت شما کاملا صحیحه اما به یک نکته توجه کنید من انواع انشعابهای مطلق و غیر مطلق رو نام بردم اما شما از یک دستور پرش شرطی استفاده کردید (JL). پرشهای شرطی (comparison) عبارتند از:

    JE,JNE,JL,JNGE,JLE,JNG,JG,JNLE,JGE,JNL,JB,JNAE,JBE ,JNA,JA,JNBE,JAE,JNB

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

    پیروز باشید
    ________________
    راستی آقا کامبیز من یه تشکر بابت یونیت تاریخ بشما بدهکارم.ممنون :wink:

  27. #27
    کاربر دائمی
    تاریخ عضویت
    مرداد 1382
    محل زندگی
    تهران
    پست
    484
    نقل قول نوشته شده توسط SyntaxCheck
    سلام
    صحبت شما کاملا صحیحه اما به یک نکته توجه کنید من انواع انشعابهای مطلق و غیر مطلق رو نام بردم اما شما از یک دستور پرش شرطی استفاده کردید (JL). پرشهای شرطی (comparison) عبارتند از:

    JE,JNE,JL,JNGE,JLE,JNG,JG,JNLE,JGE,JNL,JB,JNAE,JBE ,JNA,JA,JNBE,JAE,JNB

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

    پیروز باشید
    ________________
    راستی آقا کامبیز من یه تشکر بابت یونیت تاریخ بشما بدهکارم.ممنون :wink:
    خوشحالم که از یونیت تاریخ استفاده می‌‌کنید٬ قابل شما رو نداره.

    من صحبتم اصلا" سر این نیست که کدوم کد بهینه تره. اصلا سوال راجب این مورد نیست. من سعی دارم این رو بگم که هر گونه انشعابی در کد حاصل به معنای اینه که جواب صورت مسئله داده نشده. وگرنه فرقی بین انشعاب بر اساس Carry Flag و Sign Flag وجود نداره و هر دو بر اساس یک بیت تصمیم می‌گیرند که انشعاب رو انجام بدهند یا دستورالعمل بعدی رو.

    من که از همون اول گفتم که کد من جواب مسئله نیست و البته کد شما هم نمی‌تونه جواب باشه. کد ماشینی می‌تونه جواب باشه که هیچ انشعابی درش وجود نداشته باشه و دستورات بصورت متوالی انجام بشوند (یا در زبان الگوریتمی: فقط از ساختار توالی و بدون استفاده از ساختارهای تکرار و شرط به جواب برسیم).

    امیدوارم توانسته باشم رفع سؤتفاهم کنم.

  28. #28
    سلام
    در انشعابها هیچ شرطی کنترل نمیشه و این مسئله درکش کمی مشکله.ما چون میبینیم مثلا در JC زمانی که Carry Flag ست میشه کنترل به آفست دیگه ای منتقل میشه تصور شرط برامون بوجود میاد. این مسئله در حقیقت شرط. درک عملی تفاوت Branch ها و comparison ها و اینکه چرا اینها شرطی هسنت و اونها نیستن مشکله. اما واقعیت اینه که Branch ها نیستند.

  29. #29
    کاربر دائمی
    تاریخ عضویت
    مرداد 1382
    محل زندگی
    تهران
    پست
    484
    نقل قول نوشته شده توسط SyntaxCheck
    سلام
    در انشعابها هیچ شرطی کنترل نمیشه و این مسئله درکش کمی مشکله.ما چون میبینیم مثلا در JC زمانی که Carry Flag ست میشه کنترل به آفست دیگه ای منتقل میشه تصور شرط برامون بوجود میاد. این مسئله در حقیقت شرط. درک عملی تفاوت Branch ها و comparison ها و اینکه چرا اینها شرطی هسنت و اونها نیستن مشکله. اما واقعیت اینه که Branch ها نیستند.
    :shock: :!: :?:

    ما یک مقایسه رو به غیر از تغییر مسیر اجرای برنامه برای چه کاری انجام می‌دهیم؟
    حتی در کد زیر:

    B&#58; Boolean;

    B &#58;= X > Y;

    هم انشعاب وجود داره.

  30. #30
    در اسمبلی به تمام دستوارت JE,JNE,JL,JNGE,JLE,JNGو ... Jump گفته میشه
    ما در اسمبلی دو جور Jump داریم Near و ّFar و همانطوری که میدونید Jump دستوری که غیر
    مستقیم میتونه رجیستر EIP را عوض کند برای همین دستور بسیار کلیدی هست

    به Jump های که به جای Address از عدد نسبی استفاده میکنند Near گفته میشه
    به Jump های که مستقیم از Address استفاده میکنند Far گفته مبشه

  31. #31
    نقل قول نوشته شده توسط (امید)
    علیرضا جان تابع ord رو می تونی سورسش رو تو خود دلفی ببینی.
    راه حل خیلی قشنگیه ولی تابع integer هم IF داره ( بالای 30 تا :) )
    :?: می شود بگویید داخل چه فایلی است؟ :cry:
    //************************************
    به پاسکال زبان کنترل دقیق دادهها لقب داده اند و مانند زبانهای نسل Basic نمی توان یک متغییر Boolean را به یک Integer نسبت داد
    که من برای قالب ریزی یک Boolean بهInteger از توابع Ord یاIntegerاستفاده کردم
    /*******************
    ولی خوب برای این کار به صورت دستی!




    program minmax123;

    &#123;$APPTYPE CONSOLE&#125;

    uses
    SysUtils;

    var
    a,b &#58;integer;
    ab,ba&#58;^byte;
    Bolab,bolba&#58;boolean;
    begin
    readln&#40;a,b&#41;;
    bolab&#58;=a>b;
    bolba&#58;=b>a;
    ab&#58;=@bolab;
    ba&#58;=@bolba;
    writeln&#40;ab^*a+ba^*b&#41;;
    readln;
    end.



    ولی اگر

    نقل قول نوشته شده توسط DelphiArea
    حتی در کد زیر:

    B&#58; Boolean;

    B &#58;= X > Y;

    هم انشعاب وجود داره.
    با این روش: :lol:

    Program minmax2;

    &#123;$APPTYPE CONSOLE&#125;

    uses
    SysUtils;

    var
    a,b,c,t &#58;integer;

    d&#58;^byte;
    begin
    readln&#40;a,b&#41;;
    d&#58;=@c;

    c&#58;=b-a ;
    d^&#58;=d^ shr 7;
    t&#58;=d^*a;

    c&#58;=a-b ;
    d^&#58;=d^ shr 7;

    t&#58;=t+d^*b;
    writeln&#40;t&#41;;
    readln;
    end.

    موفق باشید

  32. #32
    دوست عزیزم آقا کامبیز دلیل استفاده از CMP بستگی به برنامه نویس داره. معمول اون پرش کردن در ادامه بلوک هست اما نه مطلق در جواب قبلیم این نوع رو در قسمت دوم عرض کردم.

    اما دوست عزیز جناب مشاطان یه توضیحی رو اینجا لازمه عرض کنم گرچه این مطلب ربط چندانی به مسئله نداره. Jump دو نوع نیست بلکه سه نوعه و تعریف انواع اون هم تقریبا چیز دیگریست از اونچه شما عرض کردید:


    There are several variations of the jump instruction&#58;
    _____________SHORT&#58;
    This jump is very limited in range. It can only move up or down
    128 bytes in memory. The advantage of this type is that it uses less
    memory than the others. It uses a single signed byte to store the
    displacement of the jump. The displacement is how many bytes to
    move ahead or behind. &#40;The displacement is added to EIP&#41;. To specify
    a short jump, use the SHORT keyword immediately before the label in
    the JMP instruction.
    _____________NEAR&#58;
    This jump is the default type for both unconditional and conditional
    branches, it can be used to jump to any location in a segment.
    Actually, the 80386 supports two types of near jumps. One
    uses two bytes for the displacement. This allows one to move up or
    down roughly 32,000 bytes. The other type uses four bytes for the
    displacement, which of course allows one to move to any location in
    the code segment. The four byte type is the default in 386 protected
    mode. The two byte type can be specified by putting the WORD keyword
    before the label in the JMP instruction.
    _____________FAR&#58;
    This jump allows control to move to another code segment. This is a
    very rare thing to do in 386 protected mode.

    متن بالا از کتاب
    PC Assembly Language
    Paul A. Carter
    December 12, 2002

  33. #33
    نقل قول نوشته شده توسط SyntaxCheck
    دوست عزیزم آقا کامبیز دلیل استفاده از CMP بستگی به برنامه نویس داره. معمول اون پرش کردن در ادامه بلوک هست اما نه مطلق در جواب قبلیم این نوع رو در قسمت دوم عرض کردم.
    میشه درباره این مورد یک مثال بزنید :wink:
    مخصوصا قسمتی که به "برنامه نویس بستگی داره"

    نقل قول نوشته شده توسط SyntaxCheck
    اما دوست عزیز جناب مشاطان یه توضیحی رو اینجا لازمه عرض کنم گرچه این مطلب ربط چندانی به مسئله نداره. Jump دو نوع نیست بلکه سه نوعه و تعریف انواع اون هم تقریبا چیز دیگریست از اونچه شما عرض کردید:
    در مورد دوم حق با شماست من توی تعاریف جابجا نوشتم راستش من مثل شما از روی کتاب ننوشتم بلکه چیزی که یادم بود رو بیان کردم خیلی خوبه افرادی مثل شما هستند که از روی کتاب میخونند و اشکالات ما رو گوشزد میکنند :)
    اصل کتاب
    http://www.grid.unina.it/Didattica/C...pcasm-book.pdf

    ارادتمند
    مشاطان

  34. #34
    مهمان
    مثال بنده لازم نیست. شما اگر همون کتابی رو که آدرسش رو هم خوشبختانه دارید کمی خوب مطالعه کنید مکانیسم عمل CMP و JMP ها و خیلی چیزهای دیگه رو به خوبی درک میکنید و سوالهای درسی و بدیهی رو اینجا نمیپرسید.در ضمن یک مسئله دیگه بجای ایرادهای اینگونه ای و بیان تفکرات شخصی راجع به دستورات و نوع کاربرد اونها پیشنهاد میکنم به الگوریتم بدست آوردن مقادیر Max و Min که ارائه کردم کمی توجه کنید و اون رو به نقد بزارید. من زمانی که این کد رو نوشتم فکر میکردم که کسانی که این رو مطالعه میکنن توجهشون بیشتر به ساختمان اصلی بلوک هست و فرض بنده بر این بود که بدیهیاتی مانند اونهایی که در مورد Branch ها و ....ذکر کردم رو خواننده بدونه. به هر حال هر چه دوستان باب میلشون هست حتما همان صحیح است و روش ارائه شده از طرف بنده اشتباه و دفاع بنده از این روش در اینجا بیمعناست.

    پیروز و شاد باشید

  35. #35
    کاربر جدید
    تاریخ عضویت
    خرداد 1382
    محل زندگی
    me_a2002@hotmail.com
    پست
    21

    قابل توجه امید خان

    سلام
    آقا امید میشه با روشی که گفتی این دو متغیر را جابجا کنی :twisted:
    int a,b
    a=32000
    b=1000
    :?: :!: :idea:

  36. #36

    Re: قابل توجه امید خان

    نقل قول نوشته شده توسط غریبه2
    سلام
    آقا امید میشه با روشی که گفتی این دو متغیر را جابجا کنی :twisted:
    int a,b
    a=32000
    b=1000
    :?: :!: :idea:

    a=a-b -->a=31000,b=1000
    b=a+b ---> a=31000 , b=32000
    a=b-a --->b=32000 , a=1000

  37. #37
    نقل قول نوشته شده توسط ali11ali112000
    نقل قول نوشته شده توسط (امید)
    علیرضا جان تابع ord رو می تونی سورسش رو تو خود دلفی ببینی.
    راه حل خیلی قشنگیه ولی تابع integer هم IF داره ( بالای 30 تا :) )
    :?: می شود بگویید داخل چه فایلی است؟ :cry:
    کلید Ctrl رو نگه دار بعد با موس روی هر تابع که کلیک کنی سورسش رو می بینی . 8)

    Adios

  38. #38
    نقل قول نوشته شده توسط (امید)
    کلید Ctrl رو نگه دار بعد با موس روی هر تابع که کلیک کنی سورسش رو می بینی . 8)
    آقا امید من این کار را برای Ord & Integer کردم ولی زیر این خط از یونیت system آمد :?: :!: :?: :cry: :cry:
    unit System;

  39. #39
    کاربر دائمی
    تاریخ عضویت
    مرداد 1382
    محل زندگی
    تهران
    پست
    484
    دوستان، اینجا بخش الگوریتم هست. معنیش اینه که اگر قراره برای مسئله‌ای در اینجا راه حلی ارائه بشه٬ اون راه حل باید برای هر ماشین و هر زبان برنامه نویسی صادق باشه.

  40. #40
    چون این بخش بخش الگریتم است :
    در حالت کلی برای بدست آوردن بزرگ ترین عدد بین دو عدد از تابع زیر استفاده می کنیم

    | a a>b
    Max= |
    | b b>a

    یا

    if a>b then max&#58;=a else max&#58;=b;

    که این تابع قابل گسترش به

    Max=a+b+|a-b|/2

    است که اگر خوب دقت شود
    معادل قدر مطلق x برابر ست با

    y=|x|
    if x>0 then Y&#58;=x else Y&#58;=-x;


    /**************************************************
    نقل قول نوشته شده توسط DelphiArea
    از بین دو عدد A و B کوچکترین و بزرگترین عدد را بدون استفاده از هرگونه مقایسه ضمنی یا عینی تعیین کنید.
    اگر منظور این باشد که بدون هیچ عملیات دو شرطی کوچک ترین و بزرگترین این دو عدد را پیدا کنیم چین چیزی محال است و امکان ندارد

    writeln&#40;'max=',&#40;2*a-&#40;&#40;a-b&#41; shr 31&#41;*2*&#40;a-b&#41;&#41; shr 1&#41;;
    writeln&#40;'min=',&#40;2*b+&#40;&#40;a-b&#41; shr 31&#41;*2*&#40;a-b&#41;&#41; shr 1&#41;;

    حتی در این هم دوشرطی وجود دارد
    ولی این کار در داخل دستورات و روش نگهداری اعداد نهفته است
    برای درک بهتر موضوع توجه کنید که معادل بیت علامت دو شرطی به صورت زیر قرار دارد
    برای عدد x:

    if x>0 then &#40;SightFlag off&#41; else &#40;SightFlag Set &#41;

    و هر گز با عملیاتی مثل جمع و ضرب و or , and , xor , xnor ,....
    :idea: بدون یک if نمیتوان این کار را کرد
    البته از نوع ریاضی آن!


    موفق باشید

صفحه 1 از 2 12 آخرآخر

تاپیک های مشابه

  1. تغییر فایل اجرایی در زمان اجرا
    نوشته شده توسط shahram197070 در بخش VB.NET
    پاسخ: 13
    آخرین پست: جمعه 02 اردیبهشت 1390, 18:29 عصر
  2. تغییر شکل آیکن فایل اجرایی
    نوشته شده توسط am_sanatiz در بخش برنامه نویسی در Delphi
    پاسخ: 4
    آخرین پست: سه شنبه 20 تیر 1385, 18:29 عصر
  3. بخش هایی از سایت که زیاد تغییر نمی کنند
    نوشته شده توسط nazaninam در بخش ASP.NET Web Forms
    پاسخ: 10
    آخرین پست: شنبه 17 تیر 1385, 21:43 عصر

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

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