在 Signed Primitives 中是 0 正数还是负数(或两者)?

In Signed Primitives is 0 Positive or Negative (or both)?

我正在阅读 "Code Ranch" 上讨论变量的页面。

讨论"signed primitives,"说0算负数???

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

All of these integer types are SIGNED. The leftmost bit represents the sign (positive or negative) and is NOT part of the value. So with a byte, for instance, you don't get the whole 8 bits to represent your value. You get 7. This gives you a range, for bytes, of : (-2 to the 7th) through (2 to the 7th) -1. Why that little -1 on the end? Because zero is in there, and zero counts as negative. Works the same way with the others.

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

但是看这个的时候 post Why is the range of bytes -128 to 127 in Java?

一条评论提到“默认情况下 0 是肯定的”。它还讨论了 "Two's Compliment," 并提到最左边带有“1”的任何东西都是 "negative," 而 0 没有那个....

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

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

此外,我正在阅读此主题How can a primitive float value be -0.0? What does that mean?

那是在谈论一个值为 -0.0 的浮点数,并向其添加“0.0”以使其成为 "neutral/positive" 0.0....

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

此外,当我在谷歌上搜索这个问题的答案时,提到了"Zero being neither positive-negative/ being both positive-negative...."好奇if/when这适用于我们的语言吗?

谢谢

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

首先,有零的数学概念,是正数还是负数。不幸的是,从本质上讲,答案是它取决于上下文,有时在一组正数或负数中包含零是合理的。数学家认识到这种歧义,并有一个特殊的术语来表示何时需要弄清楚零是否在一组特定的数字中——“非负”和“非正”都包括零。一些关于正负的“常识”定义允许与零进行排他性比较,这在既不是正也不是负的特殊情况下将零置入。其他人有积极或消极的包容性概念,这可以使零既积极又消极。 https://math.stackexchange.com/questions/26705/is-zero-positive-or-negative

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

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

虽然 2 的补码确实意味着任何给定范围内的数字都在零附近不平衡。所以,如果你取一个 8 位的值,你可以用它表示 256 个值。其中之一是 0,它为您留下 255 个非零值。但是,您将剩余部分分开,您会得到一侧比另一侧稍大。 2 的补码使 -128 成为有效的负值,而 127 成为可以用 8 位表示的最大正值。对于较大的整数类型 intlong 也是如此 - 它们可以表示比非零正整数多一个非零负整数。这既不是错误也不是错误,这是一个简单的事实。

对于浮点基本类型doublefloat,Java用IEEE 754来表示。这允许用两种不同的方式表示 0.0,因此从技术上讲,每个零要么是 -0.0 要么是 +0.0。然而,IEEE 标准清楚地表明,这两个值实际上是无法区分的——它们相等,因此 -0.0 == +0.0 的计算结果为真。对于大多数数学运算,-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) 将 return 0.0。但是 -0.0 和 0.0 之间的差别真的很小。

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

浮点数的盒装类型以及与“equals()”方法相关的类型会产生奇怪的效果。原始类型 -0.0 == +0.0 评估为 true。然而 Double.valueOf(-0.0).equals(Double.valueOf(+0.0)) 的计算结果为 false,这是 documented 但违反直觉,因此可能会造成混淆。当与自动装箱和自动拆箱结合使用时,这可能会产生一些令人困惑的副作用——例如Double.valueOf(-0.0) == Double.valueOf(+0.0) 为假,但 -0.0 == +0.0 为真。同时,Double.valueOf(-0.0) == +0.0d 为真。一如既往地使用 Java - 对盒装图元保持警惕,并始终小心混合盒装和未装箱图元。

BigDecimal 对 equals() 的实现略有不同,这进一步阻碍了工作。因此,BigDecimal.valueOf(-0.0).equals(BigDecimal.valueOf(0.0)) 计算结果为真,但 BigDecimal.valueOf(-0.0).equals(BigDecimal.ZERO) 为假。这是因为比例与值一起考虑。 BigDecimal.ZERO 实际上是 0,它被视为与 0.0 不同的值,而 0.0 又与 0.00 不同 - new BigDecimal("-0.0").equals(new BigDecimal("-0.00")) 计算为 false。

我们可以看的另一件事是 Math.signum() 函数,它被定义为 returning -1、0 或 1,具体取决于参数是负数、零还是正数。 java.math包中BigIntegerBigDecimal类上的signum方法也是如此。不幸的是,Math.signum() 函数 return 是一个双精度数,所以你得到 -0.0 表示 -0.0,0.0 表示 0.0,而 BigDecimal.signum() return 是一个整数。但是 signum 的意思是,无论你如何定义零,它都不是真正的正数或负数。