我希望我在特定表中的一列不会得到负数。有没有办法在 derby DB 中声明一个 unsigned int ?
3 回答
问:有没有办法在 Derby DB 表中声明列“unsigned int”?
A:我相信答案是“否”:
http://db.apache.org/derby/docs/10.0/manuals/reference/sqlj124.html
http://db.apache.org/derby/docs/10.0/manuals/reference/sqlj124.html
... 然而 ...
您应该能够轻松地“投射”任何查询中的存储值:
答案是不。Java(不幸的是)不支持无符号算术。
但是您仍然可以使用 Javaint
并制作自己的方法来执行无符号算术,就像这样。更好的是创建一个UnsignedInteger
类并让它处理所有的算术。
我不知道这是否值得。您可以long
按照 jtahlborn 的建议使用。
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);
}
}
祝你好运,希望以上内容有所帮助!