【问题标题】:Casting a large number type to a smaller type将大数字类型转换为较小类型
【发布时间】:2011-10-08 19:35:00
【问题描述】:

我已经环顾四周,找不到类似的问题,如果之前有人问过,我深表歉意。

我只是在玩类型和数字,我想知道是否可以保证以下行为。 如果我将 2 个变量声明为

unsigned char BIT_8 = 0;
unsigned short int BIT_16 = 0xFF01;

然后执行以下操作(暂时忽略 C 样式转换,除非这会影响它?)

cout << "BIT_16: " << BIT_16 << "\n";
cout << "BIT_8: " << (int)BIT_8 << "\n";
BIT_8 = BIT_16;
cout << "BIT_8 after: " << (int)BIT_8 << "\n";
BIT_8 = BIT_16 >> 8;
cout << "BIT_8 after shift: " << (int)BIT_8 << "\n";

我得到了输出

BIT_16: 65281
BIT_8: 0
BIT_8 after: 1
BIT_8 after shift: 255

如果我将 16 位类型转换为 8 位类型,是否保证会丢失前导字节?还是未定义,上面的结果是运气?

【问题讨论】:

  • 小 - 针对 x86
  • 字节序在这里没有影响。
  • 字节顺序仅在考虑字节顺序时才重要,此处并非如此。
  • C 规范将“最重要”字节称为被丢弃的字节。这意味着行为是明确定义的,无论是小端还是大端。

标签: c++ types


【解决方案1】:

如果我将 16 位类型转换为 8 位类型,是否保证会丢失前导字节?

取决于您使用的是有符号类型还是无符号类型(请参阅第 4.7 节第 2 节和第 3 节):

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

如果目标类型是有符号,如果它可以在目标类型(和位域宽度)中表示,则值不变;否则,该值为实现定义

由于您使用的是无符号类型,因此行为是明确指定的。

【讨论】:

  • 在 C 中,实现定义的行为可以显式包括引发实现定义的信号,例如 SIGFPE。我不知道 C++ 是否包含类似的措辞,但无论如何,它都可以隐式包含。
猜你喜欢
  • 2020-01-13
  • 2021-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-16
  • 1970-01-01
相关资源
最近更新 更多