簡體   English   中英

有效地在JavaScript中添加十六進制字符串

[英]Adding hexadecimal strings in JavaScript efficiently

在JavaScript中,我有兩個變量,每個變量都包含一個十六進制數作為字符串。 例如:

var a = 'a3bc',
    b = '1d0f';

現在,我要添加它們(因此,結果應為'c0cb' )。 為了使事情變得容易一些,讓我們對此施加一些約束:

  • 數字始終由相同數量的數字組成(即,字符串長度相同)。
  • 如有必要,數字以0 s為前綴,因此將是'001a' ,而不僅僅是'1a'

另一方面,有些約束使事情變得有些困難:

  • 數字不像上面的示例那樣由四位數字組成,而是由20位數字組成。 因此,您不能簡單地將它們轉換為十進制,添加它們,然后再轉換回它們。 換句話說:數字對於JavaScript的number類型而言太大(這就是為什么此答案不起作用的原因)。
  • 不允許溢出。 如果添加'ffff''0001' ,則結果應為'0000'而不是'10000' 換句話說:所有計算都必須使用模除法進行。

我目前有一種算法可以解決所有這些問題,但是它很長,效率不高,而且很優雅。 它的想法是逐個字符地處理字符串,將它們轉換為十進制,將它們相加,將它們轉換回,記住潛在的溢出等等。 如前所述,它可以完美運行,但我認為這不是最佳解決方案。

我怎樣才能更好地解決這個問題?

PS:我需要在Node.js中執行此操作,因此,如果有可用的現成模塊可以執行此操作,那么我對此非常滿意:-)

在最簡單的情況下,您可以一次加一位,並記錄進位:

var ndigits = 4, i, carry = 0, d, result = "";
for (i = ndigits - 1; i >= 0; i--) {
  d = parseInt(a[i], 16) + parseInt(b[i], 16) + carry;
  carry = d >> 4;
  result = (d & 15).toString(16) + result;
}

如果性能是一個問題,則您可能希望一次處理多個位數,但是事情變得很困難,或者您必須對位數進行硬編碼。 即使這樣,零填充的東西仍然需要一些工作。 這是一個分三步執行20個十六進制數字的解決方案,因此數字的長度不能超過32位:

function pad(s, n) { while (s.length < n) s = "0" + s; return s; }
d = parseInt(a.substr(13), 16) + parseInt(b.substr(13), 16);
result = pad((d & 0xfffffff).toString(16), 7);
d = parseInt(a.substr(6, 7), 16) + parseInt(b.substr(6, 7), 16) + (d >> 28);
result = pad((d & 0xfffffff).toString(16), 7) + result;
d = parseInt(a.substr(0, 6), 16) + parseInt(b.substr(0, 6), 16) + (d >> 28);
result = pad((d & 0xffffff).toString(16), 6) + result;

根據jsPerf的說法 ,至少在某些瀏覽器中,此代碼似乎比上述代碼快三倍。

很高興看到您已經擁有的東西,但是可以使用像BigNumber這樣的任意算術庫。

使用Javascript

require.config({
    paths: {
        bignumber: 'https://raw.githubusercontent.com/MikeMcl/bignumber.js/master/bignumber.min'
    }
});

require(['bignumber'], function (BigNumber) {
    function sumHex() {
        var args = [].slice.call(arguments),
            length = args.length,
            sum = new BigNumber(0, 16),
            index;

        for (index = 0; index < length; index += 1) {
            sum = sum.plus(args[index], 16).mod('100000000000000000000', 16);
        }

        sum = sum.toString(16);
        while (sum.length < 20) {
            sum = '0' + sum;
        }

        return sum;
    }

    var a = '0000000000000000a3bc',
        b = '00000000000000001d0f';

    console.log(sumHex(a, b));

    a = 'ffffffffffffffffffff';
    b = '00000000000000000001';
    console.log(sumHex(a, b));
});

產量

0000000000000000c0cb
00000000000000000000

jsFiddle上

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM