【问题标题】:Why "int" variable doesn't print negative zero?为什么“int”变量不打印负零?
【发布时间】:2018-01-29 02:42:35
【问题描述】:

在下面的程序中,float 变量打印负零。

//g++  5.4.0

#include <iostream>

int main()
{
    float val = 0;
    val = -val;

    std::cout<<val<<std::endl;
}

输出:

-0

但是,在下面的代码中

//g++  5.4.0

#include <iostream>

int main()
{
    int val = 0;
    val = -val;

    std::cout<<val<<std::endl;
}

输出:

0

打印正零。

为什么int 变量不打印负零?

【问题讨论】:

  • 因为您的系统上的整数表示没有负零?谁说应该有负零?
  • 整数在通常的表示中没有负零,它们也没有太多用处。
  • @StoryTeller 为什么不发布答案?评论不是为了答案等等......
  • @juanchopanza - 这是一个答案吗?我不知道OP的平台可以回答。
  • 为什么投反对票?这很清楚,有示例代码和记录的输出。而且不是那么明显。

标签: c++ types floating-point int


【解决方案1】:

在计算机中处理负整数的通常方法是使用two's complement 对其进行编码。并且使用二进制补码不可能有负零。

【讨论】:

  • 值得一提的是,C++ 标准不强制要求二进制补码,因此可能存在负零整数的实现。
  • 特别想到符号和幅度表示,尽管我不知道任何现实世界的非古老平台将它用于整数。一般来说,我很难在野外找到一个非 2 的补码有符号整数实现。
【解决方案2】:

浮点数由符号、指数和分数组成。如果符号为1,则为负数;如果符号为0,则为正数。

正如您在下面的示例中看到的那样


虽然计算机中的负数通常由twos complement 处理,因此如果数字具有最高有效位1,则必须将其从二进制补码转换为实际值。例如在 8 位上。

+---+---+---+---+---+---+---+---+
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+---+---+---+---+---+---+---+---+

第一步:反转位

+---+---+---+---+---+---+---+---+
| 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
+---+---+---+---+---+---+---+---+

第二步:加1

+---+---+---+---+---+---+---+---+
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+---+---+---+---+---+---+---+---+

第三步:换号

所以结果是-128

换句话说,您不能将-0 放在二进制补码中。

【讨论】:

    【解决方案3】:

    在数学整数集中没有负零这样的东西。

    一些很少使用的整数机器表示确实有不止一种零表示,在这种情况下,其中一种可能习惯上称为“负零”。然而,C++ 语言不允许通过普通整数 API 向程序员公开此类表示。因此,即使您的计算机有这样的表示,它可能没有,它也不会打印为 -0。

    另一方面,浮点数最常见的表示形式是有符号零,C++ 标准特别允许实现向程序员公开符号。

    【讨论】:

    【解决方案4】:

    那是因为 int 和 float 的二进制表示不同。

    int 由 32 位组成,最高有效位是符号位。当符号位为真时,int 的最高可能值为11111111111111111111111111111111,即-1。所以负零是不可能的。

    另一方面,有符号浮点数分为三部分 - 符号、指数和尾数(分数)。因此,当小数部分等于零时,整数等于零。当您切换符号位(本质上是 val = -val 所做的)时,该数字在技术上仍然为零,但是当您告诉 cout 将该数字转换为您可以读取的十进制数字字符串时,它会看到符号位设置为 1 并且只是在它的开头抛出减号。我希望这是有道理的

    【讨论】: