你如何在 JavaScript 中的不同基数之间转换数字?

IT技术 javascript
2021-02-08 14:34:27

我想在不同的基数之间转换数字,例如十六进制和十进制。

示例:如何将十六进制转换8F为十进制?

6个回答

应用程序接口

从十六进制字符串转换为数字:

parseInt(string, radix)
  • 字符串:必需。要解析的字符串

  • 基数:可选。代表要使用的数字系统的数字(从 2 到 36)

要将数字转换为十六进制字符串:

NumberObject.toString(radix)
  • 基数:可选。指定您希望数字显示为的基数。

示例基数值:

  • 2 - 数字将显示为二进制值
  • 8 - 数字将显示为八进制值
  • 16 - 数字将显示为十六进制值

示例用法

整数值到十六进制:

var i = 10;
console.log( i.toString(16) );

十六进制字符串到整数值:

var h = "a";
console.log( parseInt(h, 16) );

整数值转十进制:

 var d = 16;
 console.log( d.toString(10) );

我没有看到第一个如何转换为十六进制。你能解释一下吗?此外,第二个将导致十六进制而不是标记的十进制。
2021-03-22 14:34:27
这甚至更好。撤销。
2021-03-25 14:34:27
@Wahnfrieden - 我误解了你的意思。我现在很清楚:)
2021-03-28 14:34:27
@Russ Cam:第一个将基数作为参数 - 十六进制是基数 16 - 并返回该基数中该数字表示的字符串。你对第二个不正确 - 它确实导致一个十进制值。
2021-04-12 14:34:27
这对于大于 36 的基数失败,因为toString抛出RangeError. 大基地显然没有意义表示为字符。
2021-04-13 14:34:27

我来到这篇文章需要将基数从 10 转换为 62,反之亦然。虽然这里的解决方案很棒,parseInt并且toString只支持基数 2 到 36。因此,如果有人发现自己处于与我需要基数 2 到 62 相似的位置,我已在下面粘贴了我的解决方案。

https://gist.github.com/ryansmith94/91d7fd30710264affeb9

function convertBase(value, from_base, to_base) {
  var range = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/'.split('');
  var from_range = range.slice(0, from_base);
  var to_range = range.slice(0, to_base);
  
  var dec_value = value.split('').reverse().reduce(function (carry, digit, index) {
    if (from_range.indexOf(digit) === -1) throw new Error('Invalid digit `'+digit+'` for base '+from_base+'.');
    return carry += from_range.indexOf(digit) * (Math.pow(from_base, index));
  }, 0);
  
  var new_value = '';
  while (dec_value > 0) {
    new_value = to_range[dec_value % to_base] + new_value;
    dec_value = (dec_value - (dec_value % to_base)) / to_base;
  }
  return new_value || '0';
}

看起来某处有错误。将“111222444abcdef”从基数 16 转换为 10 并返回结果为“111222444abcdf0”
2021-03-24 14:34:27
@RyanSmith 你说得对,其他在线转换器也这样做。
2021-04-07 14:34:27
花车有变化吗?例如,我如何转换1.3为 base 64?
2021-04-08 14:34:27
我没有让任何人感到抱歉。
2021-04-10 14:34:27
我有一种感觉,它可能与 JavaScript @expert 中的数字精度有关,因为该错误是由dec_value % to_base大数字引起的,但我似乎无法为较小的数字重现它。
2021-04-10 14:34:27

您可以尝试以下代码,它也支持任意精度数(大于 2^53)。

function convertBase(str, fromBase, toBase) {

    const DIGITS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/";

    const add = (x, y, base) => {
        let z = [];
        const n = Math.max(x.length, y.length);
        let carry = 0;
        let i = 0;
        while (i < n || carry) {
            const xi = i < x.length ? x[i] : 0;
            const yi = i < y.length ? y[i] : 0;
            const zi = carry + xi + yi;
            z.push(zi % base);
            carry = Math.floor(zi / base);
            i++;
        }
        return z;
    }

    const multiplyByNumber = (num, x, base) => {
        if (num < 0) return null;
        if (num == 0) return [];

        let result = [];
        let power = x;
        while (true) {
            num & 1 && (result = add(result, power, base));
            num = num >> 1;
            if (num === 0) break;
            power = add(power, power, base);
        }

        return result;
    }

    const parseToDigitsArray = (str, base) => {
        const digits = str.split('');
        let arr = [];
        for (let i = digits.length - 1; i >= 0; i--) {
            const n = DIGITS.indexOf(digits[i])
            if (n == -1) return null;
            arr.push(n);
        }
        return arr;
    }

    const digits = parseToDigitsArray(str, fromBase);
    if (digits === null) return null;

    let outArray = [];
    let power = [1];
    for (let i = 0; i < digits.length; i++) {
        digits[i] && (outArray = add(outArray, multiplyByNumber(digits[i], power, toBase), toBase));
        power = multiplyByNumber(fromBase, power, toBase);
    }

    let out = '';
    for (let i = outArray.length - 1; i >= 0; i--)
        out += DIGITS[outArray[i]];

    return out;
}

用法:

console.log(convertBase("5a2a9c826c75045be9ba8fbffc80c6f25a2a9c826c75045be9ba8fbffc80c6f2",16,64));
// Returns: 5EGD89ItghrWrGfL/O0NL9qaFO2r7k4m+CWzX/YwcrO

console.log(convertBase("5EGD89ItghrWrGfL/O0NL9qaFO2r7k4m+CWzX/YwcrO",64,16));
// Returns: 5a2a9c826c75045be9ba8fbffc80c6f25a2a9c826c75045be9ba8fbffc80c6f2

基本代码已在此处找到,我对其进行了一些改进以支持高达 base 64。

这是一个非常好的代码!不知道有没有C版的?我好像没找到!
2021-03-15 14:34:27
@Zibri,对不起,IDK。但欢迎您自己转换并在此处与他人分享。
2021-04-02 14:34:27

下图可能会有所帮助。请注意,要从基数 16 转换为基数 2,您需要先转换为基数 10,然后再转换为基数 2。

基础换算

好吧,我制作了一个可以从基数 10 转换为任何基数的函数。(这取决于数组中有多少个字符串A,如果超过 + 10,符号就会用完),当我发现你可以用不到 10 个字符来处理它时,我几乎哭了...... .

添加书签,并作为 URL 插入这个...我已经完成了漫长但个人的方式。至少,我的可以使用高于36的基数。您可以自己添加更多符号,但是如果您愿意,我可以为您制作...

var X = prompt("Choose your number");
var Y = prompt("Choose your base");
var Z = [];
var M = -1;
var A = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];
var B = function() {
    for (i = X; 0 < i; i = Math.floor(i / Y)) { 
        if(i % Y >= 10) { 
            Z.push(A[i % Y - 10]);
        } else { 
            Z.push(i % Y);
        } 
        M = M + 1;
    } 
    for (j = M; j >= 0; j--) {
        document.write(Z[j]);
    } 
};

B(); // Call function

使用“ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/”,你可以使用base64(真正的,不要与btoa/atob混淆)
2021-03-21 14:34:27
我认为您在某处有计数错误。100.toString(26) = "3M" 但你的会输出 "3O"(三个哦,不是三个零)
2021-03-22 14:34:27
这不会弹出负数。尝试转换-1为 base 10
2021-03-26 14:34:27
@oooyaya 实际上,它输出“2S”,即正确答案。顺便说一句,使用 var x=100; x.toString(26);
2021-04-03 14:34:27