0

我希望我在特定表中的一列不会得到负数。有没有办法在 derby DB 中声明一个 unsigned int ?

4

3 回答 3

1

问:有没有办法在 Derby DB 表中声明列“unsigned int”?

A:我相信答案是“否”:

... 然而 ...

您应该能够轻松地“投射”任何查询中的存储值:

于 2012-09-04T23:14:03.393 回答
0

答案是不。Java(不幸的是)不支持无符号算术。

但是您仍然可以使用 Javaint并制作自己的方法来执行无符号算术,就像这样。更好的是创建一个UnsignedInteger类并让它处理所有的算术。

我不知道这是否值得。您可以long按照 jtahlborn 的建议使用。

于 2012-09-04T23:31:18.663 回答
0

Java 不支持 type unsigned int,而不是 C 或 C++。

另一方面,有一种简单的方法可以通过使用以下方法来规避此限制:

  • 中间long变量/文字
  • 演员表(int)

首先,让我们注意有符号和无符号 int 具有相同的位数;它们的大小都是 32 位。

主要区别在于,对于有符号整数,MSB(最高有效位)或位 0 用于指示实际整数是负数还是正数。

如果该位设置为 1,则整数为负,如果设置为 0,则整数为负。因此,您最终将得到 31 位的整数值和 1 位的符号。

对于无符号整数,所有 32 位都用于表示整数的值。您现在可以拥有更大的数字。

signed integers范围从-2^31(2^31 - 1)

unsigned integers范围从0(2^32 - 1)

要显示大小限制问题,请尝试编译以下代码段:

    public static void main (String[] args){
        
        int i = 2_147_483_648;//This line will generate a compiler error
    }
}

编译器会抱怨说integer number too large.

让我们看看如何规避这个问题并仍然将这个数字存储在一个 Java 整数中,然后再取回它。

提议的解决方案背后的想法源于这样一个事实,即一系列位被解释为意味着什么。它可以是图像、Java 对象、C 结构、字符等的表示。

您根据您“期望”该系列位要表示的内容“解释”该系列位。如果您期待一个字符,您可能希望将该系列与 ASCII 表进行匹配。如果您期待图像,您可能希望解码 JPEG。

现在,回到整数,如果您正在寻找,signed integers您会将 MSB 解释为符号位。如果您正在寻找,unsigned integers您会将 MSB 解释为值的一部分。

举个例子,让我们假设您有以下 32 位系列:

  • 十六进制 0x8000_0000 或二进制 0b1000_0000_0000_0000_0000_0000_0000_0000

MSB 设置为 1,所有其他位为 0。

如果您正在寻找/期望signed integer这些 32 位将被解释为负十进制数的表示-2_147_483_648

如果您正在寻找/期望unsigned integer这些相同的 32 位将被解释为正十进制数的表示2_147_483_648

因此,解决方案是将值存储在带符号的 32 位整数中,并将它们解释为无符号的 32 位整数。

这是我们将如何修改前面的代码片段并将其保存2_147_483_648为整数值并能够正确打印的方法。

为此,我们将:

  • 首先,使用long中间数据类型/值
  • 然后将该值转换为int以保存它
  • 最后,屏蔽/忽略&多余的位并显示它
    public static void main (String[] args){
        //1. cast a 64-bit long value that fits into a 32-bit int
        int i = (int)2_147_483_648L;
        //2. Mask the extra long bits
        System.out.println(i & 0x0000_0000_FFFF_FFFFL);
    }
}

long变量可以保存 64 位,其 MSB 或符号位不受其前 32 位的影响。您会注意到这里发生了按位运算:

i & 0x0000_0000_FFFF_FFFFL

这告诉编译器忽略或屏蔽超出我们感兴趣的前 32 位的所有位。我们的整数是 32 位的。

如果您想int在保存之前对值进行一些算术运算,您可以再次求助于long中间变量。

以下是方法,这将是建议的解决方案:

    public static void main (String[] args){
        int i = (int)2_147_483_648L;
        int j = 1_000_000;
        long tempL = i + j;//Use a temp long to perform the operations
        i = (int)tempL; //We save back into i and store in a DB for example
  
        //Now we use the saved value to display it, for example
        System.out.println(i & 0x0000_0000_FFFF_FFFFL);
    }
}

祝你好运,希望以上内容有所帮助!

于 2021-02-27T23:16:27.807 回答