gpt4 book ai didi

java - JAVA 中的符号扩展、位移位。帮助理解 C 代码位

转载 作者:太空宇宙 更新时间:2023-11-04 01:27:05 24 4
gpt4 key购买 nike

我有以下 C 代码(来自 FFMPEG):

static inline av_const int sign_extend(int val, unsigned bits)
{
unsigned shift = 8 * sizeof(int) - bits;
union { unsigned u; int s; } v = { (unsigned) val << shift };
return v.s >> shift;
}

我正在尝试用 JAVA 重现它。但我很难理解这一点。无论我如何抛掷这些位,我都离不开很近。

对于value参数:它取无符号字节值作为int。

位参数:4

如果值为 255 且位为 4。它返回 -1。我无法在 JAVA 中重现这个。很抱歉提出这样模糊的问题。但是你能帮我理解这段代码吗?

总的来说,我正在尝试用 JAVA 对 EA ADPCM 音频进行编码。在 FFMPEG 中: https://gitorious.org/ffmpeg/ffmpeg/source/c60caa5769b89ab7dc4aa41a21f87d5ee177bd30:libavcodec/adpcm.c#L981

最佳答案

严格来说,使用此输入数据运行此代码的结果是不确定的,因为 C 中的带符号位移位仅在不满足此场景的情况下才正确定义。来自 C99 标准:

The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has unsigned type or if E1 has signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2E2. If E1 has a signed type and negative value, the resulting value is implementation-defined.

(强调我的)

但我们假设您的实现定义了带符号的右移以扩展符号,这意味着如果设置了符号位,则左侧的空间将填充 1,否则将填充为 0; ffmpeg 代码显然期望是这种情况。发生以下情况:shift的值为 28 (假设 32 位整数)。在二进制表示法中:

00000000 00000000 00000000 11111111 = val
11110000 00000000 00000000 00000000 = (unsigned) val << shift

在解释(unsigned) val << shift时注意作为有符号整数,随着代码的继续执行(假设 two's complement 表示,因为今天的计算机都使用 1),该整数的符号位被设置,所以向右的有符号移位填满用左边的零,我们得到

11110000 00000000 00000000 00000000 = v.s
11111111 11111111 11111111 11111111 = v.s >> shift

...并且以二进制补码表示,即 -1。

在 Java 中,这个技巧以同样的方式工作——除了更好,因为那里的行为实际上是有保证的。简单地:

public static int sign_extend(int val, int bits) {
int shift = 32 - bits; // int always has 32 bits in Java
int s = val << shift;
return s >> shift;
}

或者,如果您愿意:

public static int sign_extend(int val, int bits) {
int shift = 32 - bits;
return val << shift >> shift;
}

1 严格来说,由于历史原因,这种转换在 C 标准中也没有明确定义的值。曾经有使用不同表示的计算机,并且具有一组符号位的相同位模式在(例如)带符号的幅度表示中具有完全不同的含义。

关于java - JAVA 中的符号扩展、位移位。帮助理解 C 代码位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29265800/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com