3字节整数 [英] 3-byte ints

查看:124
本文介绍了3字节整数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有2个计数器 - 一个需要是一个2字节变量,而

其他需要3个字节(不是我的选择,但我坚持了!) 。

我已经宣布它们为:


unsigned short small;

unsigned long large:24;


第一个问题 - 这是宣布大的最佳方式一到

确保它是3个字节?我得到的另一个建议是unsigned char

large [3];但是对于算术运算会更加困难。


现在我需要一个通用宏来增加它们,我需要<如果计数器在递增时会溢出,则
能够生成报告。

所以我不需要为每种类型的计数器都有单独的宏,我已经

这样做是通过引入一个临时的unsigned long(没有计数器将比这更大的
)来存储原件然后使用增量

使用真正的计数器(以确保溢出发生在预期的那个类型的计数器时)然后通过查看

结果是否小于原始结果来测试它是否已翻转在incCntr()中宏观如下:


#include< stdio.h>


typedef struct {

unsigned short small;

unsigned long large:24;

} CNTRS;


#define incCntr(cntr,incr)\

do {\

unsigned long _tmp =(unsigned long)(cntr); \

(cntr)=(cntr)+(incr); \

if((cntr)< _tmp){\

printf(" Overflow at%lu +%d \ n",_ tmp,(incr) )); \

(cntr)= _tmp; \

} \

printf("%lu - >%lu \ n",_ tmp,(unsigned long)(cntr)); \

}而(0)


int main(无效)

{

CNTRS cntrs;

cntrs.small = 65529;

cntrs.large = 16777210;

incCntr(cntrs.small,5);

incCntr(cntrs.small,5);

incCntr(cntrs.large,5);

incCntr(cntrs.large,5);

返回1;

}


第二个问题 - 任何人都看到进行溢出测试的任何问题

这样或者可以提出更好的选择吗?


编译时我收到此警告:


gcc -Wall -otst tst.c

tst.c:在函数main中:

tst.c:26:警告:long unsigned int格式,unsigned int arg(arg 3)

tst.c:27:警告:long unsigned int format,unsigned int arg(arg 3)


它抱怨cntr&quo吨;该行中的论点:


printf("%lu - >%lu \ n",_ tmp,(unsigned long)(cntr));


第三个问题 - 为什么编译器显然忽略了我的演员和

抱怨(unsigned long)(cntr)是一个unsigned int?


第四个问题 - 是否有任何理由不将我的小

计数器声明为无符号长位字段,即:


unsigned long small:16;


为了保持一致性?


FWIW,运行程序的结果是我的预期:


tst

65529 - > 65534

溢出65534 + 5

65534 - > 65534

16777210 - > 16777215

溢出16777215 + 5

16777215 - > 16777215

问候,


Ed。

I have 2 counters - one is required to be a 2-byte variable while the
other is required to be 3 bytes (not my choice, but I''m stuck with it!).
I''ve declared them as:

unsigned short small;
unsigned long large: 24;

First question - is that the best way to declare the "large" one to
ensure it''s 3 bytes? Another suggestion I got was "unsigned char
large[3];" but that would be a little tougher to do arithmetic
operations on.

Now I need a general-purpose macro to increment them and I need to be
able to produce a report if the counter would overflow when incremented.
So I don''t need to have separate macros for each type of counter, I''ve
done this by introducing a temporary unsigned long (no counter will be
larger than that) to store the original and then doing the increment
using the real counter (to ensure that overflow occurs when expected for
that type of counter) then testing if it rolled over by seeing if the
result is less than the original as in the "incCntr()" macro below:

#include <stdio.h>

typedef struct {
unsigned short small;
unsigned long large: 24;
} CNTRS;

#define incCntr(cntr,incr) \
do { \
unsigned long _tmp = (unsigned long)(cntr); \
(cntr) = (cntr) + (incr); \
if ((cntr) < _tmp) { \
printf("Overflow at %lu + %d\n",_tmp,(incr));\
(cntr) = _tmp; \
} \
printf("%lu -> %lu\n",_tmp,(unsigned long)(cntr));\
} while(0)

int main(void)
{
CNTRS cntrs;
cntrs.small = 65529;
cntrs.large = 16777210;
incCntr(cntrs.small,5);
incCntr(cntrs.small,5);
incCntr(cntrs.large,5);
incCntr(cntrs.large,5);
return 1;
}

Second question - anyone see any problems with doing the overflow test
this way or can suggest a better alternative?

When compiling I get this warning:

gcc -Wall -otst tst.c
tst.c: In function `main'':
tst.c:26: warning: long unsigned int format, unsigned int arg (arg 3)
tst.c:27: warning: long unsigned int format, unsigned int arg (arg 3)

It''s complaining about the "cntr" argument in the line:

printf("%lu -> %lu\n",_tmp,(unsigned long)(cntr));

Third question - why is the compiler apparently ignoring my cast and
complaining that "(unsigned long)(cntr)" is an unsigned int?

Fourth question - would there be any reason not to declare my "small"
counter as an unsigned long bit-field too, i.e.:

unsigned long small: 16;

for consistency?

FWIW, the result of running the program is what I expected:

tst
65529 -> 65534
Overflow at 65534 + 5
65534 -> 65534
16777210 -> 16777215
Overflow at 16777215 + 5
16777215 -> 16777215

Regards,

Ed.

推荐答案

Ed Morton< mo **************** @ lucent.com>写在

新闻:bk ******* @ netnews.proxy.lucent.com:
Ed Morton <mo****************@lucent.com> wrote in
news:bk*******@netnews.proxy.lucent.com:
我有2个柜台 - 一个是必需的是一个2字节的变量,而
其他需要3个字节(不是我的选择,但我坚持了!)。
我已经宣布它们为:

unsigned short small;
unsigned long large:24;
I have 2 counters - one is required to be a 2-byte variable while the
other is required to be 3 bytes (not my choice, but I''m stuck with it!).
I''ve declared them as:

unsigned short small;
unsigned long large: 24;




位字段如何帮助你?为什么不:


unsigned short small; //这个平台上的16位

unsigned long large; //这个平台上的32位


#define INCR_SMALL(s,i)做\

{\

if(s + i< = UNSIGNED_SHORT_MAX)s + = i; \

else printf(" Overflow off" #s" +" #i" \ n"); \

}而(0)


#define INCR_LARGE(l,i)做\

{\

if(l + i< = 0x00FFFFFFUL)l + = i; \

else printf(" Overflow off" #l" +" #i" \ n"); \\ /

}而(0)


注意:以上是未经测试的。


-

- 马克 - >

-



How does the bit field help you? Why not:

unsigned short small; // 16-bits on this platform
unsigned long large; // 32-bits on this platform

#define INCR_SMALL(s, i) do \
{ \
if (s + i <= UNSIGNED_SHORT_MAX) s += i; \
else printf("Overflow off " #s "+" #i "\n"); \
} while (0)

#define INCR_LARGE(l, i) do \
{ \
if (l + i <= 0x00FFFFFFUL) l += i; \
else printf("Overflow off " #l "+" #i "\n"); \
} while (0)

Note: above is untested.

--
- Mark ->
--


" Mark A. Odell" <无**** @ embeddedfw.com>写在

新闻:Xn ******************************* @ 130.133.1.4:
"Mark A. Odell" <no****@embeddedfw.com> wrote in
news:Xn*******************************@130.133.1.4 :

#define INCR_SMALL(s,i)do \
{\
if((unsigned long)s + i< = UNSIGNED_SHORT_MAX )s + = i; \

#define INCR_SMALL(s, i) do \
{ \
if ((unsigned long) s + i <= UNSIGNED_SHORT_MAX) s += i; \



^^^^^^^^^^^^^^^

哎呀,需要这个。


-

- 马克 - >

-


^^^^^^^^^^^^^^^
Oops, need this.

--
- Mark ->
--


在消息< bk * ******@netnews.proxy.lucent.com>

Ed Morton< mo **************** @ lucent.com>写道:
In message <bk*******@netnews.proxy.lucent.com>
Ed Morton <mo****************@lucent.com> wrote:
我有2个计数器 - 一个需要是一个2字节变量,而
其他需要3个字节(不是我的选择,但我' 我坚持了!。
我已经宣布他们:

无符号短小;
无符号长大:24;

第一个问题 - 是宣布大的最佳方式。一个确保它的3个字节?


差不多,假设它在一个结构中。我唯一要说的是:


1)C90除了int之外不允许任何其他内容。和unsigned int对于

位域类型。 C99允许实现提供其他类型

,如unsigned long;大概是你的实现 - 它是

a常见的扩展名。


2)位域的大小不能超过它的类型 - 如果你做了

将它更改为unsigned int,你就要求

int至少为24位(但你会得到一个诊断,如果它不是)。

[剪码]
第二个问题 - 任何人都看到进行溢出测试的任何问题
这样或者可以提出更好的选择吗?


对我来说很好看。如果你正在使用C99,你可以使用uintmax_t而不是

unsigned long,以防万一你将来会得到更大的位域。


我不会但是,从主要方面返回1 - 这可能被解释为

调用环境的错误条件。

它正在抱怨 CNTR"行中的论点:

printf("%lu - >%lu \ n",_ tmp,(unsigned long)(cntr));

第三个问题 - 为什么编译器显然忽略了我的演员并且抱怨(unsigned long)(cntr)是一个unsigned int?


因为它有车吗?您的代码对我来说很好。

第四个问题 - 是否有任何理由不将我的小
计数器声明为无符号长位字段,即:

unsigned long small:16;

为了保持一致性?
I have 2 counters - one is required to be a 2-byte variable while the
other is required to be 3 bytes (not my choice, but I''m stuck with it!).
I''ve declared them as:

unsigned short small;
unsigned long large: 24;

First question - is that the best way to declare the "large" one to
ensure it''s 3 bytes?
Pretty much, assuming it''s in a structure. The only things I''d say are:

1) C90 doesn''t allow anything other than "int" and "unsigned int" for
bitfield types. C99 does allow implementations to offer other types
like "unsigned long"; presumably your implementation does - it''s
a common extension.

2) The size of a bitfield can''t exceed that of its type - if you did
change it to "unsigned int", you''d then have a requirement that
int was at least 24 bits (but you''d get a diagnostic if it wasn''t).
[ snip code ]
Second question - anyone see any problems with doing the overflow test
this way or can suggest a better alternative?
Looks fine to me. If you''re using C99 you could use uintmax_t rather than
unsigned long, just in case you end up with larger bitfields in future.

I wouldn''t return 1 from main though - that''ll probably be interpreted as
an error condition by the calling environment.
It''s complaining about the "cntr" argument in the line:

printf("%lu -> %lu\n",_tmp,(unsigned long)(cntr));

Third question - why is the compiler apparently ignoring my cast and
complaining that "(unsigned long)(cntr)" is an unsigned int?
Because it''s buggy? Your code looks fine to me.
Fourth question - would there be any reason not to declare my "small"
counter as an unsigned long bit-field too, i.e.:

unsigned long small: 16;

for consistency?




不是真的,模块化上面关于类型的评论。它可能更便携

,因为它可以保证恰好16位,短不会。但是在

的实践中,我看到编译器为一个16位的比特字段而不是短的代码生成了明显不同的代码。对于代码生成术语或者只是对齐,''short''可能不会更加优化,或者只是对齐。


-

Kevin Bracey,首席软件工程师

Tematic Ltd电话:+44(0)1223 503464

182-190 Newmarket Road传真:+44(0 )1223 503458

剑桥,CB5 8HE,英国WWW: http:/ /www.tematic.com/


这篇关于3字节整数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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