在有符号的原语是0正或负(或两者)?

时间:2015-10-15 22:05:25

标签: java variables primitive zero signed

我正在阅读#34; Code Ranch"谈论变量。

正在讨论"签名的原语,"并且说0被视为负数???

在这些情况下,我一直认为0是积极的吗?

  

所有这些整数类型都是SIGNED。最左边的位表示符号(正或负),不是值的一部分。因此,例如,对于一个字节,您不能获得整个8位来表示您的值。你得到7.这给你一个字节范围:   (-2到7)到(2到7)-1。为什么那个小-1到底?因为零在那里,零计为负数。与其他人的工作方式相同。

     

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

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

一条评论提及" 0默认为正。"它还讨论了"双方的赞美,"用一个' 1'提及任何东西。在最左边的位是"否定,"哪个没有... ....

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

所以我很好奇这是一个错误,还是0是否定的,为什么?

另外,我正在阅读这个帖子How can a primitive float value be -0.0? What does that mean?

那是在谈论一个价值为-0.0的浮点数,并添加一个' 0.0'它是为了使它成为一个中性/积极的" 0.0 ....

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

此外,当我谷歌搜索答案时,提及"零既不是正面否定,也不是正面负面......"好奇如果/这何时适用于我们的语言?

由于

1 个答案:

答案 0 :(得分:1)

这是一个复杂的问题,有很多方面,所以我会尝试尽可能地将其分解。

首先,存在零的数学概念以及它是正面的还是负面的。不幸的是,对此的答案基本上是它依赖于上下文,有时在一组正数或负数中包含零是合理的。数学家认识到模糊性并且有一个特殊的术语,当他们需要清楚零是否在一组特定的数字中时 - “非负”和“非正”都包括零。正面和负面的一些“常识”定义允许与零进行排他性比较,在特殊情况下将零置于正面或负面。其他人有一个包容性的正面或负面概念,可以使正面和负面都为零。 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会让你的Nan与0.0 / 0.0完全相同。对于其他数学运算,-0.0始终如一。因此,Math.sqrt(-0.0)为-0.0,Math.sqrt(0.0)为0.0。 Math.abs(-0.0)将返回0.0。但是-0.0和0.0之间的差别确实很小。

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

当出现浮点数的盒装类型以及与'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)为false,但-0.0 == +0.0为真。同时,Double.valueOf(-0.0) == +0.0d是真的。与Java一样 - 对盒装基元有点警惕,并且总是要小心混合盒装和未装箱的基元。

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.00不同 - new BigDecimal("-0.0").equals(new BigDecimal("-0.00"))计算结果为false。

我们可以看到的另一件事是Math.signum()函数,它定义为返回-1,0或1,具体取决于参数是负数,零还是正数。对于java.math包中的BigIntegerBigDecimal类的signum方法也是如此。不幸的是Math.signum()函数返回一个double,所以你得到-0.0表示-0.0而0.0表示0.0,而BigDecimal.signum()返回一个int。但是,值得表明的是,无论你定义为零,它都不是正面的或负面的。