【问题标题】:Java hex calculationJava 十六进制计算
【发布时间】:2019-04-16 22:10:44
【问题描述】:

我有 longbits 声明如下:

long bits = len*8L; (304)

System.out.println(bits); 输出为 304

如果我像这样使用长名称位,我将分别得到 0 和 0。

System.out.println(bits>>(4*8));
System.out.println(0xFF&(bits>>(4*8)));

如果我使用实际数字,像这样,我分别得到 304 和 48

System.out.println(304>>(4*8));
System.out.println(0xFF&(304>>(4*8)));

我正在尝试将此 Java 转换为 JavaScript,但 JavaScript 在所有情况下都给我 304 和 48。我需要它来匹配 Java 并给出 0 和 0 的值。

编辑

跟进,只是为了清楚一点,我需要相当于等于 0 的 JavaScript,模仿 Java 目前是如何做到的(上面两个等于 0 的例子在我们正在开发的东西中不会改变)。

所以 console.log(0xFF&(bits>>(4*8))) 应该等于 0,它目前等于 48

【问题讨论】:

  • 在 Java 中,304 是一个 int,因此对于要移位的位数有一个隐含的 ((4*8)%32)bits 是一个long,所以有一个隐含的((4*8)%64)。 JavaScript,我不知道...
  • 并跟进@KenY-N Javascript 将所有转换作为 32 位数字进行。所以忽略了 32 位的移位。

标签: javascript java hex long-integer calculation


【解决方案1】:

JLS, Section 15.19 涵盖了 Java 中的移位运算符。

如果左侧操作数的提升类型是int,则只有右侧操作数的五个最低位用作移位距离。就好像右手操作数经过位逻辑与运算符 & (§15.22.1) 与掩码值 0x1f (0b11111)。因此,实际使用的移位距离始终在031 的范围内。

对于int 值,例如3044*8 或 32 的位移值实际上是 0,因此不会发生位移。然后一点点与0xFF 产生48

如果左侧操作数的提升类型是long,则只有右侧操作数的六个最低位用作移位距离。就好像右手操作数经过位逻辑与运算符 & (§15.22.1) 与掩码值 0x3f (0b111111)。因此,实际使用的移位距离始终在063 的范围内。

对于long 值,4*8 的位移值确实向右移动了 32 位,从而产生 0

This page 涵盖 JavaScript 位移运算符。

按位运算符将其操作数视为 32 位(零和一)的序列,而不是十进制、十六进制或八进制数。

似乎 JavaScript 将数字转换为 32 位数字,例如 Java int。同样的“只有最少 5 位”规则似乎也适用于 JavaScript 中的移位操作数。

console.log(304>>32);        // Don't shift!
console.log(0xFF&(304>>32)); // Don't shift!
console.log(304>>33);        // Shift by 1, not 33
console.log(0xFF&(304>>33)); // Shift by 1, not 33

【讨论】:

  • 感谢您的回答,我将检查 JavaScript 位移运算符。我需要 JavaScript 等于 0,比如 Java。
【解决方案2】:

如果您想在 Java 中使用常量和变量获得相同的结果,则需要将 304 作为长常量与 304L 一起传递,如下所示:

System.out.println(304L>>(4*8));
System.out.println(0xFF&(304L>>(4*8)));

原因是您不能将 int 移位 4*8=32 位; Java 将移动 32 模 32 = 零但是,因为 int 只有 32 位长。

相比之下,Javascript 不支持使用 >> 运算符移动 64 位整数;它将您传递给 >> 的每个数字视为 32 位整数。

你可以编写自己的函数来做类似的事情:

function rshift(num, bits) {
    return Math.round(num / Math.pow(2,bits));
}

console.log(rshift(304, 4*8))

【讨论】:

  • rshift 几乎成功了。其中一个计算是 0*8 位,其值为 304。Java 等效值为 48
  • 你是说Java代码System.out.println(304L >> (0*8))给你48?还是那个System.out.println(0xff & (304L >> (0*8)))?给你48?因为后者的等价物是 console.log(0xff & rshift(304, 0*8)) 并且在 Javascript 中也输出 48。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-27
  • 1970-01-01
  • 2019-04-29
  • 1970-01-01
  • 2016-08-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多