位掩码与位域 [英] Bitmask vs bitfields

查看:80
本文介绍了位掩码与位域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




这个问题似乎经常出现,但是我没有管理

来找到与我的案例相关的答案。


我经常使用二进制标志,并且我总是使用bitmask

技术,即使用#defined或const int powers of two,和$ / b $ b使用以下原语:

/ *声明和标志的初始化* / int flags = 0;

/ *设置标志* / flags | = FLAG_1;

/ * resseting flag * / flags& = ~FLAG_2;

/ *条件设置或重置* / if(条件)标志| = FLAG_3 ;

else flags& = ~FLAG_3;

/ *测试标志* / if((flags& FLAG_4)||!(flags& FLAG_5)){ ......}

/ *标志集的副本* / other_flags =标志;


这些是我用过的唯一操作,它们只是内部的

表示。当我存储或加载或交换数据时,我使用了一种人类可信的文本格式,它基本上归结为使用上述原语设置或测试

标志。 />

我最近遇到了bitfield。概念,所以alernate解决方案

将是:

/ *声明和旗帜的初始化* /

struct {

unsigned flag1:1;

unsigned flag2:1;

unsigned flag3:1;

unsigned flag4:1;

unsigned flag5:1;

}标志;

/ *设置标志* / flags.flag1 = 1;

/ *重置标志* / flags.flag2 = 0;

/ *条件设置或重置* / flags.flag3 =(条件);

/ *测试标志* / if( flags.flag4 ||!flags.flag5){...}

/ *复制标志集* / other_flags = flags;


我的第一个问题是,最后一行是否正确?结构分配

对我来说是一个新概念,我对它不熟悉。


这些代码是否可移植?我在使用位域时已经阅读了相当多的便携性

警告,但考虑到我使用的有限的

操作(特别是

位域永远不会进入accoutn),我看不出任何问题。


这两种方法之间是否存在效率差异?当然,

它取决于平台和编译器,但可能有一个规则

的拇指。我已经读过,bitfield的效率通常不高,

但是当打开优化的编译器时,我看不到

会产生与使用位掩码不同的代码方法。


凭借我天真的观点,我可以看到

位域方法的一些优点:我发现代码更具可读性(特别是对于

测试),没有命名空间问题,我不必关心

我是否使用了比机器字更多的位(我/ b $ b已经不得不在32位平台上使用34个标志,32位int和

长,这很痛苦)所以从这个意义上来看似乎更多

比bitmask方法便携。


你能帮我选择两种方法吗?


在此先感谢。

Hi,

This question seems to come up quite often, however I haven''t managed
to find an answer relevant to my case.

I often use binary flags, and I have alaways used a "bitmask"
technique, that is using #defined or const int powers of two, and
using the following primitives :
/* declaration and initizalisation of flags */ int flags = 0;
/* setting flag */ flags |= FLAG_1;
/* resseting flag */ flags &= ~FLAG_2;
/* conditional setting or resetting */ if (condition) flags |= FLAG_3;
else flags &= ~FLAG_3;
/* testing flags */ if ((flags & FLAG_4) || !(flags & FLAG_5)) { ... }
/* copy of the flag set */ other_flags = flags;

These are the only operations I ever use, they are only internal
representations. When I store or load or exchange data, I use a human-
readable text format, which basically boils down to setting or testing
flags with the above primitives.

I recently came across the "bitfield" concept, so an alernate solution
would be:
/* declaration and initizalisation of flags */
struct {
unsigned flag1 : 1;
unsigned flag2 : 1;
unsigned flag3 : 1;
unsigned flag4 : 1;
unsigned flag5 : 1;
} flags;
/* setting flag */ flags.flag1 = 1;
/* resetting flag */ flags.flag2 = 0;
/* condition setting or resetting */ flags.flag3 = (condition);
/* testing flags */ if (flags.flag4 || !flags.flag5) { ... }
/* copy fo the flag set */ other_flags = flags;

My first question is, is the last line correct? structure assignment
is a new concept for me, and I''m not familiar with it.

Are these codes portable? I have read quite a lot of portability
warning when using bitfields, however considering the limited set of
operations I used (in particular, the internal representation of the
bitfield is never taken into accoutn), I can''t see any problem in it.

Is there any efficiency difference between the two methods? Of course,
it depends on the platform and the compiler, but there might be a rule
of thumb. I have read that the bitfield is usually less efficient,
however I can''t see while a compiler with optimization turned on would
produce a different code than with the bitmask method.

With my naive point of view, I can see a few advantages to the
bitfield method : I find the code much more readable (especially for
testing), there is no namespace problems, and I don''t have to care
whether or not I''m using more bits than the machine word or not (I
already had to use 34 flags on a 32-bits platform with 32-bits int and
long, and it was quite painful) so in that sense it seems more
portable than the bitmask method.

Could you please help me choosing between the two methods?

Thanks in advance.

推荐答案

li ** ******@gmail.com 写道:
li********@gmail.com wrote:

/ *复制标志集* / other_flags =标志;


我的第一个问题是,最后一行是否正确?结构分配

对我来说是一个新概念,我对它不熟悉。
/* copy fo the flag set */ other_flags = flags;

My first question is, is the last line correct? structure assignment
is a new concept for me, and I''m not familiar with it.



是的,结构被复制为字节byte。

Yes, structures are copied byte for byte.


这些代码是否可移植?我在使用位域时已经阅读了相当多的便携性

警告,但考虑到我使用的有限的

操作(特别是

bitfield永远不会进入accoutn),我看不出任何问题。
Are these codes portable? I have read quite a lot of portability
warning when using bitfields, however considering the limited set of
operations I used (in particular, the internal representation of the
bitfield is never taken into accoutn), I can''t see any problem in it.



严格来说,没有。但实际上我从来没有遇到过使用它们的问题。

Strictly, no. But in practice I have never had a problem using them.


两种方法之间是否存在效率差异?当然,

它取决于平台和编译器,但可能有一个规则

的拇指。我已经读过,bitfield的效率通常不高,

但是当打开优化的编译器时,我看不到

会产生与使用位掩码不同的代码方法。
Is there any efficiency difference between the two methods? Of course,
it depends on the platform and the compiler, but there might be a rule
of thumb. I have read that the bitfield is usually less efficient,
however I can''t see while a compiler with optimization turned on would
produce a different code than with the bitmask method.



你必须在你的平台上测量。

That you will have to measure on your platform.


以我的天真观点,我可以看到

位域方法的一些优点:我发现代码更具可读性(特别是对于

测试),没有命名空间问题,我不知道我不得不关心

我是否使用了比机器字更多的位(我b
已经不得不在32-上使用34个标志具有32位int和

长的位平台,这非常痛苦)因此在这种意义上它似乎比bitmask方法更便携了。


你能帮我选择两种方法吗?
With my naive point of view, I can see a few advantages to the
bitfield method : I find the code much more readable (especially for
testing), there is no namespace problems, and I don''t have to care
whether or not I''m using more bits than the machine word or not (I
already had to use 34 flags on a 32-bits platform with 32-bits int and
long, and it was quite painful) so in that sense it seems more
portable than the bitmask method.

Could you please help me choosing between the two methods?



这取决于你和你的要求。我更喜欢比特币,因为你提到的原因是




-

Ian Collins。

It''s down to you and your requirements. I prefer bitfields for the
reasons you mention.

--
Ian Collins.


li********@gmail.com 写道:
li********@gmail.com writes:

我经常使用二进制标志,而且我总是使用bitmask

技术,即使用#defined或const int powers of两个,并且

使用以下原语:

/ *声明和标志的初始化* / int flags = 0;

/ *设置标志* / flags | = FLAG_1;

/ * resseting flag * / flags& = ~FLAG_2;

/ *条件设置或重置* / if(条件)标志| = FLAG_3;

else flags& = ~FLAG_3;

/ *测试标志* / if((flags& FLAG_4)||!(flags& FLAG_5) ){...}

/ *标志集的副本* / other_flags =标志;


这些是我用过的唯一操作,它们是只有内部

代表附件。当我存储或加载或交换数据时,我使用了一种人类可信的文本格式,它基本上归结为使用上述原语设置或测试

标志。 />

我最近遇到了bitfield。概念,所以alernate解决方案

将是:

/ *声明和旗帜的初始化* /

struct {

unsigned flag1:1;

unsigned flag2:1;

unsigned flag3:1;

unsigned flag4:1;

unsigned flag5:1;

}标志;

/ *设置标志* / flags.flag1 = 1;

/ *重置标志* / flags.flag2 = 0;

/ *条件设置或重置* / flags.flag3 =(条件);

/ *测试标志* / if( flags.flag4 ||!flags.flag5){...}

/ *复制标志集* / other_flags = flags;


我的第一个问题是,最后一行是否正确?结构分配

对我来说是一个新概念,我对它并不熟悉。
I often use binary flags, and I have alaways used a "bitmask"
technique, that is using #defined or const int powers of two, and
using the following primitives :
/* declaration and initizalisation of flags */ int flags = 0;
/* setting flag */ flags |= FLAG_1;
/* resseting flag */ flags &= ~FLAG_2;
/* conditional setting or resetting */ if (condition) flags |= FLAG_3;
else flags &= ~FLAG_3;
/* testing flags */ if ((flags & FLAG_4) || !(flags & FLAG_5)) { ... }
/* copy of the flag set */ other_flags = flags;

These are the only operations I ever use, they are only internal
representations. When I store or load or exchange data, I use a human-
readable text format, which basically boils down to setting or testing
flags with the above primitives.

I recently came across the "bitfield" concept, so an alernate solution
would be:
/* declaration and initizalisation of flags */
struct {
unsigned flag1 : 1;
unsigned flag2 : 1;
unsigned flag3 : 1;
unsigned flag4 : 1;
unsigned flag5 : 1;
} flags;
/* setting flag */ flags.flag1 = 1;
/* resetting flag */ flags.flag2 = 0;
/* condition setting or resetting */ flags.flag3 = (condition);
/* testing flags */ if (flags.flag4 || !flags.flag5) { ... }
/* copy fo the flag set */ other_flags = flags;

My first question is, is the last line correct? structure assignment
is a new concept for me, and I''m not familiar with it.



是的,没关系,但是你需要命名你的结构,否则你不会

能够声明other_flags变量。

Yes, it is fine, but you need have named your struct or you won''t be
able to declare the other_flags variable.


这些代码是否可移植?我在使用位域时已经阅读了相当多的便携性

警告,但考虑到我使用的有限的

操作(特别是

位域永远不会进入accoutn),我看不出任何问题

它。
Are these codes portable? I have read quite a lot of portability
warning when using bitfields, however considering the limited set of
operations I used (in particular, the internal representation of the
bitfield is never taken into accoutn), I can''t see any problem in
it.



是的。可移植性受到允许的最大位域(例如允许
)以及映射到值实际位位置等因素的影响。你

的情况还可以。

Yes. Portability is affected by things like the largest bitfield that
is allowed, and the mapping onto values actual bit positions. You
case is OK.


这两种方法有效率差异吗?当然,

它取决于平台和编译器,但可能有一个规则

的拇指。我已经读过,bitfield的效率通常不高,

但是当打开优化的编译器时,我看不到

会产生与使用位掩码不同的代码方法。
Is there any efficiency difference between the two methods? Of course,
it depends on the platform and the compiler, but there might be a rule
of thumb. I have read that the bitfield is usually less efficient,
however I can''t see while a compiler with optimization turned on would
produce a different code than with the bitmask method.



你关心这种细微差别吗?如果你这样做,唯一的办法就是测量和看看。

Do you care about such fine differences? If you do, the only recourse
is to measure and see.


以我天真的观点,我可以看到一些优点到
位域方法:我发现代码更具可读性(特别是对于

测试),没有命名空间问题,我不必关心

我是否使用了比机器字更多的位(I $ / $
已经必须在32位平台上使用34个标志,32位int并且

很长,而且非常痛苦)所以从这个意义上来说它似乎比bitmask方法更便宜了。


你能帮我选择两种方法吗?
With my naive point of view, I can see a few advantages to the
bitfield method : I find the code much more readable (especially for
testing), there is no namespace problems, and I don''t have to care
whether or not I''m using more bits than the machine word or not (I
already had to use 34 flags on a 32-bits platform with 32-bits int and
long, and it was quite painful) so in that sense it seems more
portable than the bitmask method.

Could you please help me choosing between the two methods?



主要的缺点(我可以看到)是不能测试的是套装中的b
。如果你乐意放弃这种用法,那么你还必须要求b $ b问为什么你不仅仅有一个带字段的结构。与使用位字段相比,这有一些优势(b)略有优势,除了程序需要大量复制之外,浪费的空间不太可能重要

结构。


-

Ben。

The main disadvantage (that I can see) is that bits can''t be tested
in sets. If you are happy to abandon that usage, then you must also
ask why you don''t just have a struct with char fields. This has a few
(slight) advantages over using bit fields and it is unlikely that
the wasted space matters except where the program needs lots of copies
of the struct.

--
Ben.


Ben Bacarisse写道:
Ben Bacarisse wrote:

>

主要缺点(我可以看到)是无法测试的位
$ b套装$ b。如果你乐意放弃这种用法,那么你还必须要求b $ b问为什么你不仅仅有一个带字段的结构。与使用位字段相比,这有一些优势(b)略有优势,除了程序需要大量复制之外,浪费的空间不太可能重要

结构。
>
The main disadvantage (that I can see) is that bits can''t be tested
in sets. If you are happy to abandon that usage, then you must also
ask why you don''t just have a struct with char fields. This has a few
(slight) advantages over using bit fields and it is unlikely that
the wasted space matters except where the program needs lots of copies
of the struct.



或位映射到硬件。


-

Ian Collins。

Or the bits map to hardware.

--
Ian Collins.


这篇关于位掩码与位域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆