摘要:导言进制转换是一道经典的题,基本概念不多说,像下面这样进制进制进制进制注意进制不同时,数值还是一样大的。当然,这并不是我们想要的,我们希望自己实现一个进制转换的函数。
导言
进制转换是一道经典的题,基本概念不多说,像下面这样
12(10进制) <=> C(16进制) <=> 1100(2进制) <=> 14(8进制)
注意进制不同时,数值还是一样大的。因此C(16进制)只是12(10进制)的另一种表示,而不是另一个数值。其实我的意思是,表示10进制外的其他进制时都应该用字符串。
因此一般有两种情况
1. 10进制整数转换为其他进制字符串
2. 其他进制字符串转换为10进制整数
对于10进制整数转换为8进制或16进制字符串时,C和Java里都有偷懒的办法
/* C */ int num = 12; char oct_str[100]; char hex_str[100]; sprintf(oct_str, "%o", num); /* oct_str == "14" */ sprintf(hex_str, "%x", num); /* hex_str == "C" */ /* or printf */
// Java int num = 12; String octStr = Integer.toOctalString(num); // octStr == "14" String hexStr = Integer.toHexString(num); // hexStr == "C"
对于其他进制字符串转换为10进制整数,Java已经提供了完美的方法。
// Java int num = Integer.parseInt("C", 16); // num == 12
当然,这并不是我们想要的,我们希望自己实现一个进制转换的函数。
10进制整数转换为其他进制字符串先举个栗子——我们是怎么把111(10进制)转换为157(8进制)的呢,其实就是一般的除法。
1. 比111小的最大的8的幂次是64
2. 111 / 64 = 1 ... 47
3. 47 / 8 = 5 ... 7
4. 7 / 1 = 7 ... 0
把3次除法的商连起来就是157(8进制)
算法上的思路跟这个完全一样(如果下面这段看着难受请直接看代码)
1. 假设要被转换的10进制数是num,进制是base,转换结果是result
2. 找到比num小的最大的base^n
3. result的第i位为num / base^(n-i)的商
4. num = num % base^(n-i),即余数作为下一轮的被除数
5. i++并回到第3部除非除数等于0
/* C */ char *itos(int num, int base, char *dest) { int i, divisor = 1; char *table = "0123456789ABCDEF"; while (divisor * base <= num) { divisor *= base; } for (i = 0; divisor >= 1; i++, divisor /= base) { dest[i] = table[num/divisor]; num %= divisor; } dest[i] = 0; return dest; }
等等你说C语言的这个版本有个问题,为什么要传个char *dest进去呢?我该怎么调用呢?
正确的调用姿势是下面这样的,至于为什么,请看我将来要写的一篇文章——C语言中的字符串与指针。
char str[100]; itos(255, 16, str); printf("%s", str); /* prints "FF" */
Java版本的代码
// Java public static String itos(int num, int base) { int divisor = 1; byte[] table = "0123456789ABCDEF".getBytes(); String result = ""; while (divisor * base <= num) { divisor *= base; } for (; divisor >= 1; divisor /= base) { result += (char) table[num/divisor]; num %= divisor; } return result; }其他进制字符串转换为10进制整数
这个就比较简单了,用一个表达式就是(假设字符串是a,有n位)
T[n] = a[0]*base^(n-1) + a[1]*base^(n-2) + ... + a[n-2]*base + a[n-1]
转化成迭代的式子就是
T[0] = 0 T[i+1] = base*T[i] + a[i]
转化成程序就是
/* C */ int stoi(const char *src, int base) { int i, digit, result = 0; for (i = 0; i < strlen(src); i++) { if (src[i] >= "a") { digit = src[i] - "a" + 10; } else if (src[i] >= "A") { digit = src[i] - "A" + 10; } else { digit = src[i] - "0"; } result = base*result + digit; } return result; }
// Java public static int stoi(String src, int base) { int digit, result = 0; for (int i = 0; i < src.length(); i++) { char c = src.charAt(i); if (c >= "a") { digit = c - "a" + 10; } else if (c >= "A") { digit = c - "A" + 10; } else { digit = c - "0"; } result = base*result + digit; } return result; }
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/64196.html
摘要:进制转换本身自带进制转换功能,支持进制的转换注意,不能直接使用因为数字后面小数点后面会被识别成小数点的点将十进制的转换成进制,结果是将进制的转换成进制,结果是将十进制的转换成进制,结果是将进制的转换成进制,结果是将十进制的转换成进制,结果 JavaScript进制转换 JavaScript本身自带进制转换功能,支持2-36进制的转换 // 注意,不能直接使用 11.toString(1...
摘要:有符号的右移操作符由两个大于符号表示这个操作符的含义就是将数值的位向右移指定的位数同时保留符号位的值正负号标记有符号的右移操作符与左移操作符刚好相反比如向右移动位就是同样的在移位的过程中也会出 位操作符的基本概念 因为ECMAscript中所有数值都是以IEEE-75464格式存储,所以才会诞生了位操作符的概念. 位操作符作用于最基本的层次上,因为数值按位存储,所以位操作符的作用也就是...
摘要:总结通过使用和,我们能够在数据和二进制数据中进行互相转换。下一篇系列相关的博客,将会介绍如何通过来向后端传递二进制数据,以及如何处理通过收到的二进制数据。 概述 上一篇博客我们说到了如何进行数字类型(如Short、Int、Long类型)如何在JavaScript中进行二进制转换,如果感兴趣的可以可以阅读本系列第二篇博客——WebSocket系列之JavaScript中数字数据如何转换为...
摘要:数值转换对个人而言是非常重要的,这也是本人单独拉出来总结的一个原因。在此也仅针对显示转换做点文章,隐式转换同样会单独拉出来总结有个函数可以把非数值转换为数值和。如果是值,和将分别被转换为和。如果是数字值,只是简单的传入和返回。 数值转换对个人而言是非常重要的,这也是本人单独拉出来总结的一个原因。在此也仅针对显示转换做点文章,隐式转换同样会单独拉出来总结 有 3 个函数可以把非数值转换为...
摘要:可以将其他类型转成字符串函数可以将任意类型的值转为布尔值。提示空数组空对象转换为布尔型也是。 在JS中数据类型转换有两种 相关资料参阅 官方ecma-5规范阮一峰老师类型转换规范对相等==定义 强制类型转换Number() Number函数将字符串转为数值,要比parseInt函数严格很多,只要有一个字符是非数字(空格、+、-除外),那么就会被转为NaN。 showImg(http...
阅读 1738·2021-11-25 09:43
阅读 1783·2021-11-24 10:41
阅读 3103·2021-09-27 13:36
阅读 810·2019-08-30 15:53
阅读 3565·2019-08-30 15:44
阅读 865·2019-08-30 14:03
阅读 2570·2019-08-29 16:38
阅读 994·2019-08-29 13:23