将C#代码迁移到Java,无符号短整型和字节数组转换

4

我正在使用Java编写一段代码(我对Java比较陌生),这段代码之前是用C#编写的。以下是C#中的代码和示例。

ushort number = 0xAABB; // 43707
byte[] data = new byte[2];
EndianBitConverter.Big.CopyBytes(number, data, 0); // value[0] = 170, value[1] = 187

由于.NET默认为小端序,我在.NET中使用自定义位转换器。无论如何,根据我对Java的了解,如果我想要与byte[]相同的结果,则应该期望我的值(170和187)比128(Byte.MAX_VALUE + 1)小,即(42,59)-因为.NET和Java具有不同的byte类型范围。以下是我在Java中编写的模拟上述逻辑的代码:

public class Ushort {
    private int value = 0;

    public Ushort(int i) {
        value = i - (Short.MAX_VALUE + 1);
    }

    public int get() {
        return value;
    }

    public byte[] getBytes() {
        byte[] result = new byte[]{
                (byte) (value >>> 24),
                (byte) (value >>> 16),
                (byte) (value >>> 8),
                (byte) value};

        return new byte[]{result[2], result[3]};
    }
}

然而,当我使用上述代码调用时,

new Ushort(0xAABB).getBytes()

结果应该是[42,-69]而不是[42,59]。最后一个字节比应该小128。
我真的需要一些关于如何正确执行此操作以及我的逻辑是否正确的指针。
我还需要对uint,ulong等执行相同的操作,因此我需要正确理解这一点。
2个回答

5

要么我不理解你试图进行的转换的原因,要么它们被错误地构想了,这意味着我无法发表关于它们的实现是否有误的意见。

在Java中,类型byte与C#中的类型sbyte完全相同,因此您可以使用sbyte在C#中进行所有测试,并确保在将其移植到Java之前正确运行。

(byte)0xaa = 170
(sbyte)0xaa = -86
(byte)0xbb = 187
(sbyte)0xbb = -69

所以,在Java中,你的字节数组应该是{-86,-69}。

谢谢,我没有想到sbyte,这就是我所需要的。 - Tomislav Markovski
没关系,这种情况发生在我们所有人身上。在编写C#代码几年后的某一天,我学习到了"??"运算符的存在。 - Mike Nakis

3
我没有测试过,但我会这样做:
public class Ushort {
    private int value = 0;

    public Ushort(int i) { // Changed
        if (i > 0xFFFF || i < -(0xFFFF))
            throws IllegalArgumentException("integer overflow")
        value = i;
    }

    public int get() {
        return value;
    }

    public byte[] getBytes() { // Changed! (Use & 0xFF)
        return new byte[]{
                (byte) ((value >>> 8) & 0xFF),
                (byte) (value & 0xFF)};

    }
}

这段代码给出了正确的结果,但由于它在某种程度上解决了我的所有问题,我必须接受Mike的答案。我之前测试和理解从.net到java的字节转换是错误的...令人尴尬 :) - Tomislav Markovski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接