我很难理解一些代码,这些代码显示了一个示例,该示例如何将Java中的double转换为byte [],反之亦然。
这是用于将双精度型转换为byte []的代码:
public static byte [] doubleToByteArray (double numDouble)
{
byte [] arrayByte = new byte [8];
long numLong;
// Takes the double and sticks it into a long, without changing it
numLong = Double.doubleToRawLongBits(numDouble);
// Then we need to isolate each byte
// The casting of byte (byte), captures only the 8 rightmost bytes
arrayByte[0] = (byte)(numLong >>> 56);
arrayByte[1] = (byte)(numLong >>> 48);
arrayByte[2] = (byte)(numLong >>> 40);
arrayByte[3] = (byte)(numLong >>> 32);
arrayByte[4] = (byte)(numLong >>> 24);
arrayByte[5] = (byte)(numLong >>> 16);
arrayByte[6] = (byte)(numLong >>> 8);
arrayByte[7] = (byte)numLong;
for (int i = 0; i < arrayByte.length; i++) {
System.out.println("arrayByte[" + i + "] = " + arrayByte[i]);
}
return arrayByte;
}
这是用于将byte []转换为double的代码:
public static double byteArrayToDouble (byte [] arrayByte)
{
double numDouble;
long numLong;
// When putting byte into long, java also adds the sign
// However, we don't want to put bits that are not from the orignal value
//
// The rightmost bits left unaltered because we "and" them with a 1
// The left bits become 0 because we "and" them with a 0
//
// We are applying a "mask" (& 0x00 ... FFL)
// 0 & 0 = 0
// 0 & 1 = 0
// 1 & 0 = 0
// 1 & 1 = 1
//
// So, the expression will put byte in the long (puts it into the right most position)
// Then we apply mask to remove the sign applied by java
// Then we move the byte into its position (shift left 56 bits, then 48 bits, etc.)
// We end up with 8 longs, that each have a byte set up in the appropriate position
// By doing an | with each one of them, we combine them all into the orignal long
//
// Then we use Double.longBitsToDouble, to convert the long bytes into double.
numLong = (((long)arrayByte[0] & 0x00000000000000FFL) << 56) | (((long)arrayByte[1] & 0x00000000000000FFL) << 48) |
(((long)arrayByte[2] & 0x00000000000000FFL) << 40) | (((long)arrayByte[3] & 0x00000000000000FFL) << 32) |
(((long)arrayByte[4] & 0x00000000000000FFL) << 24) | (((long)arrayByte[5] & 0x00000000000000FFL) << 16) |
(((long)arrayByte[6] & 0x00000000000000FFL) << 8) | ((long)arrayByte[7] & 0x00000000000000FFL);
numDouble = Double.longBitsToDouble(numLong);
return numDouble;
}
好的,这是我不太了解的部分。
((long)arrayByte[0] & 0x00000000000000FFL) << 56
似乎强制转换发生在实际的按位运算之前,因为作者说
该表达式将把字节放在长[…]处,然后应用mask删除java施加的符号
在实际转换之前,如何将字节转换为很长时间?操作不应该与此相似吗?
(((long)arrayByte[0]) & 0x00000000000000FFL) << 56
还是还有其他我不理解的东西?
这是由于Java中的运算符优先级和关联性是如何工作的。1个
不幸的是,Oracle
Java教程
仅提供了部分概述,并且Java语言规范也无济于事,因为它主要是通过声明以下内容来让操作员确定操作员的优先级:
运算符之间的优先级由语法产生的层次结构管理。
通常,表达式是从左到右计算的。就运算符优先级而言, 适用于下表2:
╔═══════╦══════════════╦══════════════════════╦═════════════════╗
║ Level ║ Operator ║ Description ║ Associativity ║
╠═══════╬══════════════╬══════════════════════╬═════════════════╣
║ 16 ║ [] ║ access array element ║ left to right ║
║ ║ . ║ access object member ║ ║
║ ║ () ║ parentheses ║ ║
╠═══════╬══════════════╬══════════════════════╬═════════════════╣
║ 15 ║ ++ ║ unary post-increment ║ not associative ║
║ ║ -- ║ unary post-decrement ║ ║
╠═══════╬══════════════╬══════════════════════╬═════════════════╣
║ 14 ║ ++ ║ unary pre-increment ║ right to left ║
║ ║ -- ║ unary pre-decrement ║ ║
║ ║ + ║ unary plus ║ ║
║ ║ - ║ unary minus ║ ║
║ ║ ! ║ unary logical NOT ║ ║
║ ║ ~ ║ unary bitwise NOT ║ ║
╠═══════╬══════════════╬══════════════════════╬═════════════════╣
║ 13 ║ () ║ cast ║ right to left ║
║ ║ new ║ object creation ║ ║
╠═══════╬══════════════╬══════════════════════╬═════════════════╣
║ 12 ║ * ║ multiplicative ║ left to right ║
║ ║ / ║ ║ ║
║ ║ % ║ ║ ║
╠═══════╬══════════════╬══════════════════════╬═════════════════╣
║ 11 ║ + - ║ additive ║ left to right ║
║ ║ + ║ string concatenation ║ ║
╠═══════╬══════════════╬══════════════════════╬═════════════════╣
║ 10 ║ << >> ║ shift ║ left to right ║
║ ║ >>> ║ ║ ║
╠═══════╬══════════════╬══════════════════════╬═════════════════╣
║ 9 ║ < <= ║ relational ║ not associative ║
║ ║ > >= ║ ║ ║
║ ║ instanceof ║ ║ ║
╠═══════╬══════════════╬══════════════════════╬═════════════════╣
║ 8 ║ == ║ equality ║ left to right ║
║ ║ != ║ ║ ║
╠═══════╬══════════════╬══════════════════════╬═════════════════╣
║ 7 ║ & ║ bitwise AND ║ left to right ║
╠═══════╬══════════════╬══════════════════════╬═════════════════╣
║ 6 ║ ^ ║ bitwise XOR ║ left to right ║
╠═══════╬══════════════╬══════════════════════╬═════════════════╣
║ 5 ║ | ║ bitwise OR ║ left to right ║
╠═══════╬══════════════╬══════════════════════╬═════════════════╣
║ 4 ║ && ║ logical AND ║ left to right ║
╠═══════╬══════════════╬══════════════════════╬═════════════════╣
║ 3 ║ || ║ logical OR ║ left to right ║
╠═══════╬══════════════╬══════════════════════╬═════════════════╣
║ 2 ║ ?: ║ ternary ║ right to left ║
╠═══════╬══════════════╬══════════════════════╬═════════════════╣
║ 1 ║ = += -= ║ assignment ║ right to left ║
║ ║ *= /= %= ║ ║ ║
║ ║ &= ^= |= ║ ║ ║
║ ║ <<= >>= >>>= ║ ║ ║
╚═══════╩══════════════╩══════════════════════╩═════════════════╝
对于您的特定问题,这意味着在强制转换操作周围无需放置任何括号,因为强制转换运算符的优先级()
高于按位与&
运算符的优先级(13级对7级)。
1我将其写成一个规范的答案,以解决有关Java中的运算符优先级和关联性的问题。我发现了很多现有的给出部分信息的答案,但是找不到完整的优先级和关联性表的概述的答案。
2运算符优先级和关联表摘自https://introcs.cs.princeton.edu/java/11precedence/。
所有的数学运算都认为是从左向右运算的, Java 语言中大部分运算符也是从左向右结合的,只有单目运算符、赋值运算符和三目运算符例外,其中,单目运算符、赋值运算符和三目运算符是从右向左结合的,也就是从右向左运算。 乘法和加法是两个可结合的运算,也就是说,这两个运算符左右两边的操作数可以互换位置而不会影响结果。运算符有不同的优先级,所谓优先级就是在表达式运算中的运算顺序。 一般而言,单目运算符优先级较
问题内容: 由于Java中运算符优先级的正确性,我感到困惑。我在教程很久以前读到并具有更高的优先级高于OR,这是在提供的答案确认问题。但是,我目前正在使用《 Sun Java 6认证程序员学习指南》学习Java。本书包含以下示例: 我复制并引用了有关编译器如何处理上述代码的解释: 是,然后是或结果 为,然后打印。由于存在短路,因此对表达式进行评估,好像周围有括号。换句话说,它被评估为之前的单个表达
正则表达式与数学表达式的不同在于,数学表达式执行数学运算,而正则表达式执行字符运算;相同的是,它们都按一定的优先级进行运算 运算符 操作 \ 转义符 () 捕获、匹配、断言 [] 字符类 *+? 限定符 {} 范围 ^$ 位置和顺序 | 或
从高到低顺序如下: ^ not - (一元运算) * / + - ..(字符串连接) < > <= >= ~= == and or
问题内容: 在来自http://leepoint.net/notes- java/data/expressions/precedence.html的 一个示例中 以下表达式 被评估为 然后我从http://www.roseindia.net/java/master-java/operator- precedence.shtml 看到了另一个示例 以下表达式 被评估为 我对如何确定在涉及*和/时将首
优先级从上到下依次递减,最上面具有最高的优先级,逗号操作符具有最低的优先级。 相同优先级中,按结合顺序计算。大多数运算是从左至右计算,只有三个优先级是从右至左结合的,它们是单目运算符、条件运算符、赋值运算符。 基本的优先级需要记住: 指针最优,单目运算优于双目运算。如正负号。 先乘除(模),后加减。 先算术运算,后移位运算,最后位运算。请特别注意:1 << 3 + 2 & 7等价于 (1 << (