【十进制->其他进制】
十进制数N和其他D进制数转换原理:
N = (N / D) * D + N % D (/为整除运算,%为求余运算)
1. 整数部分:除D取余,倒着读。每次将整数部分除以D,余数为该位权上的数,商继续除以D。。。直到商为0,读数时从最后一个余数读起,直到第一个余数。
举例:1348转换成8进制为2504。
N N / 8 N % 8
1348 168 4
168 21 0
21 2 5
2 0 2
倒着读:2504
2. 小数部分:乘2取整,正着读。将小数部分乘以D,取整数部分,剩下的部分继续乘以D。。。直到小数部分为0。如果永远不为0,按照精度要求取舍。
举例:0.125 换算成二进制为0.001
N N * 2 整数部分 小数部分
0.125 0.25 0 0.25
0.25 0.5 0 0.5
0.5 1 1 0
正着读:0.001
十进制->八进制,间接法:十进制 -> 二进制 -> 八进制
十进制->十六进制,间接法:十进制 -> 二进制 -> 十六进制
以下实现从十进制到二、八、十六进制的转换。
-小数部分可能会有点问题,因为浮点数不能直接和0比较大小,但是在VS2010里面运行起来好像是正确的,暂时这样吧。
-小数部分默认取5位精度,因为可能出现总也乘不完的情况。
#include <iostream> #include <cmath> #include <stack> #include <queue> #include <string> using namespace std; #define PRECISION 5 #define HEX 16 #define DEC 10 #define OCT 8 #define BIN 2 char ToHexChar(int num) { if (num <=9) return num + '0'; if (num > 9 && num < 16) { switch (num) { case 10: return 'A'; case 11: return 'B'; case 12: return 'C'; case 13: return 'D'; case 14: return 'E'; case 15: return 'F'; } } } char ToProperChar(int num, int base) { switch(base) { case BIN: case OCT: return num + '0'; case HEX: return ToHexChar(num); } } string DecimalToOtherBase(float num, int base) { int integer = (int)num; float decimal = num - integer; stack<char> newInt; queue<char> newDec; string result; //Process the integer part while (integer !=0) { char ch = ToProperChar(integer % base, base); newInt.push(ch); integer = integer / base; } while(!newInt.empty()) { char ch = newInt.top(); newInt.pop(); result += ch; } int i = 0; //Process the decimal part while (decimal != 0 && i <s PRECISION) { float a = decimal * base; int aInt = (int)a; decimal = a - aInt; char ch = ToProperChar(aInt, base); newDec.push(ch); i++; } if (!newDec.empty()) result += '.'; while (!newDec.empty()) { char ch = newDec.front(); newDec.pop(); result += ch; } return result; }
【其他进制->十进制】
按权相加。即将D进制每位上的数乘以权(乘以1,乘以D, 乘以D的平方,乘以D的四次方。。。。),然后相加得到十进制数。
【二进制与八进制】
1. 二进制->八进制
取三合一。从二进制的小数点为分界点,向左(右)每三位取成一位,变成相应的八进制数,合在一起。
举例:101110.101 -> 56.5
2. 八进制->二进制
取一分三。将八进制数的每一位分解成三位二进制数,再合起来,小数点位置不变。
举例:67.54 -> 110111.101100 ->110111.1011
【二进制与十六进制】
和二进制与八进制类似,不过是取四合一或者取一分四。
【八进制与十六进制】
不能直接互相转换,通过二进制做中间人,比如八进制 -> 二进制 -> 十六进制,小数点位置不变。