Convertion from a uint16 to uint8 [closed] - c

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
Does anybody know how I can do a correct conversion from a uint16 to a uint8 in a C program for my STM32F091?
I thought that it was like this:
uint16_t Test = 0x565;
uint8_t Test2 = (uint8_t)Test;
But that doesn't work very well, so does anyone has a suggestion?
[update from comment:]
I use a potentiometer that has a minimum value of 0x0 and a maximum value of 0xFFF. Test must have the value of ADC1->DR (this is a value from the ADC in the STM32F0)

Edit:
You cannot compress the data without information lost in this case. Since your data range from ADC is 0x000 to 0xFFF - there is no way for you to represent the data perfectly without information/precision lost in uint8 byte whose range is only from 0x00 to 0xFF
But you still can map the data with precision lost. For example:
uint8_t Test2 = (unsigned)(Test >> 4);
Will cause you to map every 16 range to a single value:
0-15 -> 0
16-31 -> 1
32-47 -> 2
//and so on
Since you only have 8 LEDs anyway, you could use uint8 byte to control the LED - though you will lose precision of the real value, but you are still able to represent the range of the value (per unit of 16) correctly with your 8 LEDs (since you only have 8 LEDs anyway)
Original:
The case is very likely cause by overflow when you cast bigger-sized uint16 data type to smaller-sized uint8:
uint16_t Test = 0x565;
uint8_t Test2 = (uint8_t)Test; //Test2 value is only 0x65, 0x500 is missing
The casting causes the most significant byte value (0x500) to be truncated.

Related

How to extract few bits or bytes from a byte array? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I want a function which would help me to extract few bits or bytes from a starting bit position from a byte array. The order of the byte array is LSB. The skeleton of the code is as follows:
typedef unsigned char uint8;
typedef unsigned short uint16;
uint16 ExtractBitsOrBytes(uint16 StartBit, uint8 *ByteArray, uint16 BitsWanted)
{
uint16 Result;
...
}
How can I implement this logic in C?. Any example or starting point is much appreciated.
Your problem is not fully specified: LSB refers to the order of bytes in memory for integral types spanning more than one byte. In your case you must specify how the bits are numbered in the array and composed to form the value extracted.
It would make sense to number the bits from 0, such that bit n is the bit with value 1 << (n % 8) in the byte at offset n / 8. For consistency, the bit with the lowest number should become the least significant bit of the extracted value. This convention is consistent with LSB as extracting 16 bits at offset 0 yields the value of the uint16 stored in the first 2 bytes of the array.
Here is a naive implementation with this convention:
typedef unsigned char uint8;
typedef unsigned short uint16;
uint16 ExtractBitsOrBytes(uint16 StartBit, const uint8 *ByteArray, uint16 BitsWanted) {
// assuming BitsWanted <= 16
uint16 result = 0;
uint16 i;
for (i = 0; i < BitsWanted; i++) {
result |= (uint16)((ByteArray[StartBit >> 3] >> (StartBit & 7)) & 1) << i;
StartBit++;
}
return result;
}
Note however that the convention used for monochrome bitmaps on many systems is different: the leftmost pixel corresponds to the most significant bit of the first byte, a convention inherited from choices made in the late 70s, mixing MSB and LSB, that made graphics software more complicated than it should have been.

Conversion from int to unsigned short [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
this is a part of a C program that i didn't understand :
unsigned short twittlen;
int x;
x = atoi(argv[1]);
twittlen = x;
if(twittlen >= 64) {
printf("Nope , You don't know about Integer");
return -1;
}
if (x >= 64 )
printf("you got it ");
My problem is how to find an int that is greater than 64 but when converting it to unsigned short it will be less than 64 !
I looked alot about limit of those types of integers even on stackoverflow but i didn't find the answer about this !
Thanks in advance :)
When you assign an int value to an unsigned short, truncation will occur.
Assuming int is 4 bytes and short is 2, you simply need to provide the program with a value greater than 64 whose lower two bytes are less than 64.
The maximum unsigned 16-bit value is 65535:
0x0000FFFF
So if you enter the number 65536:
0x00010000
When truncated to just two bytes:
0x0000
Is zero.

Single floating point decimal to binary in C [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am trying to write C program that initializes a variable of type float to 1000.565300 and extracts relevant fields of the IEEE 754 representation. I should extract the sign bit (bit 31), the exponent field (bits 30 to 23) and the significant field (bits 22 to 0). I should use bit masking and shift operations to extract these fields. My program should keep the extracted fields in 32-bit unsigned integers and should print their values in the hexadecimal and binary formats. And here is my program. I do not know how to bit masking
Well, one easy way to do all this is:
Interpret a float bits as an unsigned: uint32_t num = *(uint32_t*)&value
It means: I want to treat the address of value as the address of a 32 bit unsigned and then I want to take the value stored at that address
Sign: int sign = (~(~0u>>1)&num) ? -1 : 1 //checks if first bit of float is 1 or 0 , if it's 1 then it's a negative number
exp part: uint32_t exp = num&0x7F800000
mantissa : uint32_t mant = num&0x007FFFFF
If you don't know masks :
0x7F800000 : 0 11111111 00000000000000000000000
0x007FFFFF : 0 00000000 11111111111111111111111
As for printing bits , you can use this function:
void printbits(uint32_t num)
{
for(uint32_t m=~(~0u>>1);m;m>>=1) // initial m = 100..0 then 0100..0 and so on
putchar(n&m ? '1' : '0');
putchar('\n');
}

Pointer in C, don't understand how they got this result [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
main(){
char i[2];
* i = 0;
* (i + 1) = 1;
printf("len = %d \n",sizeof(int *));
printf("i[0] = %d \n",*(int *)i);
}
where the answer is not 16 the answer is 256
i use the turboc2.0 the hex is 100
This code depends on your system, specifically on the size of an int.
After initializing, your i array looks like this:
------------
|0x00 | 0x01 |
------------
Assumed an int is 32 bits on your system:
When casting i to an *int and dereferencing it, there will be four bytes which are accessed (since an int is 32 bits or four bytes):
--------------------------
|0x00 | 0x01 | 0x?? | 0x?? |
--------------------------
So, the last two bytes are out of bounds of your array, will have any value, and you will observe undefined behavior (on my system, actually, it prints different values each time I execute the code, like 1762656512, -375848704, ...).
Assumed an int is 16 bits on your system, it gets a littlebit "better":
In this case, when casting i to an *int and dereferencing it, the two bytes will be accessed as a 16 bit value. But, it then still depends on the endianess which value you get:
Little endian: *(int*) i = 0x0100 = 256
Big endian: *(int*) i = 0x0001 = 1
So, if you expect 256, you need to make sure to be on a little endian 16 bit system ...
BTW: When using sizeof() with printf(), make sure to use the %zu format specifier.

Byte testing between user specified boundaries [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 9 years ago.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
I'm playing around attempting to check specific bytes within a packet's payload and test if they are >,<,!, = to a specified value. The boundary points are dynamic, what is the best way to evaluate the bytes between them?
For example, I have a packet with a payload (following the headers of course) and I want to evaluate between byte 5 and byte 10 to see if it is greater than some specified value.
The return value of memcmp() does a nice unsigned little endian compare.
return memcmp(&packet[IndexLo], &Reference, IndexHi - IndexLo + 1);
A portable method would simple compare 1 byte at a time.
Quick method but has a number of assumptions:
. Packet data and platform same endian and Little.
. Boundary_width <= sizeof inttype.
. unsigned arithmetic.
. Optimized for Packet_CompareMask().
. Accessing a width integer on any byte boundary OK.
. OK to access memory just past end of packet.
typedef uint64_t inttype;
int Packet_CompareMask(const char *packet, size_t IndexLo, unint64_t Mask, inttype Reference) {
// This fails on machine with alignment restricts on wide integers.
inttype x = *((inttype *) &packet[IndexLo]);
x &= Mask;
if (x < Reference) return -1;
return x > 0;
}
int Packet_CompareRange(const void *packet, size_t IndexLo, size_t IndexHi, inttype Reference) {
inttype Mask = 0;
ssize_t Diff = IndexHi - IndexLo;
if ((Diff <= 0) || (Diff > (sizeof(Mask) - 1))) {
; // handle error
}
// This only works on little endian machines. A variant would work with Big endian.
while (--Diff >= 0) {
Mask <<= 8;
Mask |= 0xFF;
}
return Packet_CompareRange(packet, IndexLo, Mask, Reference);
}

Resources