有符号基元中的 0 是正数还是负数(或两者兼而有之)?

Xao*_*Bao 2 java variables primitive signed zero

我正在“Code Ranch”上阅读此页面,其中讨论了变量。

它正在讨论“有符号原语”,并说 0 算作负数???

我一直认为这些情况下 0 是阳性?

所有这些整数类型都是有符号的。最左边的位表示符号(正或负),不是值的一部分。例如,对于一个字节,您无法获得整个 8 位来表示您的值。您得到 7。这​​为您提供了字节范围:(-2 到第 7 个)到(2 到第 7 个)-1。为什么最后有那个小-1?因为那里有零,而零算作负数。与其他人的工作方式相同。

http://www.javaranch.com/campfire/StoryCups.jsp

但是当看这篇文章时Why the range of bytes of bytes in Java? -128 to 127 in Java?

一条评论提到“默认情况下 0 为正”。它还谈到了“二人的赞美”,并提到最左边的位中带有“1”的任何内容都将是“负数”,而 0 则没有......

另外,如果 0 是负数 -128 到 0 就是 129 个负数,127 个正数,这没有意义......

所以我很好奇这是否是一个错误,或者 0 是否为负数,为什么?

另外,我正在阅读这篇文章原始浮点值如何为-0.0?这意味着什么?

那是在谈论值为 -0.0 的浮点数,并为其添加“0.0”以使其成为“中性/正数”0.0....

所以我很好奇浮点数中是否同时存在正零和负零,或者它是否同时存在于浮点和整数基元中???

另外,当我在谷歌上搜索这个问题的答案时,提到“零既不是正负也不是正负......”好奇这是否/何时适用于我们的语言?

谢谢

sis*_*hus 5

这是一个复杂的问题,涉及多个方面,因此我\xe2\x80\x99m 将尽力尝试将其分解。

\n\n

首先,有零的数学概念以及它是正数还是负数。不幸的是,这个问题的答案本质上是它依赖于上下文,有时在一组正数或负数中包含零是合理的。数学家认识到这种歧义,并在需要明确零是否在一组特定数字中时有一个特殊的术语 - \xe2\x80\x9cnon-negative\xe2\x80\x9d 和 \xe2\x80\x9cnon -positive\xe2\x80\x9d 都包含零。一些正数和负数的 \xe2\x80\x98common-sense\xe2\x80\x99 定义允许与零进行排它比较,这在既不是正数也不是负数的特殊情况下将零放入。其他人则具有积极或消极的包容性概念,这可以使零既是积极的又是消极的。https://math.stackexchange.com/questions/26705/is-zero-positive-or-negative

\n\n

那么这对于 Java 语言意味着什么呢?同样,需要考虑许多不同的情况 - 原始整数类型、原始浮点类型、装箱原始数据、任意精度类 BigDecimal 和 BigInteger,以及最重要的是,哪些效果是可见的?

\n\n

Java 使用2 补码系统表示原始整数类型,因此它只有一个零表示形式。从 0 没有设置符号位的意义上来说,说 0 是正数可能是合理的。然而,这确实是一个有争议的问题,因为该语言中实际上没有任何其他内容涉及零是正数还是负数,因此它实际上没有实际效果。这些类型的盒装版本具有非常相似的行为。

\n\n

2\xe2\x80\x99s 补码的含义是,任何给定范围的数字在零附近不均匀平衡。因此,如果您采用 8 位值,则可以用它表示 256 个值。其中之一是 0,这会留下 255 个非零值。然而,你把剩下的部分分开,你会发现一侧比另一侧稍大。2\xe2\x80\x99s 的补码使 -128 成为有效的负值,而 127 成为可以用 8 位表示的最大正值。int对于较大的整数类型也是如此long- 它们可以比非零正整数多表示一个非零负整数。这既不是错误也不是错误,这是一个简单的事实。

\n\n

对于浮点基元类型doublefloat,Java 使用IEEE 754来表示它们。这允许用两种不同的方式来表示 0.0,因此从技术上讲,每个零要么是 -0.0,要么是 +0.0。然而,IEEE 标准明确表示这两个值实际上无法区分 - 它们\xe2\x80\x99 相等,因此-0.0 == +0.0计算结果为 true。对于大多数数学运算,-0.0 和 +0.0 具有相同的效果。直到你尝试一些会产生 Inf 的事情。因此,除以 -0.0 将得到 -Inf,除以 +0.0 将得到 +inf。无论哪种方式,你的计算都进入了黑洞。幸运的是,所有 NaN 都是相同的,因此 -0.0 / 0.0 将以与 0.0 / 0.0 完全相同的方式得到 Nan。对于其他数学运算,-0.0 的作用一致。所以,Math.sqrt(-0.0)是 -0.0,Math.sqrt(0.0)是 0.0。Math.abs(-0.0)将返回 0.0。但 -0.0 和 0.0 之间实际上差别很小。

\n\n

重要的是,当您以格式化字符串显示数字时,符号仍然存在。如果你真的关心它,那么你可以使用 Math.abs() 将“负”零变成“正”零,但这通常不是一个值得考虑的问题。

\n\n

当涉及到浮点数的装箱类型以及与 equals()xe2x80x99 方法相关的装箱类型时,xe2x80x99 会产生奇怪的效果。原始类型的-0.0 == +0.0计算结果为true。然而,Double.valueOf(-0.0).equals(Double.valueOf(+0.0))评估结果为 false,这是有记录的,但违反直觉,因此可能会令人困惑。当与自动装箱和自动拆箱结合使用时,这可能会产生一些令人困惑的副作用 - 例如,它Double.valueOf(-0.0) == Double.valueOf(+0.0)是错误的,但却-0.0 == +0.0是正确的。同时,Double.valueOf(-0.0) == +0.0d也是如此。与 Java 一样 - 对装箱原语要有点警惕,并且始终小心混合装箱和未装箱原语。

\n\n

BigDecimal 通过稍微不同的 equals() 实现,在工作中抛出了一个进一步的麻烦。因此,BigDecimal.valueOf(-0.0).equals(BigDecimal.valueOf(0.0))评估结果为 true,但BigDecimal.valueOf(-0.0).equals(BigDecimal.ZERO)结果为 false。这是因为比例是与值一起考虑的。BigDecimal.ZERO 实际上是 0,它被视为与 0.0 不同的值,而 0.0 又与 0.00 不同 -new BigDecimal("-0.0").equals(new BigDecimal("-0.00"))计算结果为 false。

\n\n

我们可以看的另一件事是函数Math.signum(),它被定义为根据参数是负数、零还是正数返回 -1、0 或 1。java.math 包中的BigInteger和类的signum方法也是如此。BigDecimal不幸的是,该Math.signum()函数返回一个双精度值,因此 -0.0 得到 -0.0,0.0 得到 0.0,而BigDecimal.signum()返回一个 int。但符号所暗示的是,无论你如何定义零,它\xe2\x80\x99都不是真正的正数或负数。

\n