为什么Java不支持无符号整数?
为什么 Java 不支持无符号整数?
在我看来,这是一个奇怪的遗漏,因为它们允许人们编写不太可能在意外大的输入上产生溢出的代码。
此外,使用无符号整数可以是自文档的一种形式,因为它们表明无符号 int 想要保存的值永远不应该是负数。
最后,在某些情况下,无符号整数对于某些运算(例如除法)可能更有效。
包括这些有什么缺点?
Why doesn't Java include support for unsigned integers?
It seems to me to be an odd omission, given that they allow one to write code that is less likely to produce overflows on unexpectedly large input.
Furthermore, using unsigned integers can be a form of self-documentation, since they indicate that the value which the unsigned int was intended to hold is never supposed to be negative.
Lastly, in some cases, unsigned integers can be more efficient for certain operations, such as division.
What's the downside to including these?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(17)
这是来自对 Gosling 和其他人的采访,关于简单性:
This is from an interview with Gosling and others, about simplicity:
从字里行间,我认为逻辑是这样的:
大多数情况下,我认为这是一个合理的决定。 可能,我会:
不过,尽管有一点拼凑,对高达 32 位的无符号值进行操作并不算太糟糕,而且大多数人不需要无符号64 位除法或比较。
Reading between the lines, I think the logic was something like this:
Mostly, I'd say it was a reasonable decision. Possibly, I would have:
Still, with a bit of kludging, operations on unsigned values up to 32 bits aren't tooo bad, and most people don't need unsigned 64-bit division or comparison.
这是一个较老的问题,帕特确实简短地提到了 char,我只是想我应该为其他将来会看到这个问题的人扩展这个问题。 让我们仔细看看 Java 基本类型:
byte
- 8 位有符号整数short
- 16 位有符号整数int
- 32-位有符号整数long
- 64 位有符号整数char
- 16 位字符(无符号整数)尽管
char
不支持unsigned
算术,它本质上可以被视为一个无符号
整数。 您必须将算术运算显式转换回char
,但它确实为您提供了一种指定无符号
数字的方法。是的,没有对无符号整数的直接支持(显然,如果有直接支持,我不必将大部分操作转换回 char)。 然而,确实存在无符号原始数据类型。 我也希望看到一个无符号字节,但我想将内存成本加倍并使用 char 是一个可行的选择。
编辑
JDK8 有新的 API
Long< /code>
和
Integer< /code>
在将
long
和int
值视为无符号值时提供辅助方法。compareUnsigned
divideUnsigned
parseUnsignedInt
parseUnsignedLong
remainderUnsigned
toUnsignedLong
toUnsignedString
此外,Guava 提供了许多辅助方法来执行类似的操作整数类型有助于缩小由于缺乏对无符号整数的本机支持而留下的空白。
This is an older question and pat did briefly mention char, I just thought I should expand upon this for others who will look at this down the road. Let's take a closer look at the Java primitive types:
byte
- 8-bit signed integershort
- 16-bit signed integerint
- 32-bit signed integerlong
- 64-bit signed integerchar
- 16-bit character (unsigned integer)Although
char
does not supportunsigned
arithmetic, it essentially can be treated as anunsigned
integer. You would have to explicitly cast arithmetic operations back intochar
, but it does provide you with a way to specifyunsigned
numbers.Yes, there isn't direct support for unsigned integers (obviously, I wouldn't have to cast most of my operations back into char if there was direct support). However, there certainly exists an unsigned primitive data type. I would liked to have seen an unsigned byte as well, but I guess doubling the memory cost and instead use char is a viable option.
Edit
With JDK8 there are new APIs for
Long
andInteger
which provide helper methods when treatinglong
andint
values as unsigned values.compareUnsigned
divideUnsigned
parseUnsignedInt
parseUnsignedLong
remainderUnsigned
toUnsignedLong
toUnsignedString
Additionally, Guava provides a number of helper methods to do similar things for at the integer types which helps close the gap left by the lack of native support for
unsigned
integers.Java 确实有无符号类型,或者至少有一种: char 是无符号短整型。 因此,无论高斯林提出什么借口,这实际上只是他对为什么没有其他未签名类型的无知。
还有短片类型:短片一直用于多媒体。 原因是您可以将 2 个样本放入一个 32 位无符号长整型中,并对许多操作进行向量化。 8 位数据和无符号字节也是如此。 您可以将 4 或 8 个样本放入寄存器中以进行矢量化。
Java does have unsigned types, or at least one: char is an unsigned short. So whatever excuse Gosling throws up it's really just his ignorance why there are no other unsigned types.
Also Short types: shorts are used all the time for multimedia. The reason is you can fit 2 samples in a single 32-bit unsigned long and vectorize many operations. Same thing with 8-bit data and unsigned byte. You can fit 4 or 8 samples in a register for vectorizing.
一旦有符号和无符号整数混合在表达式中,事情就会开始变得混乱,您可能会丢失信息。 将 Java 限制为有符号整数只会真正解决问题。 我很高兴我不必担心整个签名/未签名的业务,尽管有时我确实会错过一个字节中的第 8 位。
As soon as signed and unsigned ints are mixed in an expression things start to get messy and you probably will lose information. Restricting Java to signed ints only really clears things up. I’m glad I don’t have to worry about the whole signed/unsigned business, though I sometimes do miss the 8th bit in a byte.
http://skleaf.blogspot.com/2006/09 /java-tutorials-why-no-unsigned.html
这家伙说是因为 C 标准定义了涉及无符号和有符号整数的操作被视为无符号。 这可能会导致负有符号整数滚动到一个大的无符号整数,从而可能导致错误。
http://skeletoncoder.blogspot.com/2006/09/java-tutorials-why-no-unsigned.html
This guy says because the C standard defines operations involving unsigned and signed ints to be treated as unsigned. This could cause negative signed integers to roll around into a large unsigned int, potentially causing bugs.
我认为 Java 本身就很好,添加 unsigned 会使它变得复杂而没有太多好处。
即使使用简化的整数模型,大多数 Java 程序员也不知道基本数字类型的行为方式 - 只需阅读这本书 Java Puzzlers 看看您可能存在哪些误解。
至于实用建议:
如果您的值有点任意大小并且不适合
int
,请使用long
。如果它们不适合
long
,请使用BigInteger
。仅当您需要节省空间时才对数组使用较小的类型。
如果您正好需要 64/32/16/8 位,请使用
long
/int
/short
/byte 并且不再担心符号位,除了除法、比较、右移和转换。
另请参阅这个关于“移植随机数”的答案从 C 到 Java 的生成器”。
I think Java is fine as it is, adding unsigned would complicate it without much gain.
Even with the simplified integer model, most Java programmers don't know how the basic numeric types behave - just read the book Java Puzzlers to see what misconceptions you might hold.
As for practical advice:
If your values are somewhat arbitrary size and don't fit into
int
, uselong
.If they don't fit into
long
useBigInteger
.Use the smaller types only for arrays when you need to save space.
If you need exactly 64/32/16/8 bits, use
long
/int
/short
/byte
and stop worrying about the sign bit, except for division, comparison, right shift, and casting.See also this answer about "porting a random number generator from C to Java".
我知道这篇文章太旧了; 不过,出于您的兴趣,在 Java 8 及更高版本中,您可以使用
int
数据类型来表示无符号 32 位整数,其最小值为 0,最大值为 2 32-1。 使用Integer
类将int
数据类型用作无符号整数以及静态方法,例如compareUnsigned()
、divideUnsigned()Integer
类中添加了 code> 等,以支持无符号整数的算术运算。I know this post is too old; however for your interest, in Java 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. Use theInteger
class to useint
data type as an unsigned integer and static methods likecompareUnsigned()
,divideUnsigned()
etc. have been added to theInteger
class to support the arithmetic operations for unsigned integers.我听说过这样的故事:它们将包含在原始 Java 版本附近。 Oak 是 Java 的前身,在一些规范文档中提到了无符号值。 不幸的是,这些从未进入 Java 语言。 据任何人所知,他们只是没有得到实施,可能是由于时间限制。
I've heard stories that they were to be included close to the orignal Java release. Oak was the precursor to Java, and in some spec documents there was mention of usigned values. Unfortunately these never made it into the Java language. As far as anyone has been able to figure out they just didn't get implemented, likely due to a time constraint.
对于JDK8,它确实对它们有一些支持。
尽管 Gosling 担心,但我们可能仍会看到 Java 中对无符号类型的完全支持。
With JDK8 it does have some support for them.
We may yet see full support of unsigned types in Java despite Gosling's concerns.
我曾经和 C++ 标准委员会的某个人一起上过 C++ 课程,他暗示 Java 做出了避免使用无符号整数的正确决定,因为 (1) 大多数使用无符号整数的程序都可以与有符号整数一起使用,而且这在就人们的思维方式而言,(2)使用无符号整数会导致许多易于创建但难以调试的问题,例如整数算术溢出以及在有符号和无符号类型之间转换时丢失重要位。 如果你错误地使用有符号整数从 0 中减去 1,它通常会更快地导致你的程序崩溃,并且比它回绕到 2^32 - 1 更容易找到错误,并且编译器、静态分析工具和运行时检查必须假设您知道自己在做什么,因为您选择使用无符号算术。 此外,像 -1 这样的负数通常可以表示有用的东西,例如被忽略/默认/未设置的字段,而如果您使用无符号,则必须保留一个特殊值,例如 2^32 - 1 或类似的值。
很久以前,当内存有限并且处理器不能同时自动在 64 位上运行时,每个位都更重要,因此有符号字节或无符号字节或短路实际上更重要,并且显然是正确的设计决策。 如今,在几乎所有常规编程情况下,仅使用有符号 int 就足够了,如果您的程序确实需要使用大于 2^31 - 1 的值,那么您通常只需要 long 值。 一旦您开始使用长整型,就更难找出为什么不能使用 2^63 - 1 正整数的原因了。 每当我们使用 128 位处理器时,这个问题就更小了。
I once took a C++ course with someone on the C++ standards committee who implied that Java made the right decision to avoid having unsigned integers because (1) most programs that use unsigned integers can do just as well with signed integers and this is more natural in terms of how people think, and (2) using unsigned integers results in lots easy to create but difficult to debug issues such as integer arithmetic overflow and losing significant bits when converting between signed and unsigned types. If you mistakenly subtract 1 from 0 using signed integers it often more quickly causes your program to crash and makes it easier to find the bug than if it wraps around to 2^32 - 1, and compilers and static analysis tools and runtime checks have to assume you know what you're doing since you chose to use unsigned arithmetic. Also, negative numbers like -1 can often represent something useful, like a field being ignored/defaulted/unset while if you were using unsigned you'd have to reserve a special value like 2^32 - 1 or something similar.
Long ago, when memory was limited and processors did not automatically operate on 64 bits at once, every bit counted a lot more, so having signed vs unsigned bytes or shorts actually mattered a lot more often and was obviously the right design decision. Today just using a signed int is more than sufficient in almost all regular programming cases, and if your program really needs to use values bigger than 2^31 - 1, you often just want a long anyway. Once you're into the territory of using longs, it's even harder to come up with a reason why you really can't get by with 2^63 - 1 positive integers. Whenever we go to 128 bit processors it'll be even less of an issue.
Java 出于务实的原因放弃了“C”规范中的一些精华,但随着开发人员的需求(关闭等),它们正在慢慢回归。
我提到第一个是因为它与本次讨论相关; 指针值遵守无符号整数算术。 并且,与此线程主题相关的是,在 Java 的有符号世界中维护无符号语义的困难。
我猜想如果有人让 Dennis Ritchie 的另一个自我为 Gosling 的设计团队提供建议,他们会建议给 Signed 一个“无穷大零”,这样所有地址偏移请求都会首先添加其代数环大小以避免负值。
这样,向数组抛出的任何偏移量都不会生成 SEGFAULT。 例如,在一个封装类中,我将其称为需要无符号行为的双精度型 RingArray - 在“自旋转循环”上下文中:
上述 RingArray 永远不会从负索引中“获取”,即使恶意请求者试图这样做。 请记住,还有许多要求先前(负)索引值的合法请求。
注意:外部 %modulus 取消引用合法请求,而内部 %modulus 掩盖了比 -modulus 更负面的负数中的公然恶意。 如果这出现在 Java +..+9 || 中 8+..+ 规范,那么问题将真正成为“无法“自我旋转”故障的程序员”。
我相信所谓的Java unsigned int“缺陷”可以用上面的一句话来弥补。
PS:只是为了给上面的 RingArray 内务处理提供上下文,这里有一个候选“set”操作来匹配上面的“get”元素操作:
There's a few gems in the 'C' spec that Java dropped for pragmatic reasons but which are slowly creeping back with developer demand (closures, etc).
I mention a first one because it's related to this discussion; the adherence of pointer values to unsigned integer arithmetic. And, in relation to this thread topic, the difficulty of maintaining Unsigned semantics in the Signed world of Java.
I would guess if one were to get a Dennis Ritchie alter ego to advise Gosling's design team it would have suggested giving Signed's a "zero at infinity", so that all address offset requests would first add their ALGEBRAIC RING SIZE to obviate negative values.
That way, any offset thrown at the array can never generate a SEGFAULT. For example in an encapsulated class which I call RingArray of doubles that needs unsigned behaviour - in "self rotating loop" context:
The above RingArray would never ever 'get' from a negative index, even if a malicious requestor tried to. Remember, there are also many legitimate requests for asking for prior (negative) index values.
NB: The outer %modulus de-references legitimate requests whereas the inner %modulus masks out blatant malice from negatives more negative than -modulus. If this were to ever appear in a Java +..+9 || 8+..+ spec, then the problem would genuinely become a 'programmer who cannot "self rotate" FAULT'.
I'm sure the so-called Java unsigned int 'deficiency' can be made up for with the above one-liner.
PS: Just to give context to above RingArray housekeeping, here's a candidate 'set' operation to match the above 'get' element operation:
因为
unsigned
类型是纯粹的邪恶。事实上,在 C 中
unsigned - int
会产生unsigned
,这一事实更加邪恶。这是不止一次让我烦恼的问题的快照:
你注意到这个错误了吗? 我承认我只是在使用调试器后才看到它。
由于
n
为无符号类型size_t
,因此整个表达式n - (rays.size() - 1) / 2
的计算结果为unsigned
。 该表达式旨在成为中间第 n 条射线的有符号位置:左侧中间的第 1 条射线的位置为 -1,右边第一个的位置为 +1,等等。在获取绝对值并乘以 delta 角度后,我将得到第 n 条射线与中间射线之间的角度一。不幸的是,对我来说,上面的表达式包含邪恶的无符号,并且不是计算为 -1,而是计算为 2^32-1。 随后转换为
double
解决了该错误。在由于滥用无符号算术而导致一两个错误之后,人们必须开始怀疑是否值得为此付出额外的努力。 我正在尽可能避免在算术中使用无符号类型,尽管仍然将其用于非算术运算(例如二进制掩码)。
Because
unsigned
type is pure evil.The fact that in C
unsigned - int
producesunsigned
is even more evil.Here is a snapshot of the problem that burned me more than once:
Have you noticed the bug yet? I confess I only saw it after stepping in with the debugger.
Because
n
is of unsigned typesize_t
the entire expressionn - (rays.size() - 1) / 2
evaluates asunsigned
. That expression is intended to be a signed position of then
th ray from the middle one: the 1st ray from the middle one on the left side would have position -1, the 1st one on the right would have position +1, etc. After taking abs value and multiplying by thedelta
angle I would get the angle betweenn
th ray and the middle one.Unfortunately for me the above expression contained the evil unsigned and instead of evaluating to, say, -1, it evaluated to 2^32-1. The subsequent conversion to
double
sealed the bug.After a bug or two caused by misuse of
unsigned
arithmetic one has to start wondering whether the extra bit one gets is worth the extra trouble. I am trying, as much as feasible, to avoid any use ofunsigned
types in arithmetic, although still use it for non-arithmetic operations such as binary masks.你的问题是“为什么Java不支持无符号整数”?
我对你问题的回答是,Java 想要所有的原始类型:byte、char、short、int 和 long 应被视为 byte、word、dword 和 qword分别,就像在汇编中一样,Java 运算符是对除 char 之外的所有基本类型的有符号操作,但仅对 char 进行操作仅无符号 16 位。
因此,静态方法应该是 32 位和 64 位的无符号操作也。
您需要最终类,可以调用其静态方法来执行无符号操作。
您可以创建这个最终类,将其命名为您想要的任何名称并实现它的静态方法。
如果您不知道如何实现静态方法,那么这个链接可能会帮助您。
在我看来,Java 与 C++ 完全不相似,如果它既不支持无符号类型也不支持运算符重载,所以我认为 Java 应该被视为与 C++ 和 C 完全不同的语言。
顺便说一句,它的语言名称也完全不同。
所以我不建议在 Java 中键入类似于 C 的代码,我根本不建议键入类似于 C++ 的代码,因为那样在 Java 中你将无法执行接下来在 C++ 中要做的事情,也就是说,代码根本不会继续像 C++ 那样,对我来说,这样编码、改变中间的样式是不好的。
我建议也为签名操作编写和使用静态方法,这样您就不会在代码中看到签名和未签名操作的运算符和静态方法的混合,除非您只需要代码中的签名操作,并且可以仅使用运算符。
另外,我建议避免使用 short、int 和 long 原始类型,并使用 word、dword分别是 和 qword,并且您将调用无符号操作和/或有符号操作的静态方法,而不是使用运算符。
如果您打算仅执行签名操作并仅在代码中使用运算符,那么可以使用这些基本类型 short、int 和 long< /强>。
实际上,word、dword 和 qword 并不存在于该语言中,但是您可以为它们创建新类每个以及每个的实现都应该非常简单:
类 word 仅保存原始类型 short,类 dword 保存原始类型 <仅strong>int,类qword仅包含原始类型long。 现在,所有无符号和有符号方法都是静态或非静态的,您可以在每个类中实现,即通过在 word 类上给出含义名称来实现所有无符号和有符号的 16 位操作,所有通过在 dword 类上给出含义名称来进行无符号和有符号的 32 位操作,以及通过在 qword 类上给出含义名称来进行的所有 64 位操作(无论是无符号还是有符号)。
如果您不喜欢为每个方法提供太多不同的名称,您始终可以在 Java 中使用重载,很高兴看到 Java 也没有删除它!
如果您想要 8 位有符号运算的方法而不是运算符,以及根本没有运算符的 8 位无符号运算的方法,那么您可以创建 Byte 类(请注意,第一个字母“B”是大写,所以这不是原始类型byte)并实现此类中的方法。
关于按值传递和按引用传递:
如果我没记错的话,就像在 C# 中一样,原始对象自然是按值传递,但类对象自然是按引用传递,所以这意味着 Byte、word、dword 和 qword 默认情况下将通过引用传递,而不是通过值传递。 我希望 Java 能像 C# 一样拥有 struct 对象,
因此所有Byte、word、dword和qword都可以实现为struct而不是 class,因此默认情况下它们是按值传递的,而不是按引用传递的,就像 C# 中的任何结构体对象一样,像原始类型一样,默认情况下是按值传递而不是按引用传递,但是因为 Java 比 C# 更糟糕,我们必须处理这个问题,所以只有类和接口,它们默认通过引用传递,而不是通过值传递。 因此,如果您想按值而不是按引用传递 Byte、word、dword 和 qword 对象,例如对于 Java 和 C# 中的任何其他类对象,您只需使用复制构造函数即可。
这是我能想到的唯一解决方案。 我只是希望我可以将原始类型typedef为word、dword和qword,但是Java既不支持typedef也不支持using,不像C#支持using,这相当于C的typedef。
关于输出:
对于相同的位序列,您可以通过多种方式打印它们:作为二进制、作为十进制(如 C printf 中 %u 的含义)、作为八进制(如 % 的含义) o 在 C printf 中)、十六进制(如 C printf 中 %x 的含义)和整数(如 C printf 中 %d 的含义)。
请注意,C printf 不知道作为参数传递给函数的变量的类型,因此 printf 仅从传递给函数第一个参数的 char* 对象知道每个变量的类型。
因此,在每个类中:Byte、word、dword和qword,您可以实现 print 方法并获取printf 的功能,即使类的原始类型是有符号的,您仍然可以通过遵循一些涉及逻辑和移位操作的算法来将其打印为无符号,以获得要打印到输出的数字。
不幸的是,我给您的链接没有显示如何实现这些打印方法,但我相信您可以通过谷歌搜索实现这些打印方法所需的算法。
这就是我能回答你的问题和建议你的全部。
Your question is "Why doesn't Java support unsigned ints"?
And my answer to your question is that Java wants that all of it's primitive types: byte, char, short, int and long should be treated as byte, word, dword and qword respectively, exactly like in assembly, and the Java operators are signed operations on all of it's primitive types except for char, but only on char they are unsigned 16 bit only.
So static methods suppose to be the unsigned operations also for both 32 and 64 bit.
You need final class, whose static methods can be called for the unsigned operations.
You can create this final class, call it whatever name you want and implement it's static methods.
If you have no idea about how to implement the static methods then this link may help you.
In my opinion, Java is not similar to C++ at all, if it neither support unsigned types nor operator overloading, so I think that Java should be treated as completely different language from both C++ and from C.
It is also completely different in the name of the languages by the way.
So I don't recommend in Java to type code similar to C and I don't recommend to type code similar to C++ at all, because then in Java you won't be able to do what you want to do next in C++, i.e. the code won't continue to be C++ like at all and for me this is bad to code like that, to change the style in the middle.
I recommend to write and use static methods also for the signed operations, so you don't see in the code mixture of operators and static methods for both signed and unsigned operations, unless you need only signed operations in the code, and it's okay to use the operators only.
Also I recommend to avoid using short, int and long primitive types, and use word, dword and qword respectively instead, and you are about call the static methods for unsigned operations and/or signed operations instead of using operators.
If you are about to do signed operations only and use the operators only in the code, then this is okay to use these primitive types short, int and long.
Actually word, dword and qword don't exist in the language, but you can create new class for each and the implementation of each should be very easy:
The class word holds the primitive type short only, the class dword holds the primitive type int only and the class qword holds the primitive type long only. Now all the unsigned and the signed methods as static or not as your choice, you can implement in each class, i.e. all the 16 bit operations both unsigned and signed by giving meaning names on the word class, all the 32 bit operations both unsigned and signed by giving meaning names on the dword class and all the 64 bit operations both unsigned and signed by giving meaning names on the qword class.
If you don't like giving too many different names for each method, you can always use overloading in Java, good to read that Java didn't remove that too!
If you want methods rather than operators for 8 bit signed operations and methods for 8 bit unsigned operations that have no operators at all, then you can create the Byte class (note that the first letter 'B' is capital, so this is not the primitive type byte) and implement the methods in this class.
About passing by value and passing by reference:
If I am not wrong, like in C#, primitive objects are passed by value naturally, but class objects are passed by reference naturally, so that means that objects of type Byte, word, dword and qword will be passed by reference and not by value by default. I wish Java had struct objects as C# has,
so all Byte, word, dword and qword could be implemented to be struct instead of class, so by default they were passed by value and not by reference by default, like any struct object in C#, like the primitive types, are passed by value and not by reference by default, but because that Java is worse than C# and we have to deal with that, then there is only classes and interfaces, that are passed by reference and not by value by default. So if you want to pass Byte, word, dword and qword objects by value and not by reference, like any other class object in Java and also in C#, you will have to simply use the copy constructor and that's it.
That's the only solution that I can think about. I just wish that I could just typedef the primitive types to word, dword and qword, but Java neither support typedef nor using at all, unlike C# that supports using, which is equivalent to the C's typedef.
About output:
For the same sequence of bits, you can print them in many ways: As binary, as decimal (like the meaning of %u in C printf), as octal (like the meaning of %o in C printf), as hexadecimal (like the meaning of %x in C printf) and as integer (like the meaning of the %d in C printf).
Note that C printf doesn't know the type of the variables being passed as parameters to the function, so printf knows the type of each variable only from the char* object passed to the first parameter of the function.
So in each of the classes: Byte, word, dword and qword, you can implement print method and get the functionality of printf, even though the primitive type of the class is signed, you still can print it as unsigned by following some algorithm involving logical and shift operations to get the digits to print to the output.
Unfortunately the link I gave you doesn't show how to implement these print methods, but I am sure you can google for the algorithms you need to implement these print methods.
That's all I can answer your question and suggest you.
我可以向你保证,Java 中确实没有必要使用无符号数。
以C为例。 让我们写一些类似的内容:
你能猜出打印的是什么吗?
不存在真正的正整数这样的东西。 无符号整数只是一个 n 字节(取决于 C 中的体系结构)值,不分配 MSB 作为符号。 它不会检查分配或读取的数字的实际符号: https://www.gnu.org/s/libc/manual/html_node/Integers.html
I can assure you there is really no necessity for unsigned numbers in Java.
Take C for example. Let's write something like:
Can you guess what's printed?
There's no such thing as a true positive integer. An unsigned integer is just an n-byte(depends on architecture in C) value that doesn't allocate the MSB for sign. It doesn't check for the actual sign of the number assigned or read: https://www.gnu.org/s/libc/manual/html_node/Integers.html
我能想到一个不幸的副作用。 在java嵌入式数据库中,32位id字段可以拥有的id数量是2^31,而不是2^32(~20亿,而不是~40亿)。
I can think of one unfortunate side-effect. In java embedded databases, the number of ids you can have with a 32bit id field is 2^31, not 2^32 (~2billion, not ~4billion).
恕我直言,原因是他们太懒了,无法实施/纠正该错误。
暗示 C/C++ 程序员不理解无符号、结构、联合、位标志......简直是荒谬的。
要么你正在与一个即将开始用 C 语言编程的 basic/bash/java 程序员交谈,但对这种语言没有任何真正的了解,或者你只是在凭自己的想法说话。 ;)
当你每天处理文件或硬件的格式时,你开始质疑,他们到底在想什么。
这里的一个很好的例子是尝试使用无符号字节作为自旋转循环。
对于那些不明白最后一句话的人来说,你到底如何称自己为程序员。
直流
The reason IMHO is because they are/were too lazy to implement/correct that mistake.
Suggesting that C/C++ programmers does not understand unsigned, structure, union, bit flag... Is just preposterous.
Ether you were talking with a basic/bash/java programmer on the verge of beginning programming a la C, without any real knowledge this language or you are just talking out of your own mind. ;)
when you deal every day on format either from file or hardware you begin to question, what in the hell they were thinking.
A good example here would be trying to use an unsigned byte as a self rotating loop.
For those of you who do not understand the last sentence, how on earth you call yourself a programmer.
DC