dsi*_*cha 367 java unsigned integer language-design
为什么Java不包含对无符号整数的支持?
在我看来,这是一个奇怪的遗漏,因为它们允许人们编写不太可能在意外的大输入上产生溢出的代码.
此外,使用无符号整数可以是一种自我文档形式,因为它们表明unsigned int意图保留的值绝不应该是负数.
最后,在某些情况下,无符号整数对于某些操作(例如除法)可能更有效.
包含这些内容的不利之处是什么?
Uri*_*Uri 190
这是来自Gosling和其他人对简单性的采访:
Gosling:对于我作为一名语言设计师而言,我现在并不像以前那样真实地认为,"简单"真正意义上的结果是我可以期待J. Random Developer在他的脑海中保留这个规范.这个定义说,例如,Java不是 - 实际上很多这些语言都有很多极端情况,这些都是没人真正理解的.测试任何C开发人员关于unsigned的问题,很快你就会发现几乎没有C开发人员真正理解无符号算法是什么,无符号算术是什么.这样的事情让C变得复杂.我认为Java的语言部分非常简单.你必须查找的库.
Nei*_*fey 50
在线之间阅读,我认为逻辑是这样的:
大多数情况下,我认为这是一个合理的决定.可能,我会:
尽管如此,通过一些克服,对高达32位的无符号值的操作也不会太糟糕,并且大多数人不需要无符号的64位除法或比较.
Jyr*_*117 18
这是一个较老的问题,拍了很简单地提到了char,我只是想我应该为其他人展望这个问题.让我们仔细看看Java原始类型:
byte - 8位有符号整数
short - 16位有符号整数
int - 32位有符号整数
long - 64位有符号整数
char - 16位字符(无符号整数)
虽然char不支持unsigned算术,但它基本上可以视为unsigned整数.您必须显式地将算术运算转换回来char,但它确实为您提供了指定unsigned数字的方法.
char a = 0;
char b = 6;
a += 1;
a = (char) (a * b);
a = (char) (a + b);
a = (char) (a - 16);
b = (char) (b % 3);
b = (char) (b / a);
//a = -1; // Generates complier error, must be cast to char
System.out.println(a); // Prints ?
System.out.println((int) a); // Prints 65532
System.out.println((short) a); // Prints -4
short c = -4;
System.out.println((int) c); // Prints -4, notice the difference with char
a *= 2;
a -= 6;
a /= 3;
a %= 7;
a++;
a--;
Run Code Online (Sandbox Code Playgroud)
是的,没有对无符号整数的直接支持(显然,如果有直接支持,我不需要将大部分操作转换回char).但是,肯定存在无符号原始数据类型.我也希望看到一个无符号字节,但我想加倍内存成本,而使用char是一个可行的选择.
对于JDK8,有一些新的API Long,Integer它们在处理long和int值时提供辅助方法作为无符号值.
compareUnsigneddivideUnsignedparseUnsignedIntparseUnsignedLongremainderUnsignedtoUnsignedLongtoUnsignedString此外,Guava提供了许多辅助方法来为整数类型执行类似的操作,这有助于缩小由于缺少对unsigned整数的本机支持而留下的空白.
小智 15
Java确实有无符号类型,或者至少有一个:char是unsigned short.因此无论戈斯林抛出什么借口,实际上只是他的无知为什么没有其他无符号类型.
短型:短裤一直用于多媒体.原因是您可以在一个32位无符号长度中拟合2个样本并对多个操作进行向量化.与8位数据和无符号字节相同.您可以在寄存器中放入4或8个样本进行矢量化.
Bom*_*mbe 14
只要签名和未签名的整数混合在表达式中,事情就会开始变得混乱,您可能会丢失信息.将Java限制为签名的内容只能真正解决问题.我很高兴我不必担心整个签名/未签名的业务,尽管我有时会错过一个字节中的第8位.
aka*_*tos 12
http://skeletoncoder.blogspot.com/2006/09/java-tutorials-why-no-unsigned.html
这个人说因为C标准定义了涉及无符号和有符号整数的操作被视为无符号.这可能会导致负的有符号整数转换为大的unsigned int,从而可能导致错误.
sta*_*lue 11
我认为Java很好,添加unsigned会使它复杂化而没有太大的收益.即使使用简化的整数模型,大多数Java程序员也不知道基本数字类型的行为 - 只需阅读Java Puzzlers一书,看看你可能会有什么误解.
至于实用建议:
如果您的值有些任意大小且不适合int,请使用long.如果它们不适合long使用BigInteger.
当您需要节省空间时,仅将较小的类型用于数组.
如果您需要64/32/16/8位,请使用long/ int/ short/ byte并停止担心符号位,除了除法,比较,右移和转换.
又见这个回答有关"移植一个随机数发生器从C到Java的".
我知道这篇文章太旧了; 但是为了您的兴趣,在Java 8及更高版本中,您可以使用int数据类型来表示无符号的32位整数,其最小值为0,最大值为2 32 -1.使用Integer类中使用int的数据类型为无符号整数和静态方法一样compareUnsigned(),divideUnsigned()等已经加入到Integer类,以支持算术运算的无符号整数.
小智 5
我听说过它们将被包含在原始 Java 版本附近。Oak 是 Java 的前身,在一些规范文档中提到了使用的值。不幸的是,这些从未进入 Java 语言。至于任何人都能够弄清楚他们只是没有得到实施,可能是由于时间限制。
我曾经和 C++ 标准委员会的某个人一起参加过 C++ 课程,他暗示 Java 做出了正确的决定来避免使用无符号整数,因为 (1) 大多数使用无符号整数的程序可以很好地处理有符号整数,这在人们的思维方式,以及 (2) 使用无符号整数会导致许多易于创建但难以调试的问题,例如整数算术溢出和在有符号和无符号类型之间转换时丢失重要位。如果您错误地使用有符号整数从 0 中减去 1,则通常会更快地导致您的程序崩溃,并且比使用 2^32 - 1 更容易找到错误,并且编译器和静态分析工具以及运行时检查必须假设您知道自己在做什么,因为您选择使用无符号算术。还,
很久以前,当内存有限并且处理器不能一次自动在 64 位上运行时,每一位都算得上更多,因此有符号与无符号字节或短字节实际上更重要,而且显然是正确的设计决策。今天,在几乎所有常规编程情况下,仅使用有符号 int 就足够了,如果您的程序确实需要使用大于 2^31 - 1 的值,那么无论如何您通常只想要一个 long。一旦您进入了使用 long 的领域,就更难想出一个原因,为什么您真的无法使用 2^63 - 1 个正整数。每当我们使用 128 位处理器时,问题就更小了。
| 归档时间: |
|
| 查看次数: |
110368 次 |
| 最近记录: |