java - 带符号原始中的0是正数还是负数(或两者都是)?

标签 java variables primitive zero signed

我在有关变量的“代码牧场”上阅读此页面。

当时正在讨论“有符号原语”,并说0被视为负数???

我一直以为0在这些情况下为正?


  所有这些整数类型都是SIGNED。最左边的位代表符号(正或负),不是值的一部分。因此,例如对于一个字节,您不会得到全部8位来表示您的值。您得到7。这为您提供了一个字节范围:
  (-2至7th)至(2至7th)-1。为什么最后那小-1?因为零在那里,零算作负数。与其他人的工作方式相同。
  
  http://www.javaranch.com/campfire/StoryCups.jsp


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

一条评论提到“默认情况下,0为正”。它还讨论了“ Two's Compliment”,并提到了最左边带有“ 1”的任何内容都是“负数”,而0则没有。

另外,如果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....。

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

另外,当我在谷歌搜索时,提到“零既不是正负的也不是正负的……。”是否好奇/是否适用于我们的语言?

谢谢

最佳答案

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

首先,存在零的数学概念,无论它是正数还是负数。不幸的是,对此的答案基本上是与上下文相关的,有时在一组正数或负数中包含零是合理的。数学家认识到模棱两可,并有一个特殊的术语表示何时需要明确在特定的一组数字中是否为零-“非负数”和“非正数”都包括零。对正负的一些“常识”定义允许与零进行排他比较,这在既不是正也不是负的特殊情况下将零置为。其他人具有积极或消极的包容性概念,这可以使积极和消极的人都为零。 https://math.stackexchange.com/questions/26705/is-zero-positive-or-negative

那么这对Java语言意味着什么呢?同样,有许多不同的情况需要考虑-基本整数类型,基本浮点类型,装箱基本元素,任意精度类BigDecimal和BigInteger,最重要的是,什么效果是可见的?

Java使用2s complement系统表示原始整数类型,因此它只有一个表示零的形式。从某种意义上说,0没有设置符号位,可以合理地说0为正。但是,这实际上是一个有争议的问题,因为该语言中实际上没有任何其他内容与零是正数还是负数有关,因此它实际上没有任何实际作用。这些类型的盒装版本具有几乎相同的行为。

不过2的补码的意思是,任何给定范围的数字在0附近均不均衡。因此,如果采用8位值,则可以用它表示256个值。其中之一是0,这将为您提供255个非零值。但是,将剩余部分分开,则一侧比另一侧稍大。 2的补码使-128为有效负值,使127为最大正值(可以用8位表示)。对于较大的整数类型intlong,也是如此-它们可以表示比非零正整数多一个非零负整数。这既不是错误,也不是错误,这是一个简单的事实。

对于浮点基元类型doublefloat,Java使用IEEE 754表示它们。这允许使用两种不同的方式表示0.0,因此从技术上讲,每个零都是-0.0或+0.0。但是,IEEE标准明确规定,这两个值实际上是无法区分的-它们是相等的,因此-0.0 == +0.0的计算结果为true。对于大多数数学运算,-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为true。同时,Double.valueOf(-0.0) == +0.0d为true。与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()函数返回一个双精度值,因此对于-0.0,您将获得-0.0;对于0.0而言,您将获得0.0;而BigDecimal.signum()返回一个int。但是signum所暗示的是,无论您定义的是什么零,它并不是正数或负数。

关于java - 带符号原始中的0是正数还是负数(或两者都是)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33159303/

相关文章:

封装所有原语的 Java 对象——在 OutputStreams 中很有用

java - 有没有一种准确的方法来确定两个 Java 进程之间的 nanoTime 差异?

java - 我在 Java 中看不到默认值,例如 "char"

python - 如何在 tkinter python 中的两个函数之间传递变量?

variables - 地形变量中的 map 内的 map

用于基元的 Java vector 或 ArrayList

javascript - 为什么闭包编译器偏爱 !0 而不是 true?

java - 错误: Could not find or load main class Maven Spring Boot Application - Executable JAR

java - 从 SOAP wsdl 生成客户端 jar

java - 无需两次检查值即可表达此 Java 条件的最简洁方法