【问题标题】:Shift a byte (number) by the decimal part of a division按除法的小数部分移动一个字节(数字)
【发布时间】:2014-06-17 21:16:47
【问题描述】:

我正在尝试根据b / n 的小数部分移动字节数组

我使用的(简化的)公式是(给定n = 2):

b = b / 2
if (decimal part of b == 0.5) {
    b = floor(b) + 256 / 2
} 

所以在这种情况下:

b = 0 then 0
b = 1 then 128
b = 2 then 2
b = 3 then 129

在我到达 n = 6 之前它工作正常,但我不确定如何修复它。

这是一个完整的例子:http://jsfiddle.net/cBY2H/4/embedded/result,js/

可以在控制台输出中看到:

Shift by 2-5: fine

Shift by 6: 
Extra 128
Missing 213

Shift by 7:
Extra 110
Missing 219

Shift by 8: fine

我怎样才能使它至少适用于n = 2-9,甚至更好的n = 2+

执行转换的实际代码:

function shiftByte(byte, shiftAmount) {
    var shiftSize = 256 / shiftAmount,
        decimal = 1 / shiftAmount,
        currentDecimal = decimal,
        shiftCount = 1;
    byte = byte / shiftAmount;
    while (numberLessThan(currentDecimal, 1)) {
        if (numberEquals(byte - Math.floor(byte), currentDecimal)) {
            return Math.ceil(shiftSize * shiftCount) + Math.floor(byte);
        }
        currentDecimal += decimal;
        shiftCount++;
    }
    return Math.floor(byte);
}

【问题讨论】:

  • 可能由于十进制分辨率,您的 numberEquals() 函数有时会返回 false。
  • @AbhishekBansal numberEquals== 差不多,但有一个 0.000001 容差来满足浮点精度。该函数的来源在 JS Fiddle:(a + tolerance) >= b && (a - tolerance) <= b
  • 这是错字吗:b = 2 then 2?我希望是 1,否则我不理解这个例子。

标签: javascript algorithm binary


【解决方案1】:

如果您只想用唯一索引填充数组,您可以使用简单的方法,无需所有这些繁琐的浮点除法和比较:

function shiftData(data, n) {
    var result = [];
    var k = 0;
    var next = 0;

    for (var i = 0; i < data.length; i++) {
        result[k] = i;
        k += n;
        if (k > 256) {
            k = ++next;
        }
    }
    return result;
}

这会填充您的字节字段并满足您的验证程序。

如果您需要在shiftData 之外调用shiftByte,您可以使用相同的方法并即时创建移位表。当然,您不必每次都这样做:保留一个全局字典,其中您的移位量(或者可能是移位量和表大小)作为键,字节表作为值。如果表不存在,则创建一个表,然后查找之后的字节。

【讨论】:

    【解决方案2】:

    在我看来,您可以从一个更简单直接的公式中受益,它既更快又可以防止讨厌的浮点运算。

    如果我理解正确,您可以按模块化索引对字节进行分类。那就是:

    var group = b % n;
    

    现在您需要找到该组的起始索引。如果n 除以 256,这很容易,但否则会更麻烦一些。有256 % n 组包含比其他元素多1 个元素。 (看看256 | n 是如何退化的。)组的起始索引因此变为:

    var groupSize = Math.floor(256 / n);
    var numberOfBiggerGroups = 256 % n;
    var groupIndex = group * groupSize + max(group, numberOfBiggerGroups);
    

    如果我正确理解你的算法,组中的索引由Math.floor(b / n)确定。

    这导致以下完整方法:

    function shiftByte(b, n) {
        var group = b % n;
        var groupSize = Math.floor(256 / n);
        var groupIndex = group * groupSize  + Math.max(group, 256 % n);
        return groupIndex + Math.floor(b / n);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-23
      相关资源
      最近更新 更多