الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

تفسير نتائج برنامج بسيط

بدأه amin_mu123 في 27 أغسطس 2008 · 10 رد · 1,057 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم ورحمة الله وبركاته

برنامج بسيط جدا

ولكن المطلوب هو تفسير نتائجه


using namespace std;
int main()
{
int a,b;
cin>>a;
b=~a;
cout<<b<<endl;

return 0;
}
#include <iostream>

وشكرا لكم

تم تعديل هذه المشاركة بواسطة amin_mu123 في 27 أغسطس 2008 في 20:17

اللهم صل على سيدنا محمد وعلى آله وصحبه وسلم

#2

وعليكم السلام ورحمة الله وبركاته ،

فعلاً بسيط ، وانا مثلك اريد الجواب ، لاني لا افقه في هذا الرمز ~ ...

لكن الناتج يكون عكس الرقم المدخل بزيادة رقم ... لماذا ^^

لا إله إلا الله محمد رسول الله عليه الصلاة والسلام

سبحانك اللهم وبحمدك اشهد ان لا إله إلا انت استغفرك واتوب اليك

سأتقن الـ ++C و
PHP إن شاء الله تعالى ...

جاري العمل على
Microsoft Sql Server و MySQL ...

 

#3

اعتقد ان معامل ~ من معاملات bitwise اعتقد انه معامل Bitwise NOT

NOT 0111
  = 1000

هذا مثال wiki لهذه العملية

#4

ما فهمت ممكن تشرح اكثر ....؟

لا إله إلا الله محمد رسول الله عليه الصلاة والسلام

سبحانك اللهم وبحمدك اشهد ان لا إله إلا انت استغفرك واتوب اليك

سأتقن الـ ++C و
PHP إن شاء الله تعالى ...

جاري العمل على
Microsoft Sql Server و MySQL ...

 

#5

كلامك سليم أخى عمر

ولكن اريد تطبيق هذا الكلام على البرنامج أى عندما يكون لدينا عدد صحيح وأثرنا عليه بالمعامل ~ ينتج المعكوس الجمعى للعدد مضافا اليه واحد

بارك الله فيك

اللهم صل على سيدنا محمد وعلى آله وصحبه وسلم

#6

اخى عبد الله

عملية Bitwise NOT هى شبيهة بعملية Logical NOT

انها عملية على مستوى binary digits اى 0 & 1

و هى تعمل بعد تحويل الرقم الى binary ثم تعكس كل رقم بما يقابله

مثال :

1011001

NOT 1 0 1 1 0 0 1

---------------------------

0 1 0 0 1 1 0

فهمت ما اقصد

راجع هذا الرابطBitwise Operations

#7

تستخدم ~ للحصول على المتمم الأحادي one's complement باستخدام عملية bitwise NOT داخلياً (لست أنت من يقوم بهذا) وإضافة 1 إلى الناتج للحصول على two's complement (المتمم الثنائي).

هذه العملية تستخدم عادة في جمع الأعداد السالبة في لغة الأسمبلي حيث لا يمكن تمثيل الأعداد السالبة مباشرة.

في لغة C++ هذا ممكن، لذلك يعود الأمر على نوع البيانات التي يتم حجزها، في المثال السابق المتغير a مصرح على أنه من نوع integer بالتالي هو عدد صحيح موجب تماماً. فتكون القيمة بالقيمة المطلقة ومجال البايت الواحد من 0 حتى 255.

هناك متغيرات يمكن التصريح عنها بحيث تحمل إحدى إمكانيتين, موجبة أو سالبة بالنتيجة, فيكون المجال [-127،+127]

بمعنى آخر، هل المتغير Signed أو Unsigned؟

void convert(short bin, char *str)
{
	unsigned short mask;	  // used to check each individual bit, unsigned
							//	to alleviate sign extension problems

	mask = 0x8000;	  // Set only the high-end bit
	while (mask)			// Loop until MASK is empty
	{
		if (bin & mask)	 // test the masked bit
			  *str = '1';   // if true, value is 1
		  else
			  *str = '0';   // if false, value is 0
		str++;			  // next character
		mask >>= 1;		 // shift the mask 1 bit
	}
	*str = 0;			   // add the trailing null
}


int main()
{
	short		number;
	short		two;
	char		binary[20];

	number = 336;
	two = ~number;		//One's complement
	two = two + 1;		//Two's complement

	printf("Original number is: %hd(%hx)\n",number,number);
	printf("Two's complement is: %hd(%hx)\n",two,two);
	printf("Unsiged is: %hu\n",two);
	printf("Negative number is: %hd(%hx)\n",-number,-number);

	convert(number,binary);
	printf("Number in binary is: %s\n",binary);

	convert(two,binary);
	printf("Number in binary is: %s\n",binary);

	return 0;

}

----

سبب التعديل: إضافة الشفرة.

تم تعديل هذه المشاركة بواسطة Xacker في 27 أغسطس 2008 في 22:46

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

#8

بكل بساطة , المتمم يقوم على تحويل كافة الخانات 0 إلى القيمة 1 وكافة الخانات 1 إلى القيمة 0 .

على فرض اننا ادخلنا 5 وقمنا بايجاد المتمم لها

00000101	 5
11111010	 ?

سيكون الناتج -6

ولنتأكد من انه -6

نوجد العدد 6 بالتحويل الثنائي ومن ثم نوجد المتمم إلى 1 ومن ثم نوجد المتمم إلى 2 لنوجد -6

00000110	 6
11111001	 ~1
11111010	 ~2 ===>-6

ولنثبت بان الناتج هو -6 , نقوم بجمعه مع 6

00000110	 6
11111010	-6   +
-----------------
00000000	 0

هذا والله اعلم .

llback.jpg

اشهد ان لا إله إلا الله وان محمدا ً رسول الله

#9

بارك الله فيكم جميعا

أحسنتم.....

:clapping:

اللهم صل على سيدنا محمد وعلى آله وصحبه وسلم

#10

فعلاً بارك الله فيكم ، وضحت الفكرة ^^ ،

جزاكم الله خير اخواني على التوضيح ...

لا إله إلا الله محمد رسول الله عليه الصلاة والسلام

سبحانك اللهم وبحمدك اشهد ان لا إله إلا انت استغفرك واتوب اليك

سأتقن الـ ++C و
PHP إن شاء الله تعالى ...

جاري العمل على
Microsoft Sql Server و MySQL ...

 

#11

تستخدم ~ مثل NOT فى الاسمبلى، وهى عكس قيمة كل بت، فإذا كان 1 يصبح 0، والعكس صحيح

وانت استخدمت int لتعريف المتغيرات، وبالتالى سيكون طول المتغير لديك 32 بت

لنفرض انك ادخلت رقم 25 قيمة المتغير a فسيكون تمثيله كالتالى

00000000 00000000 00000000 00011001

وستصبح قيمة b بعد العملية b=~a كالتالى

11111111 11111111 11111111 11100110

بمعنى أن المدخل هو (25 = 19h) والمخرج هو (FFFFFFE6h = -26)

ويمكن التأكد من ذلك بتعديل بسيط على المثال الأصلى

int main(int argc, char* argv[])
{
	int a,b;

	cin >> a;
	b=~a;

	cout << "Dec: " << b << endl;
	cout << "Hex: " << hex << b << endl;

	system("PAUSE");

	return 0;
}

او تتبع ذلك بمثال اسمبلى بسيط

MOV   EAX, 19h
MOV   EBX, EAX
NOT   EBX

وفحص قيمة EBX بعد التنفيذ

ولكن لماذا رقم سالب؟

لأن أخر بت من ناحية اليسار هو ما يحدد قيمة الرقم ما اذا كان سالب ام موجب، فإذا كان اخر رقم من ناحية اليسار = 1 ، كان الرقم سالب، وإذا كان اخر رقم من ناحية اليسار = 0 كان الرقم موجب.

للتأكد أعد تنفيذ مثال السى السابق ولنفرض انك ادخلت رقم 26- قيمة المتغير a فسيكون تمثيله كالتالى

11111111 11111111 11111111 11100110

وستصبح قيمة b بعد العملية b=~a كالتالى

00000000 00000000 00000000 00011001

بمعنى أن المدخل هو (FFFFFFE6h = -26) والمخرج هو (25 = 19h)

أما إذا لم تستخدم الأرقام التى تحتوى اشارة (unsigned) فستجد نتائج مختلفة

لنفرض انك ادخلت رقم 25 قيمة المتغير a فسيكون تمثيله كالتالى

00000000 00000000 00000000 00011001

وستصبح قيمة b بعد العملية b=~a كالتالى

11111111 11111111 11111111 11100110

بمعنى أن المدخل هو (25 = 19h) والمخرج هو (FFFFFFE6h = 4294967270) دون النظر للبت الاخير على انه علامة السالب ولكن على انه بت يتم حسابه بالطرق العادية مثل اخواته

ويمكن التأكد من ذلك بتعديل بسيط على المثال الأصلى

int main(int argc, char* argv[])
{
	unsigned int a,b;

	cin >> a;
	b=~a;

	cout << "Dec: " << b << endl;
	cout << "Hex: " << hex << b << endl;

	system("PAUSE");

	return 0;
}

تم تعديل هذه المشاركة بواسطة سمسوما في 29 أغسطس 2008 في 12:53

مواضيع مشابهة