我试图了解以下代码行的工作原理:
for (int i = 0; i < numSamples; i++) {
short ampValue = 0;
for (int byteNo = 0; byteNo < 2; byteNo++) {
ampValue |= (short) ((data[pointer++] & 0xFF) << (byteNo * 8));
}
amplitudes[i] = ampValue;
}
据我所知,这是以包含方式读取2个字节(每个样本2个字节),即ampValue由两个字节读取组成。数据是实际数据样本(文件),并且指针正在增加以将其读取到最后一个样本。但我不明白这一部分:
"data[pointer++] & 0xFF) << (byteNo * 8)); "
另外,我想知道如果我想把它读成双倍而不是短片,是否有任何区别?
答案 0 :(得分:0)
在Java中,所有字节都是有符号的。表达式(data[pointer++] & 0xFF)
将带符号的字节值转换为带有字节值的int(如果它是无符号的)。然后,表达式<< (byteNo * 8)
将结果值左移0或8位,具体取决于byteNo
的值。整个表达式的值按位或ampValue
分配。
此代码中似乎存在错误。迭代之间ampValue
的值不会重置为零。并且未使用amplitude
。这些标识符是否应该相同?
答案 1 :(得分:0)
看起来data []是字节数组。
data [pointer ++]为您提供[-128..127]范围内的字节值。
0xFF是一个int contstant,所以......
数据[指针++]&amp; 0xFF将字节值提升为[-128..127]范围内的int值。然后&amp;运算符将所有未在0xFF中设置的位清零(即,它将24位高位清零,只留下低8位。
该表达式的值现在将在[0..255]范围内。
&lt;&lt;运算符将结果向左移动(byteNo * 8)位。这与说法相同,它将值乘以2乘以(byteNo * 8)的幂。当byteNo == 0时,它将乘以2到幂0(即,它将乘以1)。当byteNo == 1时,它将乘以2到幂8(即它将乘以256)。
此循环在数组中的每对字节的[0..65535](16位)范围内创建一个int,将每对中的第一个成员作为低位字节,将第二个成员作为高阶字节。
将ampValue声明为double是不行的,因为| =运算符不能用于double,但是你可以将amplitudeitude []数组声明为double的数组,并赋值{{1将隐式地将值提升为[0.0..65535.0]范围内的double值。
其他信息:不要忽视@ KevinKrumwiede对该示例中的错误的评论。
答案 2 :(得分:0)
让我们分解声明:
|=
是按位或赋值运算符。 a |= b
相当于a = a | b
。(short)
将int
数组中的data
元素投射到short
。pointer++
是一个增量后操作。 pointer
的值将被返回并使用,然后每次以这种方式访问时立即递增 - 这在这种情况下是有益的,因为外循环循环通过2字节样本(通过内循环)来自连续的data
缓冲区,因此这会不断增加。&
是按位AND运算符,0xFF
是字节0b11111111
的十六进制值(十进制为255);表达式data[pointer++] & 0xFF
基本上是对于从data
数组中检索到的字节中的每个位,以及1
。在此上下文中,它强制Java,默认情况下存储 signed 字节对象(即十进制中-128到127的值),以将值作为 unsigned 字节返回(即0到255之间的值。)<<
将第二批8位左移,作为最高有效位。 byteNo * 8
确保只有当它是两个字节中的第二个时才会移位。在读取了两个字节后,ampValue
现在将样本的值包含为short
。