• AVR Freaks

AnsweredLockedThe best way to split a 24bit integer into 3 8bit integers?

Page: 12 > Showing page 1 of 2
Author
Francesco C
Senior Member
  • Total Posts : 152
  • Reward points : 0
  • Joined: 2010/08/08 14:33:14
  • Location: UK
  • Status: offline
2017/08/24 10:37:20 (permalink)
0

The best way to split a 24bit integer into 3 8bit integers?

All,
What is the best, or correct way to split a 24bit number (long int I assume) into 3 8bit char.
 
Is this correct?
 unsigned long my_number =0xFFFFFF
 char msb, mid, lsb;
        msb=(my_number & 0xFF0000);
        mid= (my_number & 0x00FF00);
        lsb=  (my_number & 0x0000FF);
Thank you
 
Regards
Francesco C
#1
KTrenholm
Super Member
  • Total Posts : 742
  • Reward points : 0
  • Joined: 2012/08/08 14:04:23
  • Location: Connecticut, USA
  • Status: offline
Re: The best way to split a 24bit integer into 3 8bit integers? 2017/08/24 10:47:55 (permalink) ☼ Best Answerby Francesco C 2017/08/24 10:56:45
+2 (2)
You're masking, but you should shift it as well.  The way it's written msb and mid are out of range of a char.
 
 unsigned long my_number =0xFFFFFF
 char msb, mid, lsb;
        msb=(my_number & 0xFF0000)>>16;
        mid= (my_number & 0x00FF00)>>8;
        lsb= (my_number & 0x0000FF);

 
 
post edited by KTrenholm - 2017/08/24 10:49:57
#2
CinziaG
die fucking humans
  • Total Posts : 3145
  • Reward points : 0
  • Joined: 2016/12/07 14:20:36
  • Location: Wien
  • Status: offline
Re: The best way to split a 24bit integer into 3 8bit integers? 2017/08/24 10:50:32 (permalink)
+2 (2)
Yep, above or use an union (flame war coming soon Smile )

in 2018 you signed for your annihilation. in 2019 it will come ;) I promise
my most wonderful creations here
https://www.youtube.com/c...dPFRvtwsbSTXp6Sk6azGOQ
#3
TJ2015
The New Math
  • Total Posts : 491
  • Reward points : 0
  • Joined: 2015/04/19 11:38:37
  • Location: OSI
  • Status: offline
Re: The best way to split a 24bit integer into 3 8bit integers? 2017/08/24 10:52:46 (permalink)
+1 (3)

I'm pro-union wink: wink
#4
Francesco C
Senior Member
  • Total Posts : 152
  • Reward points : 0
  • Joined: 2010/08/08 14:33:14
  • Location: UK
  • Status: offline
Re: The best way to split a 24bit integer into 3 8bit integers? 2017/08/24 11:00:22 (permalink)
0
Thank you for your help,
I was not aware you need shifting those bits as well. (still learning).
 
Regards
 
Francesco C
#5
du00000001
Just Some Member
  • Total Posts : 3230
  • Reward points : 0
  • Joined: 2016/05/03 13:52:42
  • Location: Germany
  • Status: offline
Re: The best way to split a 24bit integer into 3 8bit integers? 2017/08/24 11:05:48 (permalink)
0 (2)
The best way? A union. As "unsigned long" represents 32 bits (even if only 24 bits are "filled-in"), the bytes-part of the union will have to hold 4 bytes as well. Whether you use an arry of bytes or 4 bytes named individually: your choice. Anyway, a union eliminates the shifting.
No flame wars - Peace!
#6
KTrenholm
Super Member
  • Total Posts : 742
  • Reward points : 0
  • Joined: 2012/08/08 14:04:23
  • Location: Connecticut, USA
  • Status: offline
Re: The best way to split a 24bit integer into 3 8bit integers? 2017/08/24 11:07:52 (permalink)
0
du00000001
The best way? A union. As "unsigned long" represents 32 bits (even if only 24 bits are "filled-in"), the bytes-part of the union will have to hold 4 bytes as well. Whether you use an arry of bytes or 4 bytes named individually: your choice. Anyway, a union eliminates the shifting.
No flame wars - Peace!




What makes a union the "Best" way?  Asking out of genuine curiosity as I've always assumed shifting was preferable as masking and shifting are very quick for a microprocessor to do.
#7
jtemples
عُضْوٌ جَدِيد
  • Total Posts : 11423
  • Reward points : 0
  • Joined: 2004/02/13 12:31:19
  • Location: Southern California
  • Status: offline
Re: The best way to split a 24bit integer into 3 8bit integers? 2017/08/24 11:21:30 (permalink)
+2 (2)
A union is not the "best way", and it doesn't eliminate any shifting on compilers that are smart enough to realize shifting isn't necessary in the first place (XC8 compiles the above code to three MOVFF instructions on a PIC18).
 
The union approach is not portable to different compilers since the order that the MSB/LSB is stored in multi-byte integers is implementation-defined.
#8
CinziaG
die fucking humans
  • Total Posts : 3145
  • Reward points : 0
  • Joined: 2016/12/07 14:20:36
  • Location: Wien
  • Status: offline
Re: The best way to split a 24bit integer into 3 8bit integers? 2017/08/24 11:52:19 (permalink)
0
Yep, union "should" be faster but can be not-portable and anyway with modern optimizers the shift method is as good.

in 2018 you signed for your annihilation. in 2019 it will come ;) I promise
my most wonderful creations here
https://www.youtube.com/c...dPFRvtwsbSTXp6Sk6azGOQ
#9
du00000001
Just Some Member
  • Total Posts : 3230
  • Reward points : 0
  • Joined: 2016/05/03 13:52:42
  • Location: Germany
  • Status: offline
Re: The best way to split a 24bit integer into 3 8bit integers? 2017/08/24 12:56:03 (permalink)
0 (2)
unions easily can be made portable if you implement the dependency on the endian-ness. Which is a one-time effort from which you can profit forever.
Why is it the best approach?
Because virtually every compiler will generate code that simply accesses the byte addressed. (As long as the controller supports byte access.) No masking, no shifting - just plain read or write of some byte. I've worked with many controllers (8051 - Core i-something), and this holds true for all of them.
 
BTW: What is an ever-repeating topic in these forums? The intricacies of the compilers. I do not trust them further than I have to.
post edited by du00000001 - 2017/08/24 12:58:38
#10
du00000001
Just Some Member
  • Total Posts : 3230
  • Reward points : 0
  • Joined: 2016/05/03 13:52:42
  • Location: Germany
  • Status: offline
Re: The best way to split a 24bit integer into 3 8bit integers? 2017/08/24 13:04:02 (permalink)
0
@ jtemples
The endian-ness is not implementation-defined!!
It is architecture-defined. Depending on the microcontroller architecture.
(Some of the latest controller architectures even sport a configurable endian-ness.)
 
Addon: you seem to ignore the fact that you are all using a lot of unions by using whatever xc.h includes 😊
 
May the war continue ...
#11
qhb
Superb Member
  • Total Posts : 9999
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: The best way to split a 24bit integer into 3 8bit integers? 2017/08/24 13:15:33 (permalink)
+1 (1)
du00000001
...
Because virtually every compiler will generate code that simply accesses the byte addressed. (As long as the controller supports byte access.) No masking, no shifting - just plain read or write of some byte. I've worked with many controllers (8051 - Core i-something), and this holds true for all of them.

Any decent compiler will do the same for shifts by a multiple of 8, if it can address variables on byte boundaries.
 
du00000001
@ jtemples
The endian-ness is not implementation-defined!!
It is architecture-defined. Depending on the microcontroller architecture.
 

Not necessarily. For an 8 bit processor, it is the compiler that determines which way round to place variables.
Only recently have Microchip started placing some SFR registers in little endian order in hardware.
Before that, often the low byte and high byte were in different banks.
 
 
#12
jtemples
عُضْوٌ جَدِيد
  • Total Posts : 11423
  • Reward points : 0
  • Joined: 2004/02/13 12:31:19
  • Location: Southern California
  • Status: offline
Re: The best way to split a 24bit integer into 3 8bit integers? 2017/08/24 13:31:35 (permalink)
+2 (2)
du00000001
unions easily can be made portable if you implement the dependency on the endian-ness. Which is a one-time effort from which you can profit forever.

 
How is it one-time?  You have to remember to look up the implementation or platform's endianness and configure your code every time you port to a new platform.  Why would I want do that for a hypothetical optimization?  And this being the XC8 forum, there is no optimization gained by doing it with XC8.
 
The endian-ness is not implementation-defined

 
What is the endianness of an 8-bit processor?  Whatever the compiler says it is.
 
Why is it the best approach?
Because virtually every compiler will generate code that simply accesses the byte addressed.

 
That's classic premature optimization.  If it's actually critical that the operation be as small or fast as possible, write implementation-specific code.  Otherwise, you're just creating more work for yourself.
#13
NorthGuy
Super Member
  • Total Posts : 5805
  • Reward points : 0
  • Joined: 2014/02/23 14:23:23
  • Location: Northern Canada
  • Status: online
Re: The best way to split a 24bit integer into 3 8bit integers? 2017/08/24 13:46:55 (permalink)
+5 (5)
I am pro-freedom. Do whatever you like and don't listen to what other people say. Of course, you need to understand what you're doing, but you need to anyway.
#14
dan1138
Super Member
  • Total Posts : 3285
  • Reward points : 0
  • Joined: 2007/02/21 23:04:16
  • Location: 0
  • Status: offline
Re: The best way to split a 24bit integer into 3 8bit integers? 2017/08/24 13:57:44 (permalink)
+2 (2)
Every time a "best way" topic comes up regarding unpacking bytes someone suggests using shifts and masks, someone else suggests unions then a discussion ensues on efficiency versus portability versus architectural byte ordering.
 
Each side of this issue has its adherents and its detractors but the specious argument is the one about architectural byte ordering. Microchip has no commonly available controller that uses the most significant byte first architecture so this is a Microchip forum so expect that all code will be running on a controller using the least significant byte first order.
 
Do any of the Atmel 32-bit ARM cores use the most significant byte first order?
 
Form the point of view of code maintainability the clarity of using shifts and masks makes the best implementation choice until execution speed becomes critical. When speed is critical then the only implementation choice is "whatever I have to do" and forget about any "style" imperative.
 
The bottom line there is that there is no "best way" to do this for an embedded system.
#15
jtemples
عُضْوٌ جَدِيد
  • Total Posts : 11423
  • Reward points : 0
  • Joined: 2004/02/13 12:31:19
  • Location: Southern California
  • Status: offline
Re: The best way to split a 24bit integer into 3 8bit integers? 2017/08/24 14:21:27 (permalink)
+1 (1)
Do any of the Atmel 32-bit ARM cores use the most significant byte first order?

 
Some ARMs let you configure the endianness on the fly with the SETEND instruction.  I don't know if the Atmel ARMs support that.
#16
Gort2015
Klaatu Barada Nikto
  • Total Posts : 3333
  • Reward points : 0
  • Joined: 2015/04/30 10:49:57
  • Location: 0
  • Status: offline
Re: The best way to split a 24bit integer into 3 8bit integers? 2017/08/24 14:56:32 (permalink)
0
A pointer can also be used.
unsigned long z=0x12345678;
char *x=(char *)&z;
 
printf("x[0]=0x%02X\r",x[0]); //78  or *x++
printf("x[1]=0x%02X\r",x[1]); //56
printf("x[2]=0x%02X\r",x[2]); //34
printf("x[3]=0x%02X\r",x[3]); //12

 

MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
https://www.youtube.com/watch?v=Iu1qa8N2ID0
+ ST:Continues, "What Ships are Made for", Q's back.
#17
qhb
Superb Member
  • Total Posts : 9999
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: The best way to split a 24bit integer into 3 8bit integers? 2017/08/24 14:57:41 (permalink)
+1 (1)
That's assuming the endianness as well.
#18
du00000001
Just Some Member
  • Total Posts : 3230
  • Reward points : 0
  • Joined: 2016/05/03 13:52:42
  • Location: Germany
  • Status: offline
Re: The best way to split a 24bit integer into 3 8bit integers? 2017/08/24 15:01:49 (permalink)
0
Even the 8-Bitter has endian-ness implemented: tze result from multiplying 2 bytes ends up in some "16 Bit register". If this register is memory-mapped: voilà!
But I agree that for 8-Bitters the compiler has a chance to influence "the whole thing". But only on these.
 
As about the "once - forever" approach: I have these "type-cast unions" twice in some header - "bracketed" with #ifdef _LITTLE_ENDIAN resp. #ifdef _BIG_ENDIAN.
OK - on a new machine I have to #define which pattern applies and whether the compiler eventually brings its own symbol. I would not consider this any "effort" as it is basic knowledge required anyway when checking "patterns" in some memory map.
(You're free to check your variables in the watch window. Especially some array with 256 elements 😅)
#19
du00000001
Just Some Member
  • Total Posts : 3230
  • Reward points : 0
  • Joined: 2016/05/03 13:52:42
  • Location: Germany
  • Status: offline
Re: The best way to split a 24bit integer into 3 8bit integers? 2017/08/24 15:11:48 (permalink)
+4 (4)
Of course, you need to understand what you're doing, but you need to anyway.

 
Well spoken. This is what's keeping these forums alive: those who know what they are doing 😎
#20
Page: 12 > Showing page 1 of 2
Jump to:
© 2019 APG vNext Commercial Version 4.5