开发者

Separate signed int into bytes in NXC

Is there any way to convert a signed integer into an array of bytes in NXC? I can't use explicit type casting or pointers either, due to language limitations.

I've tried:

for(unsigned long i = 1; i <= 2; i++)
{
    MM_mem[id.idx] = ((val &a开发者_如何转开发mp; (0xFF << ((2 - i) * 8)))) >> ((2 - i) * 8));

    id.idx++;
}

But it fails.

EDIT: This works... It just wasn't downloading. I've wasted about an hour trying to figure it out. >_>


EDIT: In NXC, >> is a arithmetic shift. int is a signed 16-bit integer type. A byte is the same thing as unsigned char.


NXC is 'Not eXactly C', a relative of C, but distinctly different from C.


How about

    unsigned char b[4];

    b[0] = (x & 0xFF000000) >> 24;
    b[1] = (x & 0x00FF0000) >> 16;
    b[2] = (x & 0x0000FF00) >> 8;
    b[3] = x & 0xFF;


The best way to do this in NXC with the opcodes available in the underlying VM is to use FlattenVar to convert any type into a string (aka byte array with a null added at the end). It results in a single VM opcode operation where any of the above options which use shifts and logical ANDs and array operations will require dozens of lines of assembly language.

task main()
{
  int x = Random(); // 16 bit random number - could be negative
  string data;
  data = FlattenVar(x); // convert type to byte array with trailing null
  NumOut(0, LCD_LINE1, x);
  for (int i=0; i < ArrayLen(data)-1; i++)
  {
#ifdef __ENHANCED_FIRMWARE
    TextOut(0, LCD_LINE2-8*i, FormatNum("0x%2.2x", data[i]));
#else
    NumOut(0, LCD_LINE2-8*i, data[i]);
#endif
  }
  Wait(SEC_4);
}

The best way to get help with LEGO MINDSTORMS and the NXT and Not eXactly C is via the mindboards forums at http://forums.mindboards.net/


Question originally tagged c; this answer may not be applicable to Not eXactly C.

What is the problem with this:

int value;
char bytes[sizeof(int)];

bytes[0] = (value >>  0) & 0xFF;
bytes[1] = (value >>  8) & 0xFF;
bytes[2] = (value >> 16) & 0xFF;
bytes[3] = (value >> 24) & 0xFF;

You can regard it as an unrolled loop. The shift by zero could be omitted; the optimizer would certainly do so. Even though the result of right-shifting a negative value is not defined, there is no problem because this code only accesses the bits where the behaviour is defined.

This code gives the bytes in a little-endian order - the least-significant byte is in bytes[0]. Clearly, big-endian order is achieved by:

int value;
char bytes[sizeof(int)];

bytes[3] = (value >>  0) & 0xFF;
bytes[2] = (value >>  8) & 0xFF;
bytes[1] = (value >> 16) & 0xFF;
bytes[0] = (value >> 24) & 0xFF;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜