代表C shift在Java

时间:2016-04-25 22:47:08

标签: java c bit-shift unsigned signed

我正在尝试将一些C代码移植到Java中,并且一直在努力解释转换的顺序,运算符优先级,并确保结果符合我的预期。我已经阅读了很多帖子,并认为我已经弄清楚了但是我想确定我已经正确地表示了它。

我想要移植的original C code是:

UInt32 _strtoul(char *str, int size, int base)
{
    UInt32 total = 0;
    int i;

    for (i = 0; i < size; i++)
    {
        if (base == 16)
            total += str[i] << (size - 1 - i) * 8;
        else
           total += ((unsigned char) (str[i]) << (size - 1 - i) * 8);
    }
    return total;
}

在代码中,4字节值(字节数组或字符串)转换为32位整数。我试图理解条件中两个条款的区别;具体来说,(unsigned char)演员的实际效果是什么。

根据我的理解,在C中,一个字节在左移之前被提升为一个int。但是,我不理解它是如何转换为C中的按位表示。在顶部分支(base == 16,signed)中,0xff(-1)的字节值将从0xff升级是否正确?到0xffffffff到底部分支(无符号)时,值0xff(255)会从0xff提升到0x000000ff吗?

鉴于这种解释,下面的Java代码是忠实的表示(除了Uint与int返回类型之外)吗?

public static int strtoul(byte[] bytes, int size, int base) {
    int total = 0;
    for (int i = 0; i < size; i++) {
        if (base == 16) {
            // signed bytes, shifted
            total += bytes[i] << (size - 1 - i) * 8;
        } else {
            // unsigned bytes, shifted
            total += bytes[i] & 0xff << (size - 1 - i) * 8;
        }
    }
    return total;
}

2 个答案:

答案 0 :(得分:1)

我没有使用sscanf,因为你正在寻找一个uint32解决方案。如果你真的不在乎,那就像

一样简单
#include <stdio.h>

unsigned int _strtoui(char *s)
{
    unsigned int ret;
    sscanf(str, "%u", &ret); /* use "%x" for hexadecimal */
    return ret;
}

我猜Java中有类似sscanf的东西。无论如何,这是我uint32_t / UInt32的解决方案。注意输入数据中的溢出。此外,如果字符不是(十六进制)数字,则函数将给出无意义。改善这是另一项工作。

#include <stdint.h>

uint32_t _strtoui32(char *str)
{
    int i;
    uint32_t total = 0;

    for(i=0; str[i] != '\0'; i++)
        total = total*10 + str[i] - '0';

    return total;
}

uint32_t _hextoui32(char *str)
{
    int i;
    uint32_t total = 0;

    for(i=0; str[i] != '\0'; i++) {
        total *= 16;
        if(str[i] > 47 && str[i] < 58) /* base 10 number */
            total += str[i] - '0';
        else if(str[i] > 64 && str[i] < 71) /* uppercase A-F */
            total += str[i] - 'A' + 10;
        else /* lowercase a-f */
            total += str[i] - 'a' + 10;
    }

    return total;
}

uint32_t _hstrtoui32(char *str, int base)
{
    if(base == 16)
        return _hextoui32(str);
    else
        return _strtoui32(str);
}

答案 1 :(得分:1)

根据Java's operator precedence,您需要在jQuery("#table_list_1").addRowData(undefined, { id: id, time: wavesurfer.getCurrentTime() }); 附近加上括号,否则它将被解析为bytes[i] & 0xff

所以最后你的代码应该是这样的:

bytes[i] & (0xff << (size - 1 - i) * 8)