تحويل الأعداد من النظام الثنائي إلى النظام الثماني

من موسوعة حسوب

تحوّل هذه الخوارزمية الأعداد من النظام الثنائي (الأساس 2) إلى النظام الثماني (الأساس 8).

مثال:

Input : 110001110
Output : 616

Input  : 1111001010010100001.010110110011011
Output : 1712241.26633

خطوات الخوارزمية

تتبع هذه خوارزمية تحويل الأعداد من النظام الثنائي إلى النظام الثماني الخطوات التالية:

  1. الحصول على طول السلسلة النصية الفرعية إلى يسار وإلى يمين النقطة الفاصلة.
  2. إن كان طول السلسلة النصية الفرعية اليسرى ليس من مضاعفات العدد 3 يُضاف أقل عدد ممكن من الأصفار إلى بداية تلك السلسلة لجعل طولها من مضاعفات العدد 3.
  3. إن كان طول السلسلة النصية الفرعية اليمنى ليس من مضاعفات العدد 3 يُضاف أقل عدد ممكن من الأصفار إلى نهاية تلك السلسلة لجعل طولها من مضاعفات العدد 3.
  4. استخراج سلاسل فرعية من جهة اليسار تضمّ كل واحدة منها ثلاثة حروف وإضافة القيمة الثمانية المقابلة لها إلى النتيجة.
  5. إن كان هناك نقطة فاصلة في العدد المعطى تضاف في مكانها ضمن النتيجة.

تنفيذ الخوارزمية

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

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

// تنشئ الدالة رابطًا بين الأعداد الثنائية ومكافئتها في النظام الثماني
void createMap(unordered_map<string, char> *um) 
{ 
	(*um)["000"] = '0'; 
	(*um)["001"] = '1'; 
	(*um)["010"] = '2'; 
	(*um)["011"] = '3'; 
	(*um)["100"] = '4'; 
	(*um)["101"] = '5'; 
	(*um)["110"] = '6'; 
	(*um)["111"] = '7';	 
} 

// تحسب الدالة العدد الثماني المكافئ للعدد الثنائي المعطى
string convertBinToOct(string bin) 
{ 
	int l = bin.size(); 
	int t = bin.find_first_of('.'); 
	
	// طول السلسلة النصية قبل النقطة الفاصلة
	int len_left = t != -1 ? t : l; 
	
	// إضافة الأصفار إلى بداية السلسلة النصية 
	// لجعل طول السلسلة الفرعية اليسرى من مضاعفات العدد 3
	for (int i = 1; i <= (3 - len_left % 3) % 3; i++) 
		bin = '0' + bin; 
	
	// إن كانت هناك نقطة فاصلة
	if (t != -1)	 
	{ 
		// طول السلسلة النصية بعد النقطة الفاصلة
		int len_right = l - len_left - 1; 
		
		// إضافة الأصفار في نهاية السلسلة النصية الفرعية اليمنى
		// لجعل طولها قابلًا للقسمة على 3
		for (int i = 1; i <= (3 - len_right % 3) % 3; i++) 
			bin = bin + '0'; 
	} 
	
	// إنشاء رابط بين العدد الثنائي وما يقابله في النظام الثماني
	unordered_map<string, char> bin_oct_map; 
	createMap(&bin_oct_map); 
	
	int i = 0; 
	string octal = ""; 
	
	while (1) 
	{ 
		// استخراج سلاسل نصية واحدة تلو الأخرى من جهة اليسار
		// تحتوي كل واحدة منها على 3 أرقام وإضافة مقابلها الثماني إلى النتيجة
		octal += bin_oct_map[bin.substr(i, 3)]; 
		i += 3; 
		if (i == bin.size()) 
			break; 
			
		// تضاف النقطة الفاصلة إلى النتيجة إن وجدت
		if (bin.at(i) == '.')	 
		{ 
			octal += '.'; 
			i++; 
		} 
	} 
	
	// العدد الثماني المطلوب
	return octal;	 
} 

// اختبار الدالتين السابقتين
int main() 
{ 
	string bin = "1111001010010100001.010110110011011"; 
	cout << "Octal number = "
		<< convertBinToOct(bin); 
	return 0;	 
}
  • بايثون:
# تنشئ الدالة رابطًا بين الأعداد الثنائية
# ومكافئتها في النظام الثماني 
def createMap(bin_oct_map): 
	bin_oct_map["000"] = '0'
	bin_oct_map["001"] = '1'
	bin_oct_map["010"] = '2'
	bin_oct_map["011"] = '3'
	bin_oct_map["100"] = '4'
	bin_oct_map["101"] = '5'
	bin_oct_map["110"] = '6'
	bin_oct_map["111"] = '7'

# تحسب الدالة العدد الثماني المكافئ للعدد الثنائي المعطى 
def convertBinToOct(bin): 
	l = len(bin) 
	
	# طول السلسلة النصية قبل النقطة الفاصلة 
	t = -1
	if '.' in bin: 
		t = bin.index('.') 
		len_left = t 
	else: 
		len_left = l 
	
	# إضافة الأصفار إلى بداية السلسلة النصية  
	# لجعل طول السلسلة الفرعية اليسرى من مضاعفات العدد 3 
	for i in range(1, (3 - len_left % 3) % 3 + 1): 
		bin = '0' + bin
	
	# إن كانت هناك نقطة فاصلة 
	if (t != -1): 
		
		# طول السلسلة النصية بعد النقطة الفاصلة 
		len_right = l - len_left - 1
		
		# إضافة الأصفار في نهاية السلسلة النصية الفرعية اليمنى 
		# لجعل طولها قابلًا للقسمة على 3 
		for i in range(1, (3 - len_right % 3) % 3 + 1): 
			bin = bin + '0'
	
	# إنشاء رابط بين العدد الثنائي وما يقابله في النظام الثماني 
	bin_oct_map = {} 
	createMap(bin_oct_map) 
	i = 0
	octal = "" 
	
	while (True) : 
		
		# استخراج سلاسل نصية واحدة تلو الأخرى من جهة اليسار
		# تحتوي كل واحدة منها على 3 أرقام وإضافة مقابلها الثماني إلى النتيجة 
		octal += bin_oct_map[bin[i:i + 3]] 
		i += 3
		if (i == len(bin)): 
			break
			
		# تضاف النقطة الفاصلة إلى النتيجة إن وجدت 
		if (bin[i] == '.'): 
			octal += '.'
			i += 1
			
	# العدد الثماني المطلوب 
	return octal 

# اختبار الدالتين السابقتين
bin = "1111001010010100001.010110110011011"
print("Octal number = ", 
	convertBinToOct(bin))

مصادر