将两个short打包成一个int,处理正负数问题

8

我正在创建一个名为PackedUnsigned1616的类,它可以将两个无符号短整数存储在一个整数中,还有一个名为PackedSigned1616的类,它可以将两个有符号短整数存储在一个整数中。我已经阅读了位运算的相关内容,但仍然不清楚如何处理有符号和无符号以及大于或小于short范围的值(它们作为两个int传入)。以下是我目前的代码:

public final class PackedUnsigned1616 {
public final int field;

private static final int RIGHT = (2 << 15) - 1;
private static final int LEFT = ((2 << 31) - 1) ^ RIGHT;

public PackedUnsigned1616(int left, int right) {
    field = (left << 15) | (right & RIGHT);
}

public int getLeft() {
    return field >> 15;
}
public int getRight() {
    return field & RIGHT;
}

整个概念让我感到很困惑,如果您能稍微解释一下,那将非常有帮助。


1
那么期望的行为是什么?您可以表示的最大短整数是(2<<15)-1,因此如果您使用大于该数字的数字调用构造函数,应该发生什么? - Tyler
哦,抱歉,我希望它被夹紧。 - Caleb Jares
1
这是为了好玩还是解决实际问题? - Thorbjørn Ravn Andersen
这是用于粒子模拟器的。 - Caleb Jares
1个回答

11

有趣的LEFT和RIGHT初始化方式。尝试使用以下方法代替:

public final class PackedUnsigned1616 {
    public final int field;
    
    private static final int RIGHT = 0xFFFF;
    
    public PackedUnsigned1616(int left, int right) {
        field = (left << 16) | (right & RIGHT);
    }
    
    public int getLeft() {
        return field >>> 16; // >>> operator 0-fills from left
    }

    public int getRight() {
        return field & RIGHT;
    }
}

对于带符号的值,我认为你需要修改getLeft和getRight如下:

    public int getLeft() {
        return field >> 16; // sign bit is significant
    }

    public int getRight() {
        return (short) (field & RIGHT); // gets cast back to signed int
    }

谢谢!但我该如何创建PackedSigned1616? - Caleb Jares
@Ted - 我在互联网上搜索了0xFFFF表示法。这是十六进制吗?0x代表什么?此外,无符号版本的getLeft函数不起作用。使用值(5, 32767),它返回10和32727。对于(5, 32766)和(5, 27766)也是如此。 - Caleb Jares
1
@cable729 - 0xFFFF 表示十六进制字面量。它在 Java 语言规范 中有定义。至于代码无法工作的问题,我修复了我的代码中的一个错误(我是通过复制你的代码继承的 :-0),其中它将移位由 15 改为了 16。请确保您正在使用修订版本。 - Ted Hopp
是的,我也发现了 :) 感谢你的帮助! - Caleb Jares
1
对于有符号的值,您可以返回一个 short - Peter Lawrey

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