View Full Version : کار با بیتها در فاکس پرو
rezaTavak
دوشنبه 24 دی 1386, 08:37 صبح
زمانی که اسمبلی برنامه می نویسید کار با بیتها بیشتر از یک زبان سطح بالا نمود می کند.
اما کار با بیتها هم جالب است در این سری قصد دارم کار با بیتها و طرفندهایی ابتدایی را بیاموزیم:
BITAND( ) Function (http://barnamenevis.org/html/e03290b3-e96a-421c-8efa-f9b1691b09cb.htm)
BITCLEAR( ) Function (http://barnamenevis.org/html/c3c6ff91-a5c0-47a8-b979-cb9020f13d5a.htm)
BITLSHIFT( ) Function (http://barnamenevis.org/html/82f05d74-808b-43d4-8973-dd5e73e45a6f.htm)
BITNOT( ) Function (http://barnamenevis.org/html/9881350f-b6bb-4a73-9772-95d448de5397.htm)
BITOR( ) Function (http://barnamenevis.org/html/09ff58b4-463e-424e-b3a6-b49349ec84a7.htm)
BITRSHIFT( ) Function (http://barnamenevis.org/html/946ff2f5-7140-4f1a-8fc7-05a74c1aa2d2.htm)
BITSET( ) Function (http://barnamenevis.org/html/0279f322-82f1-4687-82ac-a0d772f25e72.htm)
BITTEST( ) Function (http://barnamenevis.org/html/55285ec7-91ce-480f-ae2b-c3c41c36032e.htm)
BITXOR( ) Function (http://barnamenevis.org/html/b7858458-a38e-492c-b8b6-0d6c42324fb6.htm)
مجموعه ای است که در فاکس پرو داریم.
دقت کنید باید اعداد Integer باشند
خب اولین مثال جالب :
اگر بیتهای یک عدد به سمت چپ شیفت داده شوند به ازای هر شیفت عدد دوبرابر می شود:
a=10
?BITLSHIFT(a,1)
برعکس هنگامی که یک عدد به سمت راست شیفت داده شود عدد نصف خواهد شد:
a=10
?BITRSHIFT(a,1)
rahro
سه شنبه 25 دی 1386, 06:42 صبح
جناب توکل
متشکر میشوم که راهنمایی کنید که این توابع در کجا بیشتر کارایی دارند؟!
میدونید به نظرمیاد میشه با یک فانکشن ساده هم این توابع را نوشت؟!!!!!! حتی با نیم خط فرمان؟!!
مطمئنا باید کارایی زیبایی داشته باشند.
rezaTavak
سه شنبه 25 دی 1386, 07:32 صبح
من در یک پروژه نیاز داشتم حدود ۴۰ متغیر Logical داشته باشم اما میدانید که هر عدد Integer ۳۲ بیت است و هر پس فقط دو متغیر Integer تعریف کردم و با عملگرهای بیتی آنها را ست کردم. یعنی اگر ست شده بود درست و معادل .T. و اگر ست نشده بود نادرست و .F. بود.
یک راه استفاده دیگر این است که شما می توانید محدودیت را در محاسبات هر زبانی از بین ببرید مثلا عملگری بنویسید که دو عدد ۱۰۰ رقمی را با هم جمع کند. البته این در کار ما ممکن است وجود نداشته باشد.
rezaTavak
سه شنبه 25 دی 1386, 07:40 صبح
اما شگرد امروز:
شما برای تعویض دو مقدار اینکار را میکنید:
ltemp = a
a = b
b = lTemp
اما یک روش جالب برای تعویض مقدار در دو متغیر Integer:
a = BITXOR(a,b)
b = BITXOR(a,b)
a=BITXOR(a,b)
جالب است نه؟ در این صورت دیگر هیچ متغیر اضافی تعریف نخواهد شد!
rahro
سه شنبه 25 دی 1386, 10:13 صبح
من در یک پروژه نیاز داشتم حدود ۴۰ متغیر Logical داشته باشم اما میدانید که هر عدد Integer ۳۲ بیت است و هر پس فقط دو متغیر Integer تعریف کردم و با عملگرهای بیتی آنها را ست کردم. یعنی اگر ست شده بود درست و معادل .T. و اگر ست نشده بود نادرست و .F. بود.
یک راه استفاده دیگر این است که شما می توانید محدودیت را در محاسبات هر زبانی از بین ببرید مثلا عملگری بنویسید که دو عدد ۱۰۰ رقمی را با هم جمع کند. البته این در کار ما ممکن است وجود نداشته باشد.
خواهش میکنم اگر ممکن است مطلب را بیشتر باز کنید :کف:
rezaTavak
سه شنبه 25 دی 1386, 11:59 صبح
ببینید فرض کنید شما ۲۸ استان داریم که می خواهیم مثلا وجودتمام بیماریها را در آن نشان دهیم. برای کار عادی شما مجبورید ۲۸ متغیر تعریف کنید که منطقی باشد و آنها را ست کنید.
راه دیگر این است که یک فیلد عددی Integer تعریف کنید و به ازای هر استان یک بیت آنرا ست کنید.
برای جمع دو عدد هم اجازه بدهید برنامه را بنویسم و ازائه می کنم.
rezaTavak
سه شنبه 25 دی 1386, 12:07 عصر
عدد زوج است یا فرد؟
?BITAND(11,1)
?BITAND(12,1)
اگر عدد زوج باشد با ۱ and شود نتیجه صفر است در غیر اینصورت یک.
rahro
چهارشنبه 26 دی 1386, 06:48 صبح
ببینید فرض کنید شما ۲۸ استان داریم که می خواهیم مثلا وجودتمام بیماریها را در آن نشان دهیم. برای کار عادی شما مجبورید ۲۸ متغیر تعریف کنید که منطقی باشد و آنها را ست کنید.
راه دیگر این است که یک فیلد عددی Integer تعریف کنید و به ازای هر استان یک بیت آنرا ست کنید.
برای جمع دو عدد هم اجازه بدهید برنامه را بنویسم و ازائه می کنم.
یعنی به جای هر بیت از یک عدد اینتیجر 32 بیتی میتوانم صفر و یک بگذارم؟!!:متعجب: :متعجب:
ان وقت اگر بخواهیم ببینیم مثلا در بیت 12 چه مقدار قرار دارد یا مقدارش رو عوض کنیم باید چکار کنم؟!!
rezaTavak
چهارشنبه 26 دی 1386, 08:38 صبح
برای ست کردن یا قرار دادن مقدار یک در یک بیت از تابع
BITSET
استفاده می شود مثال کوچکترین عدد Integer
?BITSET(0,31)
چون آخرین بیت بیت علامت است
۲ بتوان ۱۰:
BITSET(0,10)
برای اینکه مقدار یک بیت را صفر کنیم آنرا باید پاک کنیم یعنی
BITCLEAR
پاک کردن بیت شماره صفر:
?BITCLEAR(a,0)
دقت کنید بیتها از صفر تا ۳۱ وجود دارند نه از ۱ تا
۳۲
برای چک کردن اینکه در یک بیت صفر است یا یک از BITTEST استفاده میشود
حال برای اینکه بدانیم عدد مثبت است یا منفی بیت ۳۱ را چک میکنیم
?BITTEST(a,31)
توجه صفر عدد مثبت است.
kia1349
چهارشنبه 26 دی 1386, 11:05 صبح
با تشکر از آقا رضا
یکی از استفاده های زیاد اینگونه توابع علاوه بر کاهش کد نویسی صرفه جوئی در اشغال حافظه توسط متغیرهای گوناگون میباشد
رضا جان ممنون که این بحث رو باز کردی
rahro
چهارشنبه 26 دی 1386, 21:02 عصر
متشکرم
واقعا خیلی برام جالب بود مخصوصا زمانیکه با این تابع نتیجه رو لحظه به لحظه چک میکردم
FUNCTION bintest
PARAMETERS iinteger
LOCAL iint as Character
FOR i=0 TO 31
IF BITTEST(iinteger,i)=.f.
iint=iint+'0'
ELSE
iint=iint+'1'
ENDIF
NEXT
return(iint)
ولی یه نکته:
فکر میکنم نحوه درسترسی به بیتها با آنچه که در زبان اسمبلی گفته دقیقا بر عکس عمل میکنه مثلا در زبان اسمبلی اولین بیت سمت چپ مربوط به اعداد منفی و مثبت است ولی اینجا بیت 31 و در آنجا از راست به چپ است در اینجا از چپ به راست .!!!!
بحرحال منتظریم به ادامه . :بوس:
rezaTavak
پنج شنبه 27 دی 1386, 08:35 صبح
نه دقیقا مانند اسمبلی است چون بیتها از راست به چپ شماره گذاری میشوند:
دلیل چون در اسمبلی بود که یاد گرفتم شیفت بیتها به چپ دو برابر میشوند.
می توانید در debug امتحان کنید.
اما آخرین عملگر یعنی BITNOT
می دانید عدد منفی یعنی بیت ۳۱ یک شده باشد و ابتدا یک واحد از مقدار کم شده و بقیه بیتها هم not شده باشند. یعنی اگر بیتی یک است صفر و اگر صفر است یک شده است پس برای منفی یا مثبت کردن عدد:
?BITNOT(11-1)
?BITNOT(-11-1)
تابع زیر علامت یک عدد را عوض می کند:
FUNCTION NegInt
Lparameter tnInteger
Return BITNOT(tnInteger-1)
تابع قدر مطلق:
FUNCTION ABS1
LPARAMETER tnInteger
RETURN IIF(BITTEST(tnInteger,31),BITNOT(tnInteger-1),tnInteger)
rahro
پنج شنبه 27 دی 1386, 09:25 صبح
نه دقیقا مانند اسمبلی است چون بیتها از راست به چپ شماره گذاری میشوند:
من Calculator ویندوز xp رو انتخاب کردم و به حالت scientific رفتم عدد 2,147,483,000 رو وارد کردم و مقدار Bin اون رو مشاهده کردم مقدار عبارت بود با :
1111111111111111111110101111000
حال با تابعی که ارائه کردم این مقدار رو بدست میآورم حاصل عبارت است از :
00011110101111111111111111111110
یعنی دقیقا" برعکس!! من کجا اشتباه کردم !؟:گیج:
کتابی رو هم که شب گذشته مطالعه کردم نیز به همین منوال بود و همچنین ذکر کرده بود در روش علامت مقدار , اولین بیت سمت چپ مربوط به مقدار منفی و مثبت عدد است؟!
rezaTavak
پنج شنبه 27 دی 1386, 10:36 صبح
این قسمت اشتباه است:
iint=iint+'0'
iint=iint+'1'
به این مثال توجه کن:
فرض کن عدد شما دو باشد که باید باینری ۱۰ باشد خب بیت صفر را اول می خوانید یعنی صفر سپس یک را می خوانید اما عددی که در بیت بالاتر است ارزش بالاتری دارد و باید در سمت چپ عدد قبلی قرار گیرد. یعنی باید دو خط ذکر شده به صورت زیر در آید:
iint='0'+iint
iint='1'+iint
علی اکبر
سه شنبه 21 تیر 1390, 08:07 صبح
سلام
جناب مدیر بخش اقای توکل
یه جایی تو این قسمت فرموده بودید با بیتها می شود اعداد بزرگ با هم جمع کرد وفرموده بودید ارائه خواهم کرد
ممنون می شوم راهنمایی بفرمائید
الان خیلی بهش نیاز دارم
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.