不知道大家在写程序的时候用不用union,之前我只拿来当前后相关性非常强的define来用,有时也和书上一样,存储绝对不会一起出现的值。0 u9 |# G+ {% i, @: ^' H) N
之前看M4的SIMD指令时发现很多操作涉及到数据的封装,把两个16位数值放到一个32位变量的高位和低位里。开始的想法是写个16位数组然后强制类型转换为32位读出。后来看了《C专家编程》,发现可以这么写
4 e5 G) u6 w* Z$ s% L; b9 o( ?
# h" Q% @/ R! U; T* ~- union simdq{
" \7 e( k p1 ~0 L4 ~+ d9 b) Z - int32_t data;
& l# t+ u9 P, I: `- h) W( w - int16_t dbyte[2];
复制代码 以下是PC测试程序(同时给2个数乘2,我随便想的一个),也通过32试验
6 o# @, o. P% @$ ~" p4 a7 H- #include <stdio.h>
8 C2 a9 c, ?9 x+ \# |6 }: } B - #include <stdint.h> k$ n9 R! H7 J5 U
- int/ T1 c. Q* q, q
- main(int argc,char * argv[]){7 e" @5 n1 T u" @, N
- union simdq{) B/ K! R3 p- g
- int32_t data;1 j& d$ c, X4 H$ I3 N! f/ Z2 f
- int16_t dbyte[2];
9 |) `+ m: B5 c) S - }test;+ b4 `3 W! s1 a/ t, k0 m/ z# g8 a
- test.dbyte[0]=1234;) i! N+ J5 J+ C) H# {
- test.dbyte[1]=-5678;
6 h M2 I# P3 L$ ?+ G5 a, Z - printf("test.dbyte[0]= %x\ntest.dbyte[1]= %x\n",test.dbyte[0],test.dbyte[1]);2 e. n/ _" a2 J
- printf("test.data = %x\n",test.data);& f0 d+ E, M$ w" I8 s! ~ p
- test.data*=2;6 L' U" i4 I/ q- g
- printf("test.dbyte[0]= %x\ntest.dbyte[1]= %x\n",test.dbyte[0],test.dbyte[1]);
' S, j( [+ G5 V! O/ } [( I5 m - printf("test.data = %x\n",test.data);
* |- Q" _8 o b& C2 `( ^- ] - return 0;
n0 i% r! G& Q! _( ^' b - }
复制代码 返回$ B* D2 f* d g7 Z2 {" F7 _
- test.dbyte[0]= 1234
3 C" \0 D; h% o6 x: O - test.dbyte[1]= -56781 g9 W! W$ f8 g
- test.data = -372112174
% o L3 T/ g. s4 F. d! E) K - test.dbyte[0]= 2468
1 p3 u( F4 ]8 p+ \ - test.dbyte[1]= -11356
$ H8 l& j4 T( q - test.data = -744224348
复制代码 8 X- d! r: h9 Q( k4 C" W
如果使用16进制,则需要把类型改成 unsigned int ,否则若最高一位为1,读取值会自动扩展(用printf和%x看起来似乎是这样(而且无法通过强制类型转换解决(例如dbyte[1]=0xFFFFACF0(期望值应该是0xACF0(非常诡异(希望高手解答(也是和大家交流分享知识)))))))7 o- z/ \$ ]8 G$ j; \
. ?; s7 U* `6 s; ]' zMCU:STM32F401 + Keil v5* H+ y5 C7 _ F/ _# n/ Q1 b
PC :Intel core + clang 3.7.0
0 M/ ^. v( Q- O& M9 t2 F, e' [$ p1 v7 @0 N- H
|
uint16_t dword[2];
int32_t data;
受教了,那我使用16位负数的时候是否会存在相应的风险