C语言 什么是 CHAR_BIT?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3200954/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is CHAR_BIT?
提问by dato datuashvili
Quoting the code for computing the integer absolute value (abs) without branching from http://graphics.stanford.edu/~seander/bithacks.html:
引用计算整数绝对值 (abs) 的代码而不从http://graphics.stanford.edu/~seander/bithacks.html分支:
int v; // we want to find the absolute value of v
unsigned int r; // the result goes here
int const mask = v >> sizeof(int) * CHAR_BIT - 1;
r = (v + mask) ^ mask;
Patented variation:
专利变体:
r = (v ^ mask) - mask;
What is CHAR_BITand how use it?
什么是CHAR_BIT以及如何使用它?
采纳答案by R.. GitHub STOP HELPING ICE
You should be aware that this code depends on the implementation-defined behavior of right bitshift on signed types. gcc promises to always give the sane behavior (sign-bit-extension) but ISO C allows the implementation to zero-fill the upper bits.
您应该知道,此代码取决于对有符号类型进行右移位的实现定义的行为。gcc 承诺始终提供合理的行为(符号位扩展),但 ISO C 允许实现对高位进行零填充。
One way around this problem:
解决此问题的一种方法:
#ifdef HAVE_SIGN_EXTENDING_BITSHIFT
int const mask = v >> sizeof(int) * CHAR_BIT - 1;
#else
int const mask = -((unsigned)v >> sizeof(int) * CHAR_BIT - 1);
#endif
Your Makefileor config.hetc. can define HAVE_SIGN_EXTENDING_BITSHIFTat build time depending on your platform.
您Makefile或其他人config.h可以HAVE_SIGN_EXTENDING_BITSHIFT根据您的平台在构建时定义。
回答by AraK
CHAR_BITis the number of bits in char. These days, almost all architectures use 8 bits per byte but it is not the case always. Some older machines used to have 7-bit byte.
CHAR_BIT是 中的位数char。如今,几乎所有架构都使用每字节 8 位,但情况并非总是如此。一些较旧的机器曾经有 7 位字节。
It can be found in <limits.h>.
它可以在<limits.h>.
回答by plugwash
Trying to answer both the explicit question (what is CHAR_BIT) and the implicit question (how does this work) in the original question.
试图回答原始问题中的显式问题(什么是 CHAR_BIT)和隐式问题(这是如何工作的)。
A char in C and C++ represents the smallest unit of memory the C program can address*
C 和 C++ 中的字符表示 C 程序可以寻址的最小内存单元*
CHAR_BIT in C and C++ represents the number of bits in a char. It must always be at least 8 due to other requirements on the char type. In practice on all modern general purpose computers it is exactly 8 but some historic or specialist systems may have higher values.
C 和 C++ 中的 CHAR_BIT 表示字符中的位数。由于对 char 类型的其他要求,它必须始终至少为 8。实际上,在所有现代通用计算机上,它正好是 8,但某些历史或专业系统可能具有更高的值。
Java has no equivilent of CHAR_BIT or sizeof, there is no need for it as all primitive types in Java are fixed size and the internal structure of objects is opaque to the programmer. If translating this code to Java you can simply replace "sizeof(int) * CHAR_BIT - 1" by the fixed value 31.
Java 没有 CHAR_BIT 或 sizeof 等价物,没有必要,因为 Java 中的所有原始类型都是固定大小的,并且对象的内部结构对程序员来说是不透明的。如果将此代码转换为 Java,您可以简单地将“sizeof(int) * CHAR_BIT - 1”替换为固定值 31。
In this particular code it is being used to calculate the number of bits in an int. Be aware that this calculation assumes that the int type doesn't contain any padding bits.
在此特定代码中,它用于计算 int 中的位数。请注意,此计算假定 int 类型不包含任何填充位。
Assuming that your compiler chooses to sign extend on bit shifts of signed numbers and assuming your system uses 2s complement representation for negative numbers this means that "MASK" will be 0 for a positive or zero value and -1 for a negative value.
假设您的编译器选择对有符号数的位移进行符号扩展,并假设您的系统对负数使用 2s 补码表示,这意味着“MASK”将是 0 表示正值或零值,-1 表示负值。
To negate a twos complement number we need to perform a bitwise not and then add one. Equivilently we can subtract one and then bitwise negate it.
要否定二进制补码数,我们需要执行按位非然后加一。同样,我们可以减去 1,然后按位取反。
Again assuming twos complement representation -1 is represented by all ones, so exclusive or with -1 is equivilent to bitwise negation.
再次假设二进制补码表示 -1 由所有 1 表示,因此异或与 -1 等效于按位否定。
So when v is zero the number is left alone, when v is one it is negated.
因此,当 v 为零时,数字保持不变,当 v 为 1 时,它被否定。
Something to be aware of is that signed overflow in C and C++ is undefined behaviour. So using this ABS implementaion on the most negative value leads to undefined behaviour. This can be fixed by adding casts such that the final line of the program is evaluated in unsigned int.
需要注意的是,C 和 C++ 中的有符号溢出是未定义的行为。因此,在最负值上使用此 ABS 实现会导致未定义的行为。这可以通过添加强制转换来解决,以便程序的最后一行以 unsigned int 计算。
* Which is usually but not nesacerally the same as the smallest unit of memory the hardware can address. An implementation can potentially combine multiple units of hardware-addressable memory into one unit of program-addressable memory or split one unit of hardware addressable memory into multiple units of program-addresable memory.
* 这通常与硬件可以寻址的最小内存单元相同,但并非完全相同。一种实现可以潜在地将多个硬件可寻址存储器单元组合为一个程序可寻址存储器单元,或者将一个硬件可寻址存储器单元拆分为多个程序可寻址存储器单元。

