Java 中的无符号短整型

发布于 2024-08-12 23:23:41 字数 50 浏览 8 评论 0原文

如何在 Java 中声明 unsigned Short 值?

How can I declare an unsigned short value in Java?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

感情废物 2024-08-19 23:23:41

你不能,真的。除了 char 之外,Java 没有任何无符号数据类型。

诚然,您可以使用char - 它是一个16位无符号类型 - 但在我看来这将是可怕的,因为char显然意味着用于文本:当代码使用 char 时,我希望它将它用于代表程序感兴趣的文本的 UTF-16 代码单元,而不是与文本无关的任意无符号 16 位整数。

You can't, really. Java doesn't have any unsigned data types, except char.

Admittedly you could use char - it's a 16-bit unsigned type - but that would be horrible in my view, as char is clearly meant to be for text: when code uses char, I expect it to be using it for UTF-16 code units representing text that's interesting to the program, not arbitrary unsigned 16-bit integers with no relationship to text.

卸妝后依然美 2024-08-19 23:23:41

如果您确实需要一个恰好 16 位的值:

解决方案 1: 使用可用的有符号短整型,不再担心符号,除非您需要进行比较 (<, <=, >, >=)或除法(/、%、>>)运算。请参阅此答案了解如何处理带符号的数字如果他们没有签名。

解决方案 2(解决方案 1 不适用):使用 int 的低 16 位并使用 & 删除高位。必要时为 0xffff。

If you really need a value with exactly 16 bits:

Solution 1: Use the available signed short and stop worrying about the sign, unless you need to do comparison (<, <=, >, >=) or division (/, %, >>) operations. See this answer for how to handle signed numbers as if they were unsigned.

Solution 2 (where solution 1 doesn't apply): Use the lower 16 bits of int and remove the higher bits with & 0xffff where necessary.

你是我的挚爱i 2024-08-19 23:23:41

这是一个非常陈旧的线程,但为了之后的任何人的利益。 char 是数字类型。它支持所有数学运算符、位运算等。它是一个无符号 16 位。

我们处理由定制嵌入式硬件记录的信号,因此我们处理来自 AD 的大量无符号 16 位。多年来我们一直在各地使用字符,从未遇到过任何问题。

This is a really stale thread, but for the benefit of anyone coming after. The char is a numeric type. It supports all of the mathematical operators, bit operations, etc. It is an unsigned 16.

We process signals recorded by custom embedded hardware so we handle a lot of unsigned 16 from the A-D's. We have been using chars all over the place for years and have never had any problems.

神爱温柔 2024-08-19 23:23:41

您可以使用 char,因为它是一个无符号 16 位值(尽管从技术上讲它是一个 unicode 字符,因此将来可能会更改为 24 位值)...另一种选择是使用 int 并确保它在范围内。

不要使用 char - 使用 int :-)

这里有一个 讨论 Java 和缺乏 unsigned 的链接

You can use a char, as it is an unsigned 16 bit value (though technically it is a unicode character so could potnetially change to be a 24 bit value in the future)... the other alternative is to use an int and make sure it is within range.

Don't use a char - use an int :-)

And here is a link discussing Java and the lack of unsigned.

瘫痪情歌 2024-08-19 23:23:41

来自 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);
}

From 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);
}
柏林苍穹下 2024-08-19 23:23:41

不可能声明 unsigned Short 类型,但就我而言,我需要获取无符号数才能在 for 循环中使用它。 Short 类中有一个方法 toUnsignedInt,它返回“通过无符号转换将参数转换为 int”:

short signedValue = -4767;
System.out.println(signedValue ); // prints -4767

int unsignedValue = Short.toUnsignedInt(signedValue);
System.out.println(unsingedValue); // prints 60769

Integer 和 Integer 也存在类似的方法Long:

Integer.toUnsignedLong

Long.toUnsignedString :在这种情况下,它最终会出现在 String 中,因为没有更大的数字类型。

It is not possible to declare a type unsigned short, but in my case, I needed to get the unsigned number to use it in a for loop. There is the method toUnsignedInt in the class Short that returns "the argument converted to int by an unsigned conversion":

short signedValue = -4767;
System.out.println(signedValue ); // prints -4767

int unsignedValue = Short.toUnsignedInt(signedValue);
System.out.println(unsingedValue); // prints 60769

Similar methods exist for Integer and Long:

Integer.toUnsignedLong

Long.toUnsignedString : In this case it ends up in a String because there isn't a bigger numeric type.

〃温暖了心ぐ 2024-08-19 23:23:41

java中没有这个类型

No such type in java

风尘浪孓 2024-08-19 23:23:41

如果可以选择使用第三方库,则可以使用 jOOU (来自 jOOQ),它为 Java 中的无符号整数提供了包装类型。这与对无符号类型的原始类型(以及字节代码)支持并不完全相同,但也许它对于您的用例来说仍然足够好。

import static org.joou.Unsigned.*;

// and then...
UShort s = ushort(1);

(免责声明:我在这些库背后的公司工作)

If using a third party library is an option, there is jOOU (a spin off library from jOOQ), which offers wrapper types for unsigned integer numbers in Java. That's not exactly the same thing as having primitive type (and thus byte code) support for unsigned types, but perhaps it's still good enough for your use-case.

import static org.joou.Unsigned.*;

// and then...
UShort s = ushort(1);

(Disclaimer: I work for the company behind these libraries)

比忠 2024-08-19 23:23:41

是的,如果您想在代码中使用该值而不是位操作,则没有这样的事情。

Yep no such thing if you want to use the value in code vs. bit operations.

别挽留 2024-08-19 23:23:41

他说他想创建一个多维短数组。但没有人建议按位运算符?从我读到的内容来看,您想使用 16 位整数而不是 32 位整数来节省内存?

因此,首先,10,000 x 10,000 个短值是 1,600,000,000 位、200,000,000 字节、200,000 千字节、200 兆字节。

如果您需要 200MB 内存消耗的东西,您可能需要重新设计这个想法。我也不相信它会编译,更不用说运行了。如果有任何东西利用了称为按需加载和数据缓存的两个功能,则永远不应该初始化这样的大型数组。本质上,按需加载是指仅在需要时加载数据的想法。然后数据缓存执行相同的操作,但利用自定义框架来删除旧内存并根据需要添加新信息。要拥有良好的速度性能是很棘手的。你还可以做其他事情,但如果做得好的话,这两件事是我最喜欢的。

好吧,回到我刚才所说的按位运算符。

所以一个 32 位整数或者 Java 中的“int”。你可以存储所谓的“位”,所以假设你有 32 个布尔值,在 Java 中,所有值都占用 32 位(长整型除外),或者对于数组,它们占用 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);

所以上面所做的是 value 是 -32768 和 32767 之间的值,或者作为无符号值 0 - 65535。所以假设值等于 -1,那么作为无符号值它是 65535。这意味着位 1 到 16 被打开,但在实际执行数学计算时,请考虑范围 0 - 15。

因此我们需要激活位 17 - 32。因此我们必须从大于 15 位的值开始。所以我们从 16 位开始。因此,通过取 value2 并将其乘以 65536,这就是“<< 16”的作用。现在,假设 value2 等于 3,则将进行或运算 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 来看待它。我发布这篇文章主要是为了帮助任何可能遇到这种搜索无符号短数组甚至可能是多维数组的人。如果有任何错别字,我会尽快写下来,对此表示歉意。

He said he wanted to create a multi-dimensional short array. Yet no one suggested bitwise operators? From what I read you want to use 16 bit integers over 32 bit integers to save memory?

So firstly to begin 10,000 x 10,000 short values is 1,600,000,000 bits, 200,000,000 bytes, 200,000 kilobytes, 200 megabytes.

If you need something with 200MB of memory consumption you may want to redesign this idea. I also do not believe that will even compile let alone run. You should never initialize large arrays like that if anything utilize 2 features called On Demand Loading and Data Caching. Essentially on demand loading refers to the idea to only load data as it is needed. Then data caching does the same thing, but utilizes a custom frame work for delete old memory and adding new information as needed. This one is tricky to have GOOD speed performance. There are other things you can do, but those two are my favorite when done right.

Alright back to what I was saying about bitwise operators.

So a 32bit integer or in Java "int". You can store what are called "bits" to this so let's say you had 32 Boolean values which in Java all values take up 32 bits (except long) or for arrays they take up 8 for byte, 16 for short, and 32 for int. So unless you have arrays you don't get any memory benefits from using a byte or short. This does not mean you shouldn't use it as its a way to ensure you and others know the data range this value should have.

Now as I was saying you could effectively store 32 Booleans into a single integer by doing the following:

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;

So now a short consists of 16 bits so 16 + 16 = 32 which fits PERFECTLY within a 32bit integer. So every int value can consist of 2 short values.

int two_shorts = value | (value2 << 16);

So what the above is doing is value is something between -32768 and 32767 or as an unsigned value 0 - 65535. So let's say value equaled -1 so as an unsigned value it was 65535. This would mean bits 1 through 16 are turned on, but when actually performing the math consider the range 0 - 15.

So we need to then activate bits 17 - 32. So we must begin at something larger than 15 bits. So we begin at 16 bits. So by taking value2 and multiplying it by 65536 which is what "<< 16" does. We now would have let's say value2 equaled 3 it would be OR'd 3x65536 = 196608. So our integer value would equal 262143.

int assumed_value = 262143;

so let's say we want to retrieve the two 16bit integer values.

short value1 = (short)(assumed_value & 0xFFFF); //-1
short value2 = (short)(assumed_value >> 16); //=3

Also basically think of bitwise operators as powers of 2. That is all they really are. Never look at it terms of 0's and 1's. I mostly posted this to assist anyone who may come across this searching for unsigned short or even possibly multi-dimensional arrays. If there are any typo's I apologize quickly wrote this up.

囚我心虐我身 2024-08-19 23:23:41

不,确实没有这样的方法,java是高级语言。这就是为什么 Java 没有任何无符号数据类型。

No, really there is no such method, java is a high-level language. That's why Java doesn't have any unsigned data types.

你げ笑在眉眼 2024-08-19 23:23:41

Java 没有无符号类型。你需要它做什么?

然而,Java 确实有“字节”数据类型。

Java does not have unsigned types. What do you need it for?

Java does have the 'byte' data type, however.

时常饿 2024-08-19 23:23:41

您可以自己编写一个 ShortUnsigned 类,并为所需的运算符定义方法。您将无法重载 +- 以及它们上的其他内容,也无法与其他基元或数字对象类型进行隐式类型转换,唉。

和其他一些回答者一样,我想知道为什么您迫切需要无符号短整型,而其他数据类型无法填充。

You can code yourself up a ShortUnsigned class and define methods for those operators you want. You won't be able to overload + and - and the others on them, nor have implicit type conversion with other primitive or numeric object types, alas.

Like some of the other answerers, I wonder why you have this pressing need for unsigned short that no other data type will fill.

夜唯美灬不弃 2024-08-19 23:23:41

简单的程序来说明为什么需要无符号数:

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) ),认为没有必要,对我们的短视来说太糟糕了。当您所拥有的只是更长的数字时,移位、与、或和异或都是有限的工具。当连接到使用 16 位或更多“真实”计算机位的硬件设备时,这是一个特殊的问题。 “char”不保证有效(现在是两个字节宽),但在几种基于 gif 的东方语言(例如中文、韩语和日语)中,需要至少 3 个字节。我不知道沙盘风格语言的需求量。字节数不取决于程序员,而是取决于 JAVA 标准委员会。因此将 char 设为 16 位存在下游风险。为了安全地实现 unsigned Shorts JAVA,基于上述歧义,特殊类是最好的解决方案。该类的缺点是无法重载该特殊类的数学运算。该线程的许多贡献者准确地指出了这些问题,但我的贡献是一个工作代码示例以及我在 Linux 下使用 C++ 实现 3 字节 gif 语言的经验。

Simple program to show why unsigned numbers are needed:

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);
    }
}

results:

0xC568 0xFFFFE2B4 0xFFFFF15A 0xFFFFF8AD 0xFFFFFC56

Now for those that are not system types:

JAVA does an arithmetic shift because the operand is signed, however, there are cases where a logical shift would be appropriate but JAVA (Sun in particular), deemed it unnecessary, too bad for us on their short sightedness. Shift, And, Or, and Exclusive Or are limited tools when all you have are signed longer numbers. This is a particular problem when interfacing to hardware devices that talk "REAL" computer bits that are 16 bits or more. "char" is not guaranteed to work (it is two bytes wide now) but in several eastern gif based languages such as Chinese, Korean, and Japanese, require at least 3 bytes. I am not acquainted with the number need for sandscript style languages. The number of bytes does not depend on the programmer rather the standards committee for JAVA. So basing char as 16 bits has a downstream risk. To safely implement unsigned shorts JAVA, as special class is the best solution based on the aforementioned ambiguities. The downside of the class is the inability of overloading the mathematical operations for this special class. Many of the contributors for this thread of accurately pointed out these issues but my contribution is a working code example and my experience with 3 byte gifs languages in C++ under Linux.

西瓜 2024-08-19 23:23:41
//вот метод для получения аналога 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);
      }
    }
//вот метод для получения аналога 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);
      }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文