C語言,36進制以內的浮點數任意進制互相轉換

最近在複習考研的c語言編程,對於我這種總是用C++刷題的突然一下不能用C++只能用C了還是有點難受,想要多練練。然後我就遇到了一道浮點數進制轉換的題目,按理說是很簡單的,但是小數部分的進制轉換我卻想了半天,發現必須要用字符串處理,不然會出現很多精度問題。然後我想百度看看別人的解決方法,結果找到的都是在線進制轉換器= =,所以在這裏記錄一下我的方法。

#include<stdio.h>
#include<string.h>
#include<math.h>

char* hexConvert(char* num,int begin,int end)//將浮點數num從begin進制轉化成end進制(36進制以內)
{
	//先轉化成十進制便於計算
	double eps = 1e-8;//精度爲1e-8,如果對精度要求高可以調小
	int int_D = 0;//十進制整數部分
	double dec_D = 0;//十進制小數部分
	double indexf = 1.0 / double(begin);//小數部分相應位的權重
	bool isInt = true;
	for (int i = 0; i < strlen(num); i++)
	{
		if (num[i] == '.')//找到小數點,後面的是小數位
		{
			isInt = false;
			continue;
		}
		if (isInt)//處理整數位
		{
			int_D *= begin;
			if(num[i]>='0'&&num[i]<='9')
				int_D += (num[i] - '0');
			if (num[i] >= 'a' && num[i] <= 'z')
				int_D += (num[i] - 'a' + 10);
		}
		else//處理小數位
		{
			if (num[i] >= '0' && num[i] <= '9')
				dec_D += indexf * (num[i] - '0');
			if (num[i] >= 'a' && num[i] <= 'z')
				dec_D += indexf * (num[i] - 'a' + 10);
			indexf /= double(begin);
		}
	}

	//將轉化好的十進制轉化爲目標進制
	char* ans;//答案字符串
	char int_T[1005], dec_T[1005];//目標進制的整數部分和小數部分
	int int_T_index = 0, dec_T_index = 0;
	int tmp;
	while (int_D)//處理整數位
	{
		tmp = int_D % end;
		if (tmp >= 0 && tmp <= 9)
			int_T[int_T_index++] = '0' + tmp;
		if (tmp >= 10 && tmp <= 35)
			int_T[int_T_index++] = 'a' + tmp - 10;
		int_D /= end;
	}
	int_T[int_T_index] = '\0';
	ans = _strrev(int_T);//整數部分是先獲取的低位後獲取的高位,所以要反轉,strrev函數被_strrev替代了
	indexf = 1.0 / double(end);
	while (fabs(dec_D)>=eps)//處理小數位,dec_D如果小於精度就默認爲0,跳出循環,否則當作不爲0,繼續處理
	{
		tmp = int(dec_D / indexf);
		if (tmp >= 0 && tmp <= 9)
			dec_T[dec_T_index++] = '0' + tmp;
		if (tmp >= 10 && tmp <= 35)
			dec_T[dec_T_index++] = 'a' + tmp - 10;
		dec_D -= tmp * indexf;
		indexf /= end;
	}
	dec_T[dec_T_index] = '\0';
	strcat(ans, ".");
	strcat(ans, dec_T);
	return ans;
}

123.456從7進制轉18進制結果是3c.c7fc7fc

asdf.jklm從32進制轉24進制結果是11j9n.ehf3e

測試了幾條結果,與在線進制轉換器的結果都是一致的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章