将一个字节(数字)移动一个除法的小数部分

时间:2014-05-01 11:39:17

标签: javascript algorithm binary

我试图根据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);
}

2 个答案:

答案 0 :(得分:2)

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

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;
}

这将填充您的字节字段,并且还满足您的验证例程。

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

答案 1 :(得分: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);
}