Array doubles in size if a struct defines both its uint16_t words and uint8_t bytes


Instead of an array of 2 bytes, use a structure of 2 bytes:

// Two bytes in a 16-bit word
typedef struct{
    uint8_t     lsb;    // As uint8_t, LSB
    uint8_t     msb;    // As uint8_t. MSB
} two_bytes_t;

typedef union {
   uint16_t u16;   // As uint16_t
   two_bytes_t  u8x2; // As 2 each of uint8_t
} my_array_t;


my_array_t my_array[1]; // 1 word array, for testing

my_array[0].u8x2.msb = 1;
my_array[0].u8x2.lsb = 2;

The XC16 compiler correctly allocates only 2 bytes for each element, and the debugger correctly shows the individual bytes.



How may we reload struct pointer to array back to uint8_t array?

I was trying memcpy, but this is 1 way that works.

for (i=0; i < SIZE_MAX; i++)  {// message fixed at
length 10
    //printf(" %x",  ((uint8_t*) media_ptr->addressOfPtr)[i]);
    message[i] = ((uint8_t*) media_ptr->addressOfPtr)[i];
    printf(" %x",  message[i]);
}

TinyOS: converting uint16_t and uint8_t into uint32_t

The problem is that h_MSB is uint8_t and the shift operation is performed within the uint8_t type (or possibly within uint16_t, but it doesn't matter), so you get 0. Cast it to uint32_t before shifting:

(*timeStamp) = (((uint32_t)Header->h_MSB) << 16) |
Header->h_LSB;

Array of doubles in java: How to create an array without mentioning the size and give it to another method for populating it

Since Java is pass-by-value, you can not directly pass the double[] array to have it created inside the method so that it is still visible when the method returns.

The closest solution you can get is to use a container object:

class DoubleContainer {
   public double[] theArray;
}

public class SampleContainer {

   public void populate(DoubleContainer dc) {
      dc.theArray = new double[2];
      dc.theArray[0] = 42.0;
      dc.theArray[1] = 43.0;
   }

   public static void main(String[] args) {
      SampleContainer sc = new SampleContainer();

      // create the double[] container and call the API method
      DoubleContainer dc = new DoubleContainer();
      sc.populate(dc);

      System.err.println(java.util.Arrays.toString(dc.theArray));
   }
}

A much simpler alternative would be to return the array:

public class Sample {

   public double[] populate() {
      double[] result = new double[2];
      result[0] = 42.0;
      result[1] = 43.0;
      return result;
   }
}

On a side note, as others mentioned, consider using ArrayList instead of raw arrays.


Pass uint16_t array into function that takes uint8_t*

When you say uint16_t d[10];, you are defining an array d. When you say d[0], you access the first element of that array, which is of type uint16_t. The function is expecting a pointer, so you should cast a pointer to your array, not an element in it:

fctn( (uint8_t*)d, 10*sizeof(uint16_t) );

When you do this, d is decayed from type uint16_t[10] to uint16_t*, then cast to uint8_t* before being passed to fctn.

As an aside, you can also use sizeof(d) to simplify your length calculation:

fctn( (uint8_t*)d, sizeof(d) );

Note that this only works if d is declared as an array (on the stack).


Converting uint16_t to decimal and storing it in char array, bitwise. Error in retrieving the data in uint16_t variable

As written, the output is indeterminate because you never set ptr[1] to a known value. On my Mac, this minor variation of your code (primarily added some, headers, spaces and printf() statements):

#include <stdint.h>
#include <stdio.h>

int main(void)
{
    unsigned char ptr[9];
    uint16_t dat = 128, s;
    int i, j = 1;

    ptr[0] = ptr[0] & 0;
    j = -1;
    printf("0x%.2X 0x%.2X
", ptr[0], ptr[1]);

    for (i = 0; i <= 15; i++)
    {
        if (i % 8 == 0)
            j++;

        s = dat << i;

        if (s & (1 << 15))
            ptr[j] |= 1 << (7 - i % 8);
        else
            ptr[j] |= 0 << (7 - i % 8);
    }
    printf("0x%.2X 0x%.2X
", ptr[0], ptr[1]);

    j = -1;
    s &= 0;

    for (i = 0; i <= 15; i++)
    {
        if (i % 8 == 0)
            j++;
        s |= (ptr[j] & (1 << (7 - i % 8))) << (15 -
i);  // <-----------
    }

    printf("0x%.2X
", s);
    printf("%d
", s);

    return(0);
}

shows the output:

0x00 0xF4
0x00 0xF4
0x5510
21776

When modified to replace ptr[0] = ptr[0] & 0; with ptr[0] = ptr[1] = 0;, the output is:

0x00 0x00
0x00 0x80
0x4000
16384

You're unlucky that your machine zeroes the stack; it is going to much harder for you to spot mistakes like uninitialized variables.

Your choice of 128 as a test value makes life difficult; there is only one bit set. Were I testing, I'd use a distinctive pattern such as 0x3CA5 (0b0011'1100'1010'0101 in C++14 binary notation). When I change the code to use 0x3CA5, I get the output:

0x00 0x00
0x3C 0xA5
0x5411
21521

The good news: the first loop copies the bits so that the high-order byte of the number is in ptr[0] and the low-order byte is in ptr[1]. The bad news: the second loop seems to mangle things horribly.

Here's an instrumented version of the second loop:

    for (i = 0; i < 16; i++)
    {
        if (i % 8 == 0)
            j++;
        uint16_t s0 = s;
        s |= (ptr[j] & (1 << (7 - i % 8))) << (15 -
i);  // <-----------
        printf("i: %2d, j: %d, 7-i%%8: %d, ptr[j]: 0x%.2X, &val:
0x%.2X, "
               "|val = 0x%.5X, s0: 0x%.4X, s: 0x%.4X
",
               i, j, 7 - i % 8, ptr[j], (1 << (7 - i % 8)),
               (ptr[j] & (1 << (7 - i % 8))) << (15 -
i),
               s0, s);
    }

The output is:

0x00 0x00
0x3C 0xA5
i:  0, j: 0, 7-i%8: 7, ptr[j]: 0x3C, &val: 0x80, |val = 0x00000,
s0: 0x0000, s: 0x0000
i:  1, j: 0, 7-i%8: 6, ptr[j]: 0x3C, &val: 0x40, |val = 0x00000,
s0: 0x0000, s: 0x0000
i:  2, j: 0, 7-i%8: 5, ptr[j]: 0x3C, &val: 0x20, |val = 0x40000,
s0: 0x0000, s: 0x0000
i:  3, j: 0, 7-i%8: 4, ptr[j]: 0x3C, &val: 0x10, |val = 0x10000,
s0: 0x0000, s: 0x0000
i:  4, j: 0, 7-i%8: 3, ptr[j]: 0x3C, &val: 0x08, |val = 0x04000,
s0: 0x0000, s: 0x4000
i:  5, j: 0, 7-i%8: 2, ptr[j]: 0x3C, &val: 0x04, |val = 0x01000,
s0: 0x4000, s: 0x5000
i:  6, j: 0, 7-i%8: 1, ptr[j]: 0x3C, &val: 0x02, |val = 0x00000,
s0: 0x5000, s: 0x5000
i:  7, j: 0, 7-i%8: 0, ptr[j]: 0x3C, &val: 0x01, |val = 0x00000,
s0: 0x5000, s: 0x5000
i:  8, j: 1, 7-i%8: 7, ptr[j]: 0xA5, &val: 0x80, |val = 0x04000,
s0: 0x5000, s: 0x5000
i:  9, j: 1, 7-i%8: 6, ptr[j]: 0xA5, &val: 0x40, |val = 0x00000,
s0: 0x5000, s: 0x5000
i: 10, j: 1, 7-i%8: 5, ptr[j]: 0xA5, &val: 0x20, |val = 0x00400,
s0: 0x5000, s: 0x5400
i: 11, j: 1, 7-i%8: 4, ptr[j]: 0xA5, &val: 0x10, |val = 0x00000,
s0: 0x5400, s: 0x5400
i: 12, j: 1, 7-i%8: 3, ptr[j]: 0xA5, &val: 0x08, |val = 0x00000,
s0: 0x5400, s: 0x5400
i: 13, j: 1, 7-i%8: 2, ptr[j]: 0xA5, &val: 0x04, |val = 0x00010,
s0: 0x5400, s: 0x5410
i: 14, j: 1, 7-i%8: 1, ptr[j]: 0xA5, &val: 0x02, |val = 0x00000,
s0: 0x5410, s: 0x5410
i: 15, j: 1, 7-i%8: 0, ptr[j]: 0xA5, &val: 0x01, |val = 0x00001,
s0: 0x5410, s: 0x5411
0x5411
21521

Except that the values in s0 and s are not what you want, and ignoring |val, the values are what we'd expect; the basic iteration structure is under control. However, the |val column shows that there is a problem — it was unexpected to need to use 5 hex digits in the output format! The i - 15 shift is not placing bits where you want and need them placed.

From here, you need to resolve the problem for yourself. What I hope this does is provide you with some insight in how to go about debugging such problems.

Incidentally, the question has been updated to offer:

s |= (ptr[j] & (1 << i%8)) << (15 - i); //
Correction

In my test harness with 0x3CA5 as the initial value in dat, that produces the output:

0x00 0x00
0x3C 0xA5
i:  0, j: 0, 7-i%8: 7, ptr[j]: 0x3C, &val: 0x80, |val = 0x00000,
s0: 0x0000, s: 0x0000
i:  1, j: 0, 7-i%8: 6, ptr[j]: 0x3C, &val: 0x40, |val = 0x00000,
s0: 0x0000, s: 0x0000
i:  2, j: 0, 7-i%8: 5, ptr[j]: 0x3C, &val: 0x20, |val = 0x08000,
s0: 0x0000, s: 0x8000
i:  3, j: 0, 7-i%8: 4, ptr[j]: 0x3C, &val: 0x10, |val = 0x08000,
s0: 0x8000, s: 0x8000
i:  4, j: 0, 7-i%8: 3, ptr[j]: 0x3C, &val: 0x08, |val = 0x08000,
s0: 0x8000, s: 0x8000
i:  5, j: 0, 7-i%8: 2, ptr[j]: 0x3C, &val: 0x04, |val = 0x08000,
s0: 0x8000, s: 0x8000
i:  6, j: 0, 7-i%8: 1, ptr[j]: 0x3C, &val: 0x02, |val = 0x00000,
s0: 0x8000, s: 0x8000
i:  7, j: 0, 7-i%8: 0, ptr[j]: 0x3C, &val: 0x01, |val = 0x00000,
s0: 0x8000, s: 0x8000
i:  8, j: 1, 7-i%8: 7, ptr[j]: 0xA5, &val: 0x80, |val = 0x00080,
s0: 0x8000, s: 0x8080
i:  9, j: 1, 7-i%8: 6, ptr[j]: 0xA5, &val: 0x40, |val = 0x00000,
s0: 0x8080, s: 0x8080
i: 10, j: 1, 7-i%8: 5, ptr[j]: 0xA5, &val: 0x20, |val = 0x00080,
s0: 0x8080, s: 0x8080
i: 11, j: 1, 7-i%8: 4, ptr[j]: 0xA5, &val: 0x10, |val = 0x00000,
s0: 0x8080, s: 0x8080
i: 12, j: 1, 7-i%8: 3, ptr[j]: 0xA5, &val: 0x08, |val = 0x00000,
s0: 0x8080, s: 0x8080
i: 13, j: 1, 7-i%8: 2, ptr[j]: 0xA5, &val: 0x04, |val = 0x00080,
s0: 0x8080, s: 0x8080
i: 14, j: 1, 7-i%8: 1, ptr[j]: 0xA5, &val: 0x02, |val = 0x00000,
s0: 0x8080, s: 0x8080
i: 15, j: 1, 7-i%8: 0, ptr[j]: 0xA5, &val: 0x01, |val = 0x00080,
s0: 0x8080, s: 0x8080
0x8080
32896

This is not the complete answer.

I am trying to get the value of dat into s. I need it because I have to send the char array over a UDP socket. So at one end I will store integer as binary in a character array and then on the other end reassemble it as an integer.

You don't need to do bitwise operations to achieve the result you are after; bytewise operations work fine.

ptr[0] = dat >> 8;
ptr[1] = dat & 0xFF;  // You could get away without the '&
0xFF'

// Transmit over UDP

dat = (ptr[0] << 8) | ptr[1];

It is important that you use unsigned char (which you are doing); if you use plain char (or, worse, signed char), then you have to worry about sign bits and sign extension.

As an exercise for you in bit manipulation, this has some purpose; it is worth you spending some time to fix your code so it works. As a way of manipulating the data for transmission over the network, it is not a good way of working and should be jettisoned once you've learned what you can about bit manipulation.


Array doubles in size if a struct defines both its uint16_t words and uint8_t bytes

Instead of an array of 2 bytes, use a structure of 2 bytes:

// Two bytes in a 16-bit word
typedef struct{
    uint8_t     lsb;    // As uint8_t, LSB
    uint8_t     msb;    // As uint8_t. MSB
} two_bytes_t;

typedef union {
   uint16_t u16;   // As uint16_t
   two_bytes_t  u8x2; // As 2 each of uint8_t
} my_array_t;


my_array_t my_array[1]; // 1 word array, for testing

my_array[0].u8x2.msb = 1;
my_array[0].u8x2.lsb = 2;

The XC16 compiler correctly allocates only 2 bytes for each element, and the debugger correctly shows the individual bytes.



- Technology - Languages
+ Webmasters
+ Development
+ Development Tools
+ Internet
+ Mobile Programming
+ Linux
+ Unix
+ Apple
+ Ubuntu
+ Mobile & Tablets
+ Databases
+ Android
+ Network & Servers
+ Operating Systems
+ Coding
+ Design Software
+ Web Development
+ Game Development
+ Access
+ Excel
+ Web Design
+ Web Hosting
+ Web Site Reviews
+ Domain Name
+ Information Security
+ Software
+ Computers
+ Electronics
+ Hardware
+ Windows
+ PHP
+ ASP/ASP.Net
+ C/C++/C#
+ VB/VB.Net
+ JAVA
+ Javascript
+ Programming
Privacy Policy - Copyrights Notice - Feedback - Report Violation 2018 © BigHow