int to two chars

Go To Last Post
25 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The int is stored in 2 memory places. I need to send it via uart, so i need to divide it into two. I do it like this

a = int & 0x00FF;
b = (int & 0xFF00) >> 8;

But inst there anyway I could simply get directly into the mmory and do something like getting directly two 8 bit vars. with out the "math"?

Thankyou

There are pointy haired bald people.
Time flies when you have a bad prescaler selected.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#include 
main() {
  short int i = 32;
  char a = ((char*)&i)[0];
  char b = ((char*)&i)[1];
  printf("[%d][%d]", a, b);
}

:?:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
a = *( char *)&i;
b = *((char *)&i + 1);
register char *p;
p = &i;
a = *p++;
b = *p;
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks...

There are pointy haired bald people.
Time flies when you have a bad prescaler selected.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
typedef union _int_char
{
  int i;
  char ch[2];
} int_char;

int_char value;
value.i = 32;
printf("%c%c", value.ch[0], value.ch[1]);
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Neat techniques. I'll have to try some of these. I wonder if using these techniques saves any time over just doing

uint8_t low = integer & 0xFF;
uint8_t high = integer >> 8;
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just a special note here... bogasaurus' answer is the ANSI way, and will work on any platform correctly. The other 3 postings, which are all essentiually the same, rely on the organization of a multibyte value in RAM, and therefore may break if the code is ever ported onto a different platform, or in the case of 8 bit micros, even a different compiler.

Also note that the & 0xFF isn't needed, as the upper 8 bits will be truncated. The masking is only required if the destination type is larger than the desired bitlength.

uint8_t low = integer;
uint8_t high = integer >> 8; 

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

glitch wrote:
Just a special note here... bogasaurus' answer is the ANSI way, and will work on any platform correctly. The other 3 postings, which are all essentiually the same, rely on the organization of a multibyte value in RAM, and therefore may break if the code is ever ported onto a different platform, or in the case of 8 bit micros, even a different compiler.

Also note that the & 0xFF isn't needed, as the upper 8 bits will be truncated. The masking is only required if the destination type is larger than the desired bitlength.

uint8_t low = integer;
uint8_t high = integer >> 8; 

Oh, nifty. I wonder if the compiler removes the & 0xFF automatically... probably not hunh.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

glitch wrote:
Just a special note here... bogasaurus' answer is the ANSI way, and will work on any platform correctly. The other 3 postings, which are all essentiually the same, rely on the organization of a multibyte value in RAM, and therefore may break if the code is ever ported onto a different platform, or in the case of 8 bit micros, even a different compiler.

Also note that the & 0xFF isn't needed, as the upper 8 bits will be truncated. The masking is only required if the destination type is larger than the desired bitlength.

uint8_t low = integer;
uint8_t high = integer >> 8; 

Not exactly true. Only if sizeof (int) == 2.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

brberie wrote:
Not exactly true. Only if sizeof (int) == 2.

Not sure what your point of contention is. The high bits will be truncated, during the copy, no matter if the int is 16, or 32 bits in size.... only the least significant 8 bits will be passed to the result (assuming the destination var is 8 bits in size). Thus only shifting and copying operations are required. One special note... source and destination must be unsigned... if they are signed, you may not get the desired result.

If the destination var was 16bits in size, but you only wanted 8 bits.. then indeed you will need to include a mask.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

brberie wrote:
glitch wrote:

uint8_t low = integer;
uint8_t high = integer >> 8; 

Not exactly true. Only if sizeof (int) == 2.

Fine, let's be pedantic:

#include 

uint16_t integer = 0xAA55;
uint8_t low = integer;    // low will contain 0x55.
uint8_t high = integer >> 8;     // high will contain 0xAA.

Oh and technically you only need sizeof (int) > 1 for this to work.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Actually it'll still work if sizeof(int) was 1... it's just that high will always be filled with 0.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey, Eric:

That's not enough pedantic. This is very pedantic:

#include 

uint_least16_t integer = UINT16_C(0xAA55);
uint8_t low = (uint8_t) integer;             // low will contain 0x55
uint8_t high = (uint8_t) (integer >> 8);     // high will contain 0xAA

Only requires an 8 bit size integer, and C99 compatible stdint.h (avr-libc-1.4.0 or later)

And this gets the prize to the universally compatible mega-pedantic one:

#include 

uint_least16_t integer = UINT16_C(0xAA55);
uint_least8_t low = (uint_least8_t) (integer & UINT8_C(0xff));
uint_least8_t high = (uint_least8_t) ((integer >> 8) & UINT8_C(0xff));

Regards,

Carlos.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I was talking about any platform. There are some with sizeof(int)==4.I gues sizeof(int)==8 is already exist or will be pretty soon.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

brberie wrote:
I was talking about any platform. There are some with sizeof(int)==4.I gues sizeof(int)==8 is already exist or will be pretty soon.

But as I said.. it does not matter what the sizeof(int) is.. it can be anything... the destination is what matters, and in this case it's uint8_t.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

wrong!

Quote:

uint8_t high = integer >> 8; 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

please explain... There is nothing wrong with that statement. Integer can be 1, 2, 4, or even 8 bytes. "high" will contain bits 8-15 of the original value. I made no other claim.

By all means please try to prove my statements incorrect. Just don't tell me I'm wrong with a one word reply like a troll.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In my understanding high is a highest 8 bits of an int. If it is not than for uint32_t bytes are going to be low, high, higher, highest? What about uint64_t? My English isn't good enough to provide terminology for that.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

High implies nothing about the data type.. it's just a name, that makes sense in the context of it's use. In this case high represents the high 8 bits of a 16bit value.. that 16bit value may be stored in a datatype that is 16, 32, 64 or more bits in length.. it does not matter.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You posted "absolute" solution and it is not absolute. I believe that the guy who has asked initial question had in mind very simple staff and was satisfied with help.
You wanted something more, so lets be precise with that including names. If one will ask: int in 3 chars? Every one would ask what is sizeof int? Right?
And if low byte includes bits 0-7 than what bits are in the high? Depends on size of int but not bits 8-15!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

brberie wrote:
I was talking about any platform.

Sorry, but if you want to discuss about *any* platform then take this thread to the comp.lang.c newsgroup.

This forum is about the AVR platform, using the AVR-GCC compiler.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Memory maping
assume char: 8 bits & int: 16 bits

int a;
char *b = (char*)(&a);

send_uart(*(b+0));
send_uart(*(b+1));

or
send_uart(b[0]);
send_uart(b[1]);

I always use memory mapping, like buffer to stucture and sturcture to buffer.

Time to go too sleep :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

EW, I did NOT start this discussion. But you're right "any platform" should be put in quotes. a

glitch wrote:
Just a special note here... bogasaurus' answer is the ANSI way, and will work on any platform correctly. The other 3 postings, which are all essentiually the same, rely on the organization of a multibyte value in RAM, and therefore may break if the code is ever ported onto a different platform, or in the case of 8 bit micros, even a different compiler.

Also note that the & 0xFF isn't needed, as the upper 8 bits will be truncated. The masking is only required if the destination type is larger than the desired bitlength.

uint8_t low = integer;
uint8_t high = integer >> 8; 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

brberie wrote:
You posted "absolute" solution and it is not absolute. I believe that the guy who has asked initial question had in mind very simple staff and was satisfied with help.
You wanted something more, so lets be precise with that including names. If one will ask: int in 3 chars? Every one would ask what is sizeof int? Right?
And if low byte includes bits 0-7 than what bits are in the high? Depends on size of int but not bits 8-15!

You're reading into this too much. It was not a general question about sending out an int of arbitrary size, it was about sending out an int of 16bits in size. Indeed one cannot send out a 32bit value in two chars... that was never the question here. And thus was never reflected in the answer. Had the question been about sending a 24bit value out the port, then there would be a 3rd line, and a 3rd character. For 32 bit, a 4th and so on.

In terms of my statement of portability to any platform.. it still works for all, except those where int is only 8 bits in size, this is because int no longer has enough resolution for the source value. Had the system been ported to a 32bit platform, the data might have been stored in a 32bit variable, but the actual range should still be only 16bits if nothing else is changed in the code. So it still works. Don't get confused with the range/size of the data and the range/size of data type, they are quite often different.

You as the programmer are responsible for choosing names that make sense to you, in the context in which they are used. As the programmer, you are also responsible for knowing the size of your data-types, or the values that they contain, so that when you do down convert them to individual bytes for transmission, you know how many bytes to send. Just because an int might be 32 bits in size, does not mean you need to send all 32 bits, if the range of the actual data is only 16 bits.

As for your issue with the names, I did not choose the names... if you read the whole thread, you will see that the variable names came from the original post. And again, they make sense in the context of which they are used. They represent the high, and low bytes of a 16bit value.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

brberie wrote:
EW, I did NOT start this discussion

You're right.

But I will end it.

Topic locked