如何unsigned short
在 Java 中声明一个值?
16 回答
你不能,真的。Java 没有任何无符号数据类型,除了char
.
诚然,您可以使用char
- 它是一个 16 位无符号类型 - 但在我看来,这将是可怕的,因为char
它显然是用于文本:当代码使用 时char
,我希望它将它用于表示文本的 UTF-16 代码单元这对程序来说很有趣,而不是与文本无关的任意无符号 16 位整数。
如果你真的需要一个正好是 16 位的值:
解决方案 1:使用可用的有符号缩写,不要担心符号,除非您需要进行比较(<、<=、>、>=)或除法(/、%、>>)操作。请参阅此答案以了解如何处理已签名的数字,就好像它们未签名一样。
解决方案 2(解决方案 1 不适用):使用 int 的低 16 位,并在必要时使用 & 0xffff 删除高位。
这是一个非常陈旧的线程,但为了以后任何人的利益。char 是数字类型。它支持所有的数学运算符、位运算等。它是一个无符号 16。
我们处理定制嵌入式硬件记录的信号,因此我们处理大量来自 AD 的无符号 16。多年来,我们一直在到处使用字符,从未遇到任何问题。
您可以使用 char,因为它是一个无符号的 16 位值(尽管从技术上讲它是一个 unicode 字符,因此将来可能会更改为 24 位值)...另一种选择是使用 int 并确保它在范围内。
不要使用 char - 使用 int :-)
来自 DataInputStream.java
public final int readUnsignedShort() throws IOException {
int ch1 = in.read();
int ch2 = in.read();
if ((ch1 | ch2) < 0)
throw new EOFException();
return (ch1 << 8) + (ch2 << 0);
}
java中没有这种类型
不可能声明一个 unsigned short 类型,但在我的情况下,我需要获取 unsigned 数字才能在 for 循环中使用它。toUnsignedInt
类中有一个方法Short
返回“通过无符号转换转换为 int 的参数”:
short signedValue = -4767;
System.out.println(signedValue ); // prints -4767
int unsignedValue = Short.toUnsignedInt(signedValue);
System.out.println(unsingedValue); // prints 60769
Integer 和 Long 也存在类似的方法:
Integer.toUnsignedLong
Long.toUnsignedString
:在这种情况下,它以 a 结尾,String
因为没有更大的数字类型。
"In Java SE 8 and later, you can use the int data type to represent an unsigned 32-bit integer, which has a minimum value of 0 and a maximum value of 232-1." However this only applies to int and long but not short :(
是的,如果您想在代码与位操作中使用该值,则没有这样的事情。
不,真的没有这种方法,java是高级语言。这就是 Java 没有任何无符号数据类型的原因。
他说他想创建一个多维短数组。然而没有人建议按位运算符?从我读到的你想使用 16 位整数而不是 32 位整数来节省内存?
所以首先开始 10,000 x 10,000 短值是 1,600,000,000 位、200,000,000 字节、200,000 千字节、200 兆字节。
如果您需要 200MB 内存消耗的东西,您可能需要重新设计这个想法。我也不相信会编译更不用说运行了。如果有任何东西利用了称为按需加载和数据缓存的 2 个功能,则永远不应该像这样初始化大型数组。本质上,按需加载是指仅在需要时加载数据的想法。然后数据缓存做同样的事情,但使用自定义框架来删除旧内存并根据需要添加新信息。这个很难有良好的速度性能。您还可以做其他事情,但是如果做得好,这两件事是我最喜欢的。
好吧,回到我所说的按位运算符。
所以一个 32 位整数或 Java 中的“int”。您可以将所谓的“位”存储到此,因此假设您有 32 个布尔值,在 Java 中所有值占用 32 位(long 除外),或者对于数组,它们占用 8 个字节,16 个短字节,32 个 int . 因此,除非您有数组,否则您不会从使用字节或短字节中获得任何内存优势。这并不意味着您不应该使用它来确保您和其他人知道该值应具有的数据范围。
现在正如我所说,您可以通过执行以下操作有效地将 32 个布尔值存储到一个整数中:
int many_booleans = -1; //All are true;
int many_booleans = 0; //All are false;
int many_booleans = 1 | 2 | 8; //Bits 1, 2, and 4 are true the rest are false;
所以现在一个 short 由 16 位组成,所以 16 + 16 = 32 完全适合 32 位整数。因此,每个 int 值都可以包含 2 个短值。
int two_shorts = value | (value2 << 16);
所以上面所做的是值介于 -32768 和 32767 之间或作为无符号值 0 - 65535。所以假设值等于 -1,所以作为无符号值它是 65535。这意味着第 1 位到第 16 位被打开,但在实际执行数学运算时,请考虑范围 0 - 15。
所以我们需要激活位 17 - 32。所以我们必须从大于 15 位的东西开始。所以我们从 16 位开始。因此,通过取 value2 并将其乘以 65536,这就是 "<< 16" 的作用。我们现在假设 value2 等于 3 它将是 OR'd 3x65536 = 196608。所以我们的整数值将等于 262143。
int assumed_value = 262143;
所以假设我们要检索两个 16 位整数值。
short value1 = (short)(assumed_value & 0xFFFF); //-1
short value2 = (short)(assumed_value >> 16); //=3
也基本上将按位运算符视为 2 的幂。这就是它们的全部含义。永远不要用 0 和 1 来看待它。我发布此内容主要是为了帮助任何可能遇到此搜索无符号短数组甚至可能是多维数组的人。如果有任何错字,我很抱歉很快写了这个。
Java 没有无符号类型。你需要它做什么?
但是,Java 确实具有“字节”数据类型。
您可以自己编写一个ShortUnsigned
类并为您想要的那些运算符定义方法。唉,您将无法重载+
and-
和其他它们,也无法与其他原始或数字对象类型进行隐式类型转换。
像其他一些回答者一样,我想知道为什么您迫切需要 unsigned short 没有其他数据类型可以填充。
显示为什么需要无符号数的简单程序:
package shifttest;
public class ShiftTest{
public static void main(String[] args){
short test = -15000;
System.out.format ("0x%04X 0x%04X 0x%04X 0x%04X 0x%04X\n",
test, test>>1, test>>2, test>>3, test>>4);
}
}
结果:
0xC568 0xFFFFE2B4 0xFFFFF15A 0xFFFFF8AD 0xFFFFFC56
现在对于那些不是系统类型的:
JAVA 会进行算术移位,因为操作数是有符号的,但是,在某些情况下逻辑移位是合适的,但 JAVA(尤其是 Sun)认为没有必要,因为我们的短视,这对我们来说太糟糕了。Shift、And、Or 和 Exclusive Or 是有限的工具,当您拥有的都是签名较长的数字时。当连接到 16 位或更多位的“真实”计算机位的硬件设备时,这是一个特殊的问题。"char" 不能保证工作(现在是两个字节宽),但在几种基于东方 gif 的语言(如中文、韩文和日文)中,至少需要 3 个字节。我不熟悉 Sandscript 样式语言的数量需求。字节数不取决于程序员,而是 JAVA 标准委员会。因此,将 char 设为 16 位具有下游风险。为了安全地实现无符号短裤 JAVA,特殊类是基于上述歧义的最佳解决方案。该类的缺点是无法重载这个特殊类的数学运算。该线程的许多贡献者准确地指出了这些问题,但我的贡献是一个工作代码示例以及我在 Linux 下使用 C++ 的 3 字节 gifs 语言的经验。
//вот метод для получения аналога unsigned short
public static int getShortU(byte [] arr, int i ) throws Exception
{
try
{
byte [] b = new byte[2];
b[1] = arr[i];
b[0] = arr[i+1];
int k = ByteBuffer.wrap(b).getShort();
//if this:
//int k = ((int)b[0] << 8) + ((int)b[1] << 0);
//65536 = 2**16
if ( k <0) k = 65536+ k;
return k;
}
catch(Throwable t)
{
throw new Exception ("from getShort: i=" + i);
}
}