Java:无符号数
Java 中有没有一种方法可以像 (My)SQL 中那样使用无符号数字?
例如:我想使用一个 8 位变量 (byte
),其范围如下:0
... 256
;而不是 -128
... 127
。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
Java 中有没有一种方法可以像 (My)SQL 中那样使用无符号数字?
例如:我想使用一个 8 位变量 (byte
),其范围如下:0
... 256
;而不是 -128
... 127
。
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(7)
不,除了
char
(其值实际上为 0-65535)之外,Java 没有任何无符号基元类型。这很痛苦(特别是对于byte
),但事实就是如此。通常,您要么坚持使用相同的大小,并溢出到“高”数字的负数,要么使用更宽的类型(例如
short
表示byte
)并应对额外的情况内存要求。No, Java doesn't have any unsigned primitive types apart from
char
(which has values 0-65535, effectively). It's a pain (particularly forbyte
), but that's the way it is.Usually you either stick with the same size, and overflow into negatives for the "high" numbers, or use the wider type (e.g.
short
forbyte
) and cope with the extra memory requirements.您可以使用类来模拟无符号数。例如
You can use a class to simulate an unsigned number. For example
大多数情况下,您可以像使用无符号数字一样使用有符号数字。大多数操作保持不变,有些需要修改。请参阅这篇文章。
You can mostly use signed numbers as if they were unsigned. Most operations stay the same, some need to be modified. See this post.
在内部,您不应该使用较小的值——只需使用 int。据我了解,使用较小的单位只会减慢速度。它不会节省内存,因为 Java 在内部使用系统的字大小进行所有存储(它不会打包字)。
但是,如果您使用较小尺寸的存储单元,则必须对每个操作进行屏蔽或范围检查或其他操作。
有没有注意到 char (任何操作) char 都会产生 int ?他们只是真的不希望您使用这些其他类型。
例外是数组(我相信它们会被打包)和 I/O,您可能会发现使用较小的类型很有用……但屏蔽也可以工作。
Internally, you shouldn't be using the smaller values--just use int. As I understand it, using smaller units does nothing but slow things down. It doesn't save memory because internally Java uses the system's word size for all storage (it won't pack words).
However if you use a smaller size storage unit, it has to mask them or range check or something for every operation.
ever notice that char (any operation) char yields an int? They just really don't expect you to use these other types.
The exceptions are arrays (which I believe will get packed) and I/O where you might find using a smaller type useful... but masking will work as well.
不,你无法改变这一点。如果您需要大于 127 的值,请选择大于字节的值。
Nope, you can't change that. If you need something larger than 127 choose something larger than a byte.
如果您需要优化存储(例如大矩阵),您可以用负数编码更大的正数,以节省空间。然后,您必须在需要时移动数值才能获得实际值。例如,我只想操纵短正数。这在 Java 中是如何实现的:
因此,当短整数超出范围时,它会变为负数。然而,至少你可以将这个数字存储在 16 位中,并通过添加移位值(可以编码的不同值的数量)来恢复其正确值。该值应该以更大的类型(在我们的例子中为 int )恢复。这可能不是很方便,但我发现对于我来说确实如此。
If you need to optimize your storage (e.g. large matrix) you can u can code bigger positive numbers with negatives numbers, so to save space. Then, you have to shift the number value to get the actual value when needed. For instance, I want to manipulate short positive numbers only. Here how this is possible in Java:
So when a short integer exceeds range, it becomes negative. Yet, at least you can store this number in 16 bits, and restore its correct value by adding shift value (number of different values that can be coded). The value should be restored in a larger type (int in our case). This may not be very convenient, but I find it's so in my case.
我对 Java 和编程都很陌生。
然而,我最近遇到了同样的情况,需要无符号值。
我花了大约两周的时间来编写我想到的所有内容,但我完全是个菜鸟,所以你可以花更少的钱。
总体思路是创建接口,我将其命名为:
UnsignedNumber
并扩展 Number.class,同时实现抽象AbstractUnsigned >
类。所以,Base参数化类型代表基本类型,Shifted代表实际的Java类型。 Impl 是实现这个抽象类的快捷方式。
大部分时间消耗在 Java 8 Lambda 的样板以及内部私有类和安全过程上。重要的是当减法或负加等数学运算产生零限制时,实现无符号的行为:向后溢出有符号上限。
最后,又花了几天时间来编写工厂和实现子类的代码。
到目前为止我已经知道:
UByte 和 MUByte
UShort 和 MUshort
UInt 和 MUInt
...等等。
他们是 AbstractUnsigned 的后代:
UByte 或 MUByte 扩展
AbstractUnsigned
或AbstractUnsigned
UShort 或 MUShort 扩展
AbstractUnsigned
或AbstractUnsigned
...ETC。
总体思想是将无符号上限作为移位(强制转换)类型和负值的代码转置,因为它们不是来自零,而是来自无符号上限。
更新:
(感谢 Ajeans 友善而礼貌的指示)
这是
AbstractUnsigned 的外部可访问方法;
(或者正如之前所说的AbstractUnsigned
);现在,进行底层工作:
在上面的私有方法中,
mutable
是一个AbstractUnsigned
的私有最终布尔值
。number
是内部私有类之一,负责将Base
转换为Shifted
,反之亦然。与之前的“我去年夏天做了什么”相对应的重要内容
是两个内部对象:
caster
和shiftedConstructor
:这些是将
N
(或Base
)转换为的参数化函数Shifted
或创建新的Impl
实例(如果AbstractUnsigned<>
的当前实现实例是不可变的)。在此片段中显示了
number
对象的添加方法。这个想法是始终在内部使用 Shifted,因为不确定何时产生“原始”类型的正限制。shifted
是一个内部参数化字段,它承载整个AbstractUnsigned<>
的值。下面给出了另外两个Function>>
派生对象:前者执行两个
Shifted
值的加法。后者在零转位以下进行产卵。现在是来自
AbstractUnsigned
的工厂样板“地狱”之一的示例,专门针对之前提到的spawnBelowZero
UnaryOperator
>:如果
Shifted v
为正,则不会发生任何事情,并且会返回原始值。否则:需要计算Base
类型的上限(即Byte
),并将该值加起来为负值v
。假设,v == -8
则Math.abs(Byte.MIN_VALUE)
将生成128
和Byte.MAX_VALUE
将产生127
,它给出255
+ 1 以获得原始上限,该上限被符号位切断,正如我所得到的那样,如此理想256
就在这个地方。但第一个负值实际上是256
,这就是为什么再次+1
或总共+2
的原因。最后,255 + 2 + v
(即-8
)给出255 + 2 + (-8)
和249
或者以更直观的方式:
最后确定所有这些:这绝对不会减轻您的工作或节省内存字节,但在需要时您会获得非常理想的行为。您几乎可以将这种行为与任何其他
Number.class
子类一起使用。AbstractUnsigned
是Number.class
的子类,它本身提供了所有方便的方法和常量与其他“原生”
Number.class
子类类似,包括MIN_VALUE
和MAX_VALUE
等等,例如,我为可变代码编写了便捷方法名为makeDivisibileBy(Number n)
的子类执行最简单的value - (value % n)
操作。我最初的努力是为了证明即使像我这样的菜鸟也可以编写代码。当我编写该类代码时,我最初的努力是获得方便的多功能工具以供持续使用。
I'm quite new to Java and to programming.
Yet, I encountered the same situation recently the need of unsigned values.
It took me around two weeks to code everything I had in mind, but I'm a total noob, so you could spend much less.
The general idea is to create interface, I have named it:
UnsignedNumber<Base, Shifted>
and to extend Number.class whilst implementing an abstractAbstractUnsigned<Base, Shifted, Impl extends AbstractUnsigned<Base, Shifted, Impl>>
class.So, Base parameterized type represents the base type, Shifted represents actual Java type. Impl is a shortcut for Implementation of this abstract class.
Most of the time consumed boilerplate of Java 8 Lambdas and internal private classes and safety procedures. The important thing was to achieve the behavior of unsigned when mathematical operation like subtraction or negative addition spawns the zero limit: to overflow the upper signed limit backwards.
Finally, it took another couple of days to code factories and implementation sub classes.
So far I have know:
UByte and MUByte
UShort and MUShort
UInt and MUInt
... Etc.
They are descendants of AbstractUnsigned:
UByte or MUByte extend
AbstractUnsigned<Byte, Short, UByte>
orAbstractUnsigned<Byte, Short, MUByte>
UShort or MUShort extend
AbstractUnsigned<Short, Integer, UShort>
orAbstractUnsigned<Short, Integer, MUShort>
...etc.
The general idea is to take unsigned upper limit as shifted (casted) type and code transposition of negative values as they were to come not from zero, but the unsigned upper limit.
UPDATE:
(Thanks to Ajeans kind and polite directions)
This is an externally accessible method of
AbstractUnsigned<N, Shifted, Impl>
(or as it was said beforeAbstractUnsigned<Base, Shifted, Impl>
);Now, to the under-the-hood work:
In the above private method
mutable
is aprivate final boolean
of anAbstractUnsigned
.number
is one of the internal private classes which takes care of transformingBase
toShifted
and vice versa.What matters in correspondence with previous 'what I did last summer part'
is two internal objects:
caster
andshiftedConstructor
:These are the parameterized functions to cast
N
(orBase
) toShifted
or to create a newImpl
instance if current implementation instance of theAbstractUnsigned<>
is immutable.In this fragment is shown the adding method of the
number
object. The idea was to always useShifted
internally, because it is uncertain when the positive limits of 'original' type will be spawned.shifted
is an internal parameterized field which bears the value of the wholeAbstractUnsigned<>
. The other twoFunction<>
derivative objects are given below:The former performs addition of two
Shifted
values. And the latter performs spawning below zero transposition.And now an example from one of the factory boilerplates 'hell' for
AbstractUnsigned<Byte, Short>
specifically for the mentioned beforespawnBelowZero
UnaryOperator<Shifted>
:if
Shifted v
is positive nothing really happens and the original value is being returned. Otherwise: there's a need to calculate the upper limit of theBase
type which isByte
and add up to that value negativev
. If, let's say,v == -8
thenMath.abs(Byte.MIN_VALUE)
will produce128
andByte.MAX_VALUE
will produce127
which gives255
+ 1 to get the original upper limit which was cut of by the sign bit, as I got that, and the so desirable256
is in the place. But the very first negative value is actually that256
that's why+1
again or+2
in total. Finally,255 + 2 + v
which is-8
gives255 + 2 + (-8)
and249
Or in a more visual way:
And to finalize all that: this definitely does not ease your work or saves memory bytes, but you have a pretty much desirable behaviour when it is needed. And you can use that behaviour pretty much with any other
Number.class
subclasses.AbstractUnsigned
being subclass ofNumber.class
itself provides all the convenience methods and constantssimilar to other 'native'
Number.class
subclasses, includingMIN_VALUE
andMAX_VALUE
and a lot more, for example, I coded convenience method for mutable subclasses calledmakeDivisibileBy(Number n)
which performs the simplest operation ofvalue - (value % n)
.My initial endeavour here was to show that even a noob, such as I am, can code it. My initial endeavour when I was coding that class was to get conveniently versatile tool for constant using.