Java中负字节和短数据类型中的位操作 [英] Bit manipulation in negative byte and short data types in Java

查看:115
本文介绍了Java中负字节和短数据类型中的位操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现一个存储32位数字的类,而不使用int原语类型.为此,我使用两个short变量msbslsbs来存储数字的32位,每个变量16位. 变量msbs将存储数字的前16位,变量lsbs将存储数字的前16位.

Im trying to implement a class that stores a 32-bit number without using the int primitive type. For doing so, I'm using two short variables msbs and lsbs to store the 32 bits of the number, 16 bits in each variable. The variable msbs will store the first 16 bits of the number and the lsbs variable the 16 bits left.

当将给定的字节保存到变量时,我应用下一个公式:(字节顺序以Little-Endian表示法给出)

When It comes to save the given bytes to the variables I apply the next formula: (The bytes order are given as Little-Endian notation)

输入-> byte[] n = {0b00110101, -3, 0b1001, 0b0};到数字0b00000000 00001001 11111101 00110101(654645)

Input -> byte[] n = {0b00110101, -3, 0b1001, 0b0}; to the number 0b00000000 00001001 11111101 00110101 (654645)

msbs = ((n[3] << 8) | n[2]); lsbs = ((n[1] << 8) | n[0]);

msbs = ((n[3] << 8) | n[2]); lsbs = ((n[1] << 8) | n[0]);

如下所示

private void saveNumber(byte[] n) {
    msbs = (byte)((n[3] << 8) | n[2]);
    lsbs = (byte)((n[1] << 8) | n[0]);

    System.out.println(Integer.toBinaryString((n[1] << 8) | n[0]));//Prints 11111111111111111111110100110101

    System.out.println("msbs -> " + Integer.toBinaryString(msbs));
    System.out.println("lsbs -> " + Integer.toBinaryString(lsbs));//Prints 110101
}

System.out.println(Integer.toBinaryString((n[1] << 8) | n[0]));//Prints 11111111111111111111110100110101

精确地打印了我需要的内容,尽管在开始时有大量无用的1位(我可以将其强制转换为short来消除它们) 但是,当我打印lsbs时,我存储的值完全相同(显然),当它应该为0b1111110100110101

prints exactly what I need, despite the huge amount of useless 1's bits at the beggining (of which I can get rid of just by casting it to short) But when I print the lsbs where I store the exact same value (apparently) it outputs 110101 when It should be 0b1111110100110101

为什么会出现这种现象?我了解这一定与Java在将值11111111111111111111110100110101存储为16位原始类型时执行的内部"强制转换有关(我个人认为,由于将8位移至剩下一个8位数字,应该给我一个16位数字) 附带说明一下,msbs变量确实可以实现我想要的功能,因此问题应该与Java表示负数的方式有关

Why does this behavior occur? I understand It must be something with the "internal" casting performed by Java at the time of store the value 11111111111111111111110100110101 into a 16 bits primitive type (Which personally, I think sholdn't be happening because I am shifting 8 bits to the left in an 8-bits number which should give me a 16-bits number) As a side note, the msbs variable is doing exactly what I want it to do, so the problem should be related to the way that Java represents the negative numbers

顺便说一句,我知道Java并不是完全有趣的语言.

Btw, I know Java isn't exactly the best language to have fun with bits.

推荐答案

为什么会出现这种现象?

Why does this behavior occur?

在Java中,所有按位运算都是32或64位运算.这与某些其他语言不同,并且可能是意外的.但这就是它.

In Java, all bitwise operations are 32 or 64 bit operations. This is different from some other languages, and can be unexpected. But it is what it is.

我了解这一定与Java进行的内部"转换有关.

I understand It must be something with the "internal" casting performed by Java ....

在您的任何示例中,Java均未进行隐式缩小强制转换 1 .实际上,我认为导致意外行为的原因是代码中的转换范围明显缩小:

Java doesn't do an implicit narrowing casts in any of your examples1. In fact, I think that the cause of the unexpected behaviour is an explicit narrowing cast in your code:

  msbs = (byte)((n[3] << 8) | n[2]);

您已明确将32位值从((n[3] << 8) | n[2])强制转换为byte.根据您的期望,您应该转换为short.

You have explicitly cast a 32 bit value from ((n[3] << 8) | n[2]) to a byte. Based on what you say you expect, you should be casting to short.

在旁边:当您编写这样的内容时,"我个人认为这不会发生……" 这意味着您正在怀疑Java编译器的正确性.实际上,在99.999%的情况下 2 ,真正的问题是有人不了解编译器应该怎么做;即他们对语言的了解太浅 3 .在大多数情况下,有一种编程语言的规范可以精确地精确地表达特定构造的含义.在Java情况下,它就是Java语言规范.

Aside: When you write things like this "Which personally, I think sholdn't be happening ..." it implies that you are doubting the correctness of the Java compiler. In fact, in 99.999% of cases2, the real problem is someone does not understand what the compiler should do with their; i.e. their knowledge of the language is too shallow3. In most cases, there is a specification of the programming language that says precisely what a particular construct means. In the Java case, it is the Java Language Specification.

1-实际上,我只能想到赋值运算符中原始类型会在内部缩小的地方.

2-我增加了这个数字,但要点是,编译器错误很少是应用程序意外行为的原因.

3-也许这只是程序员错过的一个应用程序错误.疲倦会对大脑造成不良影响...

这篇关于Java中负字节和短数据类型中的位操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆