حساب القيمة المطلقة لعدد صحيح دون استخدام التفريع

من موسوعة حسوب
< Algorithms
مراجعة 12:47، 2 ديسمبر 2019 بواسطة Mohammed Taher (نقاش | مساهمات)
(فرق) → مراجعة أقدم | المراجعة الحالية (فرق) | مراجعة أحدث ← (فرق)
اذهب إلى التنقل اذهب إلى البحث

القيمة المطلقة لعدد معين هي القيمة غير السالبة لذلك العدد دون النظر إلى إشارته، ويرمز لها بالرمز |x|.

لا حاجة لحساب القيمة المطلقة للعدد الموجب لأنّها تكون مساوية له، وإن كان العدد المعطى سالبًا فسنحتاج فقط إلى قلب إشارته، ولمّا كانت الأعداد السالبة تخزّن بهيئة متمم الاثنين ‎2’s complement، فإن الحصول على القيمة المطلقة للعدد السالب تتطلب تغيير حالة العبتات في العدد ثم إضافة 1 إلى الناتج.

فعلى سبيل المثال يخزّن العدد ‎-2 في النظام ثماني البتات بالصيغة ‎1 1 1 1 1 1 1 0، ويمثّل البت في أقصى يسار العدد بت الإشارة. وللحصول على القيمة المطلقة للعدد السالب، يجب تبديل جميع البتات ثم إضافة 1 إلى العدد الناتج، أي ‎0 0 0 0 0 0 0 1 + 1 سيعطي الناتج ‎1 1 1 1 1 1 1 0.

الطريقة الأولى

تتبع الطريقة الأولى الخطوات التالية:

1- سيحمل المتغير mask ناتج الإزاحة اليمينة للعدد الصحيح بمقدار 31 (على فرض أنّ العدد الصحيح مخزّن باستخدام 32 بت).

mask = n >> 31

2- ينتج عن الخطوة السابقة المقدار 1 1 1 1 1 1 1 1 للأعداد السالبة والمقدار 0 0 0 0 0 0 0 0 للأعداد الموجبة. تُضاف قيمة المتغير إلى العدد المعطى.

 mask + n

3- يؤدي تطبيق العامل XOR على القيمتين السابقتين mask + n و mask إلى الحصول على القيمة المطلقة للعدد المعطى.

تنفيذ الطريقة

تعرض الأمثلة التالية كيفية تنفيذ هذه الطريقة في عدد من لغات البرمجة:

  • C++‎:
#include <bits/stdc++.h> 
using namespace std; 
#define CHARBIT 8 

unsigned int getAbs(int n) 
{ 
	int const mask = n >> (sizeof(int) * CHARBIT - 1); 
	return ((n + mask) ^ mask); 
} 

/* اختبار الدالة السابقة */
int main() 
{ 
	int n = -6; 
	cout << "Absoute value of " << n << " is " << getAbs(n); 
	return 0; 
}
  • بايثون:
CHARBIT = 8
SIZE_INT = 8
 
def getAbs(n): 
	mask = n >> (SIZE_INT * CHARBIT - 1)
	return ((n + mask) ^ mask)

# اختبار الدالة السابقة
n = -6
print("Absolute value of",n,"is",getAbs(n))
  • جافا:
class GFG { 

	static final int CHAR_BIT = 8; 
	static final int SIZE_INT = 8; 

	static int getAbs(int n) 
	{ 
		int mask = n >> (SIZE_INT * CHAR_BIT - 1); 
		return ((n + mask) ^ mask); 
	} 

	/* اختبار الدالة السابقة */
	public static void main(String[] args) 
	{ 
		int n = -6; 
		System.out.print("Absoute value of " + n + " is " + getAbs(n)); 
	} 
}

تعطي الشيفرات السابقة المخرجات التالية:

Absolute value of -6 is 6

الطريقة الثانية

تتبع الطريقة الأولى الخطوات التالية:

1- سيحمل المتغير mask ناتج الإزاحة اليمينة للعدد الصحيح بمقدار 31 (على فرض أنّ العدد الصحيح مخزّن باستخدام 32 بت).

mask = n >> 31

2- تطبيق العامل XOR على العدد الناتج من الخطوة السابقة والعدد المعطى.

 mask ^ n

3- طريقة قيمة المتغير mask من نتيجة الخطوة الثانية وإعادة الناتج.

 (mask^n) - mask

تنفيذ الطريقة

تعرض الأمثلة التالية كيفية تنفيذه هذه الطريقة في عدد من لغات البرمجة:

  • C++‎:
/* This function will return absolute value of n*/
unsigned int getAbs(int n) 
{ 
	int const mask = n >> (sizeof(int) * CHAR_BIT - 1); 
	return ((n ^ mask) - mask); 
} 

/* اختبار الدالة السابقة */
int main() 
{ 
	int n = -6; 
	cout << "Absoute value of " << n << " is " << getAbs(n); 
	return 0; 
}
  • بايثون:
CHARBIT = 8
SIZE_INT = 8
 
def getAbs(n): 
	mask = n >> (SIZE_INT * CHARBIT - 1)
        return ((n ^ mask) - mask)

# اختبار الدالة السابقة
n = -6
print("Absolute value of",n,"is",getAbs(n))
  • جافا:
class GFG { 

	static final int CHAR_BIT = 8; 
	static final int SIZE_INT = 8; 

	static int getAbs(int n) 
	{ 
		int mask = n >> (SIZE_INT * CHAR_BIT - 1); 
		return ((n ^ mask) - mask); 
	} 

	/* اختبار الدالة السابقة */
	public static void main(String[] args) 
	{ 
		int n = -6; 
		System.out.print("Absoute value of " + n + " is " + getAbs(n)); 
	} 
}

مصادر