【问题标题】:Is there difference between static_cast<unsigned>(signed) vs std::bit_cast<unsigned>(signed)?static_cast<unsigned>(signed) 与 std::bit_cast<unsigned>(signed) 之间有区别吗?
【发布时间】:2020-04-08 16:44:09
【问题描述】:

再次,关于 C++ 和有符号 -> 无符号(相同大小)转换/转换。

C++ 标准 4.7/2 规定:

如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模 2n,其中 n 是用于表示无符号类型的位数)。 [注意:在二进制补码表示中,这种转换是概念性的,位模式没有变化(如果没有截断)。]

好的,在二进制补码表示中static_caststd::bit_cast 产生相同的位模式。

static_cast&lt;unsigned&gt;(signed) 是否有任何理由更改一个补码或有符号幅度表示中的位模式?

由于“模 2^n ...”,static_cast&lt;unsigned&gt;(signed) 可能总是以位模式产生二进制补码表示(与 unsigned x = -1 总是产生 111..1 位模式相同)?

【问题讨论】:

  • bit_cast 仅在 C++20 中可用。而且,在 C++20 中,唯一允许的整数表示是二进制补码。我不明白你的问题“static_cast(signed) 有什么理由改变一个补码或有符号幅度表示中的位模式吗?”。您是在问,为什么标准要求模 2^n 行为?因为,在模 2^n 中,非二进制补码的位模式可以改变。我认为强制模 2^n 行为是有意义的,因为它将在平台之间保持一致。
  • @geza 是的,bit_cast 是 c++20 功能,但假设它之前可用。问题是: static_cast(signed) 在一个补码或有符号幅度的情况下如何改变位模式,为什么?
  • 嗯,这很简单。假设数字-1。在一个的补码中,它具有1111 1110 的表示。如果将其转换为无符号,根据取模规则,数值应变为 255。但 255 的表示形式为 1111 1111。所以表示已经改变了。
  • @geza 谢谢!这是否正确: static_cast(signed) 为任何有符号数生成二进制补码位模式,除了负零(对于非二进制补码表示)?
  • 是的,我认为这是真的。

标签: c++


【解决方案1】:

使用一个补码,您会遇到偏移量为 -1 的问题:

在一个常数(-1)内,个数的补码表现得像 二进制加法的原始数字的负数。然而,不同于 二进制补码,这些数字没有得到广泛使用,因为 的问题,例如 -1 的偏移量,否定零会导致 明显的负零位模式,算术不太简单 借贷等。

例如,用static_cast 转换one's complement 中的“-0”(与8 位中的无符号255 具有相同的位模式),在转换为无符号时应导致“0”跟随在题。这需要对位进行更改。

【讨论】:

  • 如果 static_cast 在一个补码表示中从有符号 -0 和 +0 变为无符号将产生相同的位模式(比如零位),它是否违反“与源整数一致”的要求(是否正确将 'congruent' 解释为 'bijection' 或至少在这种情况下是 'surjection')?
猜你喜欢
  • 1970-01-01
  • 2017-06-20
  • 2013-08-26
  • 2014-08-03
  • 2011-07-02
  • 2017-03-27
  • 2012-01-13
  • 1970-01-01
  • 2012-09-27
相关资源
最近更新 更多