为什么布尔值的大小是 1 个字节而不是 1 位?

发布于 2024-10-10 12:50:18 字数 125 浏览 9 评论 0原文

在 C++ 中,

  • 为什么布尔值的大小是 1 个字节而不是 1 位?
  • 为什么没有像 4 位或 2 位整数这样的类型?

在为 CPU 编写模拟器时,我遗漏了上述内容

In C++,

  • Why is a boolean 1 byte and not 1 bit of size?
  • Why aren't there types like a 4-bit or 2-bit integers?

I'm missing out the above things when writing an emulator for a CPU

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

扛起拖把扫天下 2024-10-17 12:50:18

因为CPU不能寻址任何小于字节的东西。

Because the CPU can't address anything smaller than a byte.

阿楠 2024-10-17 12:50:18

来自维基百科

从历史上看,一个字节是
用于编码单个字符的位
计算机中的文本,它是
因此基本可寻址
许多计算机中的元素
架构。


因此,字节是基本可寻址单元,低于该单位的计算机体系结构无法寻址。而且由于(可能)不存在支持 4 位字节的计算机,因此您没有 4 位 bool 等。

但是,如果您可以设计这样的一个可以将 4 位寻址作为基本可寻址单元的体系结构,那么您将仅在该计算机上拥有大小为 4 位的 bool

From Wikipedia:

Historically, a byte was the number of
bits used to encode a single character
of text in a computer and it is
for this reason the basic addressable
element
in many computer
architectures.

So byte is the basic addressable unit, below which computer architecture cannot address. And since there doesn't (probably) exist computers which support 4-bit byte, you don't have 4-bit bool etc.

However, if you can design such an architecture which can address 4-bit as basic addressable unit, then you will have bool of size 4-bit then, on that computer only!

难忘№最初的完美 2024-10-17 12:50:18

以前,我不得不在暴风雪中步行去学校,双向都是上坡,午餐就是我们在学校后面的树林里找到并徒手杀死的任何动物,计算机的可用内存比计算机要少得多。今天。我使用的第一台计算机有 6K RAM。不是 6 MB,不是 6 GB,是 6 KB。在那种环境下,将尽可能多的布尔值打包到一个 int 中是很有意义的,因此我们会定期使用操作将它们取出并放入。

今天,人们会嘲笑你只有 1 GB内存,而你唯一能找到小于 200 GB 的硬盘的地方是在古董店,不值得费力打包。

Back in the old days when I had to walk to school in a raging blizzard, uphill both ways, and lunch was whatever animal we could track down in the woods behind the school and kill with our bare hands, computers had much less memory available than today. The first computer I ever used had 6K of RAM. Not 6 megabytes, not 6 gigabytes, 6 kilobytes. In that environment, it made a lot of sense to pack as many booleans into an int as you could, and so we would regularly use operations to take them out and put them in.

Today, when people will mock you for having only 1 GB of RAM, and the only place you could find a hard drive with less than 200 GB is at an antique shop, it's just not worth the trouble to pack bits.

纵情客 2024-10-17 12:50:18

最简单的答案是;这是因为CPU以字节而不是位来寻址内存,并且按位运算非常慢。

但是,可以在 C++ 中使用位大小分配。有针对位向量的 std::vector 专门化,以及采用位大小条目的结构。

The easiest answer is; it's because the CPU addresses memory in bytes and not in bits, and bitwise operations are very slow.

However it's possible to use bit-size allocation in C++. There's std::vector specialization for bit vectors, and also structs taking bit sized entries.

豆芽 2024-10-17 12:50:18

因为字节是语言中最小的可寻址单元。

但是如果你有一堆,你可以让 bool 取 1 位
例如。在一个结构体中,像这样:

struct A
{
  bool a:1, b:1, c:1, d:1, e:1;
};

Because a byte is the smallest addressible unit in the language.

But you can make bool take 1 bit for example if you have a bunch of them
eg. in a struct, like this:

struct A
{
  bool a:1, b:1, c:1, d:1, e:1;
};
风和你 2024-10-17 12:50:18

您可以使用位字段来获取较小大小的整数。

struct X
{
    int   val:4;   // 4 bit int.
};

尽管它通常用于将结构映射到精确的硬件预期位模式:

// 1 byte value (on a system where 8 bits is a byte)
struct SomThing   
{
    int   p1:4;   // 4 bit field
    int   p2:3;   // 3 bit field
    int   p3:1;   // 1 bit
};

You can use bit fields to get integers of sub size.

struct X
{
    int   val:4;   // 4 bit int.
};

Though it is usually used to map structures to exact hardware expected bit patterns:

// 1 byte value (on a system where 8 bits is a byte)
struct SomThing   
{
    int   p1:4;   // 4 bit field
    int   p2:3;   // 3 bit field
    int   p3:1;   // 1 bit
};
猫卆 2024-10-17 12:50:18

您可以有 1 位布尔值以及 4 位和 2 位整数。但这会产生一个奇怪的指令集,而不会提高性能,因为这是一种不自然的看待架构的方式。实际上,“浪费”字节的更好部分而不是尝试回收未使用的数据是有意义的。

根据我的经验,唯一需要将多个布尔值打包到一个字节中的应用程序是 Sql Server。

You could have 1-bit bools and 4 and 2-bit ints. But that would make for a weird instruction set for no performance gain because it's an unnatural way to look at the architecture. It actually makes sense to "waste" a better part of a byte rather than trying to reclaim that unused data.

The only app that bothers to pack several bools into a single byte, in my experience, is Sql Server.

幽蝶幻影 2024-10-17 12:50:18

bool 可以是一个字节——CPU 的最小可寻址大小,也可以更大。出于性能目的,将 bool 的大小设置为 int 的情况并不罕见。如果出于特定目的(例如硬件模拟),您需要 N 位类型,您可以找到一个库(例如 GBL 库具有 BitSet 类)。如果您关心 bool 的大小(您可能有一个大容器),那么您可以自己打包位,或者使用 std::vector 即可为您提供(请小心后者,因为它不满足容器要求)。

bool can be one byte -- the smallest addressable size of CPU, or can be bigger. It's not unusual to have bool to be the size of int for performance purposes. If for specific purposes (say hardware simulation) you need a type with N bits, you can find a library for that (e.g. GBL library has BitSet<N> class). If you are concerned with size of bool (you probably have a big container,) then you can pack bits yourself, or use std::vector<bool> that will do it for you (be careful with the latter, as it doesn't satisfy container requirments).

四叶草在未来唯美盛开 2024-10-17 12:50:18

考虑一下如何在模拟器级别实现这一点......

bool a[10] = {false};

bool &rbool = a[3];
bool *pbool = a + 3;

assert(pbool == &rbool);
rbool = true;
assert(*pbool);
*pbool = false;
assert(!rbool);

Think about how you would implement this at your emulator level...

bool a[10] = {false};

bool &rbool = a[3];
bool *pbool = a + 3;

assert(pbool == &rbool);
rbool = true;
assert(*pbool);
*pbool = false;
assert(!rbool);
如此安好 2024-10-17 12:50:18

因为一般情况下,CPU分配内存都是以1字节为基本单位,尽管有些CPU如MIPS使用4字节字。

然而,vector 以一种特殊的方式处理 boolvector 为每个 bool 分配一位。

Because in general, CPU allocates memory with 1 byte as the basic unit, although some CPU like MIPS use a 4-byte word.

However vector deals bool in a special fashion, with vector<bool> one bit for each bool is allocated.

谁的新欢旧爱 2024-10-17 12:50:18

字节是计算机数字数据存储的较小单位。在计算机中,RAM 有数百万字节,其中任何一个字节都有一个地址。如果计算机的每一位都有一个地址,那么计算机可以管理的 RAM 比它能管理的 RAM 少 8 倍。

更多信息:维基百科

The byte is the smaller unit of digital data storage of a computer. In a computer the RAM has millions of bytes and anyone of them has an address. If it would have an address for every bit a computer could manage 8 time less RAM that what it can.

More info: Wikipedia

掩耳倾听 2024-10-17 12:50:18

即使最小可能大小为 1 字节,您也可以在 1 字节上拥有 8 位布尔信息:

http:// /en.wikipedia.org/wiki/Bit_array

例如,Julia 语言有 BitArray,我阅读了有关 C++ 实现的信息。

Even when the minimum size possible is 1 Byte, you can have 8 bits of boolean information on 1 Byte:

http://en.wikipedia.org/wiki/Bit_array

Julia language has BitArray for example, and I read about C++ implementations.

三人与歌 2024-10-17 12:50:18

位运算并不“慢”。

和/或运算往往很快。

问题是对齐以及解决它的简单问题。

作为部分正确回答的答案,CPU 通常与读取字节对齐,RAM/内存也以相同的方式设计。

因此,必须明确排序数据压缩以使用更少的内存空间。

正如一个答案所建议的,您可以在结构中为每个值订购特定数量的位。但是,如果 CPU/内存未对齐,之后会做什么呢?这将导致内存不对齐,如果您想在一个值中使用一半大小的位,而不是仅+1或+2或+4,则不会有+1.5,所以它必须填充或恢复剩余的部分space 为空白,然后简单地读取下一个对齐的空间,该空间至少对齐 1,通常默认对齐 4(32 位)或 8(64 位)。然后,CPU 通常会获取包含标志的字节值或 int 值,然后检查或设置所需的标志。因此,您仍然必须将内存定义为 int、short、byte 或适当的大小,但是在访问和设置该值时,您可以显式压缩数据并将这些标志存储在该值中以节省空间;但许多人不知道它是如何工作的,或者只要有开/关值或标记当前值就跳过该步骤,尽管节省发送/接收内存中的空间在移动和其他受限环境中非常有用。在将 int 拆分为字节的情况下,它没有什么价值,因为您可以单独定义字节(例如 int 4Bytes;vs byte Byte1;byte Byte2;byte Byte3;byte Byte4;)在这种情况下,使用 int 是多余的;然而,在像Java这样更容易的虚拟环境中,他们可能将大多数类型定义为int(数字、布尔值等),因此在这种情况下,您可以利用int将其划分并使用字节/位来实现超高效必须发送较少整数数据的应用程序(按 4 对齐)。然而,由于管理位可以说是多余的,因此它是按位运算更优越但并不总是需要的众多优化之一。很多时候,人们只是将布尔值存储为整数,从而利用高内存限制,从而浪费“许多数量级”500%-1000% 左右的内存空间。它仍然很容易有它的用途,如果您在其他优化中使用它,那么在移动和其他只有字节或几 kb 数据流入的数据流中,如果总体上您优化了所有要加载的内容,那么它会产生影响在这种情况下,它会加载或加载得很快,因此减少发送的字节数最终会让您受益匪浅;即使您可以超额发送大量不需要在日常互联网连接或应用程序中发送的数据。这绝对是你在为移动用户设计应用程序时应该做的事情,甚至是当今大型企业应用程序失败的事情;使用过多的空间和负载限制,可能会减少一半或更少。不执行任何操作和堆积未知的软件包/插件(在加载之前至少需要数百 KB 或 1MB)与专为速度而设计(例如需要 1KB 或仅几KB)之间的区别将使其加载和运行速度更快,因为即使对您来说加载浪费的 MB 或数千 KB 的不需要的数据很快,您也会遇到那些有数据限制的用户和人员。

Bitwise operations are not 'slow'.

And/Or operations tend to be fast.

The problem is alignment and the simple problem of solving it.

CPUs as the answers partially-answered correctly are generally aligned to read bytes and RAM/memory is designed in the same way.

So data compression to use less memory space would have to be explicitly ordered.

As one answer suggested, you could order a specific number of bits per value in a struct. However what does the CPU/memory do afterward if it's not aligned? That would result in unaligned memory where instead of just +1 or +2, or +4, there's not +1.5 if you wanted to use half the size in bits in one value, etc. so it must anyway fill in or revert the remaining space as blank, then simply read the next aligned space, which are aligned by 1 at minimum and usually by default aligned by 4(32bit) or 8(64bit) overall. The CPU will generally then grab the byte value or the int value that contains your flags and then you check or set the needed ones. So you must still define memory as int, short, byte, or the proper sizes, but then when accessing and setting the value you can explicitly compress the data and store those flags in that value to save space; but many people are unaware of how it works, or skip the step whenever they have on/off values or flag present values, even though saving space in sent/recv memory is quite useful in mobile and other constrained enviornments. In the case of splitting an int into bytes it has little value, as you can just define the bytes individually (e.g. int 4Bytes; vs byte Byte1;byte Byte2; byte Byte3; byte Byte4;) in that case it is redundant to use int; however in virtual environments that are easier like Java, they might define most types as int (numbers, boolean, etc.) so thus in that case, you could take advantage of an int dividing it up and using bytes/bits for an ultra efficient app that has to send less integers of data (aligned by 4). As it could be said redundant to manage bits, however, it is one of many optimizations where bitwise operations are superior but not always needed; many times people take advantage of high memory constraints by just storing booleans as integers and wasting 'many magnitudes' 500%-1000% or so of memory space anyway. It still easily has its uses, if you use this among other optimizations, then on the go and other data streams that only have bytes or few kb of data flowing in, it makes the difference if overall you optimized everything to load on whether or not it will load,or load fast, at all in such cases, so reducing bytes sent could ultimately benefit you alot; even if you could get away with oversending tons of data not required to be sent in an every day internet connection or app. It is definitely something you should do when designing an app for mobile users and even something big time corporation apps fail at nowadays; using too much space and loading constraints that could be half or lower. The difference between not doing anything and piling on unknown packages/plugins that require at minumim many hundred KB or 1MB before it loads, vs one designed for speed that requires say 1KB or only fewKB, is going to make it load and act faster, as you will experience those users and people who have data constraints even if for you loading wasteful MB or thousand KB of unneeded data is fast.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文