带小数的高精度数的任意进制转换

算法 Dec 28, 2014

大学第一学期期末课程设计的一道题,进制转换。

大概思路就是把整数和小数部分分开为 整型 类型,由一个结构体构成。整数部分进制转换模拟人工除法取余,小数部分进制转换模拟人工乘法取整。

numTrans.h
/* Windows 8.1 VS 2013 Pro 编译通过 */
#include <stdio.h>
#define MAXSIZE 10000

typedef struct n{
	short s_integer[MAXSIZE];
	short s_decimal[MAXSIZE];
}NUMBER;

int inputNum(NUMBER * f_num, int f_n);
short charToNum(char f_c);
void numFlip(short * f_num);
void transNum(NUMBER * f_number, NUMBER * f_resultNumber, int f_n, int f_m);
void printNum(short * f_num);
void printTheWholeNum(NUMBER * f_num, int f_m);
numTrans.c
/* Windows 8.1 VS 2013 Pro 编译通过 */

#include "numTrans.h"

char numBase[36] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int i, j;
int isHightestNum = 1;
int haveDecimalNum = 0;
int haveIntegerNum = 0;

int main(){
	NUMBER number, resultNumber;
	int n, m;
	printf("请输入数字的进制类型:\n");
	scanf("%d", &n);
	fflush(stdin);
	//高精度数总是以位数从低到高排在数组里面,如有计算需要翻转,计算完毕再翻转回来,以免混乱。
	printf("请输入这个整数:\n");
	if (!inputNum(&number, n)){
		printf("输入错误\n");
		return 0;
	}
	printf("请输入需要转换的进制类型:\n");
	scanf("%d", &m);
	transNum(&number, &resultNumber, n, m);
	printTheWholeNum(&resultNumber, m);
	return 0;
}

int inputNum(NUMBER * f_num, int f_n){
	char tempChar;
	short tempNum;
	*(f_num->s_integer) = 0;
	*(f_num->s_decimal) = 0;
	while ((tempChar = getchar()) != '\n'){
		if (isHightestNum){
			if (tempChar == '0'){
				continue;
			}else{
				isHightestNum = 0;
			}
		}
		if (!haveDecimalNum && tempChar == '.'){
			haveDecimalNum = 1;
		}
		if ((tempNum = charToNum(tempChar, f_n)) == -1){
			return 0;
		}
		if (haveDecimalNum){
			++(*(f_num->s_decimal));
			*(f_num->s_decimal + *(f_num->s_decimal)) = tempNum;
		}else{
			++(*(f_num->s_integer));
			*(f_num->s_integer + *(f_num->s_integer)) = tempNum;
		}
	}
	if (haveDecimalNum){
		numFlip(f_num->s_decimal);
	}

	if (*(f_num->s_integer) != 0){
		haveIntegerNum = 1;
		numFlip(f_num->s_integer);
	}
	return 1;
}

short charToNum(char f_c, int f_n){
	short tempNum;
	if (f_c >= 'a' && f_c <= 'z'){
		tempNum = (short)f_c - 'a' + 10;
	}else if (f_c >= 'A' && f_c <= 'Z'){
		tempNum = (short)f_c - 'A' + 10;
	}else if (f_c >= 48 && f_c <= 57){
		tempNum = (short)f_c - '0';
	}
	if (tempNum >= f_n){
		return -1;
	}else{
		return tempNum;
	}
}

void numFlip(short * f_num){
	short temp;
	for (i = 0; i < *f_num / 2; i++){
		temp = *(f_num + 1 + i);
		*(f_num + 1 + i) = *(f_num + *f_num - i);
		*(f_num + *f_num - i) = temp;
	}
}

void transNum(NUMBER * f_number, NUMBER * f_resultNumber, int f_n, int f_m){
	short f_tempNum[MAXSIZE];
	short f_num[MAXSIZE];
	//*f_tempNum = 0;
	*(f_resultNumber->s_decimal) = 0;
	*(f_resultNumber->s_integer) = 0;
	if (haveIntegerNum){
		for (j = 1; j <= *(f_number->s_integer); j++){
				*(f_tempNum - 1 + j) = *(f_number->s_integer + j);
		}
		int len = *(f_number->s_integer);
		while(len) {	//每一轮手动模拟除法
	        for(i = len - 1; i >= 1; --i) {
	        	*(f_tempNum + i - 1) += *(f_tempNum + i) % f_m * f_n;
				*(f_tempNum + i) /= f_m;
	        }
	        *(f_resultNumber->s_integer + ++(*(f_resultNumber->s_integer))) = *f_tempNum % f_m;
	        *f_tempNum /= f_m;
	        while(len > 0 && !*(f_tempNum + len - 1)){
	            len--;
	        }
	    }
	}
	if (haveDecimalNum){
		for (i = 0; i <= *(f_number->s_decimal); i++){
			*(f_num + i) = *(f_number->s_decimal + i);
		}
		*f_tempNum = *(f_number->s_decimal);
		int len = *f_tempNum, k = 0, s = 0, carry, flag = 1;  // k 如果进制转换死循环,用于控制小数点位数
		*(f_tempNum + len + 1) = 0;
		*(f_tempNum + len + 2) = 0;
		while (1){
			++k;
			for (i = 1; i <= len; i++){
				*(f_tempNum + i) = 0;
			}
			for (i = 1; i <= len; i++){
				*(f_tempNum + i) += *(f_num + i) * (f_m % 10);
				*(f_tempNum + i + 1) += *(f_tempNum + i) / 10;
				*(f_tempNum + i) %= 10;
			}
			for (i = 1; i <= len; i++){
				*(f_tempNum + i + 1) += *(f_num + i) * (f_m / 10);
				*(f_tempNum + i + 2) += *(f_tempNum + i + 1) / 10;
				*(f_tempNum + i + 1) %= 10;
			}

			*(f_resultNumber->s_decimal + ++(*(f_resultNumber->s_decimal))) = *(f_tempNum + len + 1) + *(f_tempNum + len + 2) * 10;
			*(f_tempNum + len + 1) = 0;
			*(f_tempNum + len + 2) = 0;
			for (i = 0; i <= len; i++){
				*(f_num + i) = *(f_tempNum + i);
			}
			for (i = 1; i <= len; ++i){
				if (*(f_tempNum + i) != 0){
					flag = 0;
				}
			}
			if (flag){
				break;
			}
			flag = 1;
			if (k == 16){
				break;
			}
		}
		numFlip(f_resultNumber->s_decimal);
	}

}

void printNum(short * f_num){
	for (i = *f_num; i >= 1; i--){
		printf("%c", *(numBase + *(f_num + i)));
	}
}

void printTheWholeNum(NUMBER * f_num, int f_m){
	if (f_m == 16){
		printf("0x");
	}else if (f_m == 8){
		printf("0");
	}
	if (*(f_num->s_integer)){
		printNum(f_num->s_integer);
	}else{
		printf("0");
	}
	if (*(f_num->s_decimal)){
		printf(".");
		printNum(f_num->s_decimal);
	}
	printf("\n");
}

Tags

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.