Binary Concatenation not Working - c

I am currently working on a project in C and I am running into some issues when I am trying to concatenate some binary numbers.
uint64_t IMM = vmicxtFetch4Byte(processor, thisPC+2);
uint64_t shiftedInstr = ((uint64_t) instr16) << 32;
uint64_t instr48 = IMM | shiftedInstr;
printf("Instr16: %x IMM: %lx Instr64: %lx\n", instr16, (unsigned long) IMM, (unsigned long) instr48);
Now the output I get for the Immediate value (IMM) and the initial instruction (instr16) are correct but the OR'd result doesn't seem to be giving me what I want. I expect 068200000040 but i get
Instr16: 682 IMM: 40 Instr64: 40
I have done this sort of binary math a lot and for some reason this is tripping me up. Any thoughts would be appreciated!

This is a problem with output, not with the computation. You cast the converted value of instr48 to unsigned long, which appears to be a 32-bit type on your system. The most significant portion of instr48 gets "sliced off", so you get the value that consists of only the least significant part.
You should cast it to unsigned long long instead, and use %llu format specifier.

To get "068200000040" from instr48 code needs
Leading 0 in print specifier
Print width of 12.
Matching specifier sequence which for uint64_t is found in #include <inttypes.h>
#include <inttypes.h>
printf("Instr64: %012" PRIx64 "\n", instr48);

Related

Embedded-C:How to perform division between 2 unsigned integers and display the answer in decimal format

I am new to embedded System. I would like to perform division between 2 unsigned 16 bit integer and display the answer(including the decimal values). I wonder how can I accomplish this in embedded-C. Float,double and unsigned long does not seem to work. I am using TI's TM4C launchpad.
uint8_t PPGMsg[5];
unsigned long PPG;
uint16_t IR_combined,RED_combined;
IR_combined = (PPGMsg[1]<< 8)|PPGMsg[2];
RED_combined = (PPGMsg[3]<< 8)|PPGMsg[4];
PPGMsg[0]=(RED_combined/IR_combined);
PPG=(RED_combined/IR_combined);
UARTprintf("IR_combined is: %d\n",IR_combined);
UARTprintf("RED_combined is: %d\n",RED_combined);
UARTprintf("PPG is: %d\n",PPGMsg[0]);
UARTprintf("long PPG is: %d\n",PPG);
For example when IR_combined is: 147 and RED_combined is: 1012, the PPG: 6.
However I would like the answer to be displayed as 6.88 instead.
For 2 decimals precision, you need to do (uint32_t)RED_combined*100/IR_combined. Then print the decimals as you would like them. Example:
#include <stdint.h>
#include <inttypes.h>
...
uint16_t RED_combined = 1012;
uint16_t IR_combined = 147;
uint16_t x = ((uint32_t)RED_combined*100u / IR_combined);
printf("%"PRIu16".%.2"PRIu16, x/100, x%100);
However, you also have lots of other problems/bugs:
IR_combined = (PPGMsg[1]<< 8)|PPGMsg[2]; is dangerous/buggy code. Since PPGMsg[1] is a small integer type, it gets promoted to int and you end up performing left shifts on a signed type. Similarly, the | invokes implicit promotion to signed type.
You must study Implicit type promotion rules.
(PPGMsg[3]<< 8)|PPGMsg[4]; Same bugs here.
PPGMsg[0]=(RED_combined/IR_combined); You store the result in a 8 bit variable that is too small to hold the result. I don't understand how this makes any sense. Are you trying to parse out the ls byte?
%d is used to print signed integers. UARTprintf("IR_combined is: %d\n",IR_combined); should be "IR_combined is: %"PRIu16 "\n",IR_combined. You find these format specifier macros in inttypes.h.
Same bug: UARTprintf("PPG is: %d\n",PPGMsg[0]);. Should be UARTprintf("PPG is: %"PRIu8 "\n",PPGMsg[0]);.
unsigned long is printed with %ld
Using the correct type matters, everywhere!
Also consider using a good compiler like gcc that does warn if you use the wrong format specifier. Or better yet, don't use printf-like functions at all - they are unsafe, slow and resource-heavy.

C printf of an integer with %lu produces large number

I know that is bad practice to print an integer with %lu which is a unsigned long. In a project i was working on i got a large number when trying to print 11 with %lu in the snprint format.(old code) I am using gcc 4.9.3.
This code below i thought would produce the wrong number since snprintf is told to read more than the 4 bytes occupied. Its doesnt though. Works perfectly. It reads everything correctly. Either it does not go past the 4 bytes in to the unknown or the extra 4 bytes in the long are fully of zeros when it gets promoted to long from int.
I am wondering out of curiosity is when does printf print the wrong number? What conditions does it need produce a wrong big number? There has to be garbage in the upper 4 bytes but it seems like it does not set that garbage for me.
I read the answers here but the code worked for me. I know its a different compiler.
Printing int type with %lu - C+XINU
#include<inttypes.h>
#include<stdio.h>
int main(void){
uint32_t number1 = 11;
char sentence[40];
snprintf(sentence,40,"Small number :%lu , Big number:%lu \n",number1,285212672);
printf(sentence);
}
On OP's machine, uint32_t, unsigned long and int appear to be the same size #R Sahu. OP's code is not portable and may produce incorrect output on another machine.
when does printf print the wrong number?
Use the matching printf() specifier for truly portable code. Using mis-matched specifiers may print the wrong number.
The output string may be well over 40 characters. Better to use a generous or right-sized buffer.
#include <inttypes.h>
#include <stdio.h>
int main(void){
uint32_t number1 = 11;
// char sentence[40];
char sentence[80];
snprintf(sentence, sizeof sentence,
"Small number :%" PRIu32 " , Big number:%d \n",
number1, 285212672);
// printf(sentence); // Best not to print a string using the printf() format parameter
fputs(sentence, stdout);
}

C printf integer type U32

I have the hex value 0x5a800000000b and I'm trying to get a printf statement in C to print it to the console.
So far (because I'm useless in C) I'm able to get the 'b' to print, using the syntax:
printf("Hex value%x\n", value);
The value is stored in an integer type U32, but after trying all different combinations of %llx, %lx, I just keep getting compiler warnings.
I'm guessing that I'm getting the printf syntax wrong, but I can't seem to find the right % option, can someone help me out?
Thanks
It's not a problem with the printf.
The problem is that a 32 bits variable cannot hold the value 0x5a800000000b. 32 bits can hold only 8 hex digits: 0x0000000b. Hence the b on output.
To store such a large value, you should use a 64 bits variable.
long long value = 0x5a800000000bLL
Note also the double L at the end. It tells the compiler that the constant is also a long long.
Then you can use %llx in the printf format string.
There are some pre-defined macro for these types:
#include <inttypes.h>
int64_t PRId64. PRIi64
int32_t PRId32, PRIi32
int16_t PRId16, PRIi16
int8_t PRId8, PRIi8
For example:
printf("%"PRId32"\n", my32Int);
The value 0x5a800000000b is more that 32 bits, so you have to use a long.
long value = 0x5a800000000bl;
printf("Hex value%lx\n", value);
Note that hex constant should end in l,.

Defined behavior, passing character to printf("%02X"

I recently came across this question, where the OP was having issues printing the hexadecimal value of a variable. I believe the problem can be summed by the following code:
#include <stdio.h>
int main() {
char signedChar = 0xf0;
printf("Signed\n”);
printf(“Raw: %02X\n”, signedChar);
printf(“Masked: %02X\n”, signedChar &0xff);
printf(“Cast: %02X\n", (unsigned char)signedChar);
return 0;
}
This gives the following output:
Signed
Raw: FFFFFFF0
Masked: F0
Cast: F0
The format string used for each of the prints is %02X, which I’ve always interpreted as ‘print the supplied int as a hexadecimal value with at least two digits’.
The first case passes the signedCharacter as a parameter and prints out the wrong value (because the other three bytes of the int have all of their bits set).
The second case gets around this problem, by applying a bit mask (0xFF) against the value to remove all but the least significant byte, where the char is stored. Should this work? Surely: signedChar == signedChar & 0xFF?
The third case gets around the problem by casting the character to an unsigned char (which seems to clear the top three bytes?).
For each of the three cases above, can anybody tell me if the behavior defined? How/Where?
I don't think this behavior is completely defined by c standard. After all it depends on binary representation of signed values. I will just describe how it's likely to work.
printf(“Raw: %02X\n”, signedChar);
(char)0xf0 which can be written as (char)-16 is converted to (int)-16 its hex representation is 0xfffffff0.
printf(“Masked: %02X\n”, signedChar &0xff);
0xff is of type int so before calculating &, signedChar is converted to (int)-16.
((int)-16) & ((int)0xff) == (int)0x000000f0.
printf(“Cast: %02X\n", (unsigned char)signedChar);
(unsigned char)0xf0 which can be written as (unsigned char)240 is converted to (unsigned int)240 as hex it's 0x000000f0

How to print 5 byte integer values?

I've just started reading C and have a question about a macro.
How can I print a 5 byte integer value (that happens to be defined in a macro)?
For example:
#define MAX 0xdeadbeaf12
int main(){
printf(" 0x %2x \n", MAX);
}
This code prints adbeaf12 but not deadbeaf12.
How do I get all the bytes printed?
I prefer to make my assumptions about the size of a variable explicit. The following uses standard (though often unused) macros to define a 64-bit constant and print such a quantity as a hex value.
#include <stdio.h>
// Pull in UINT64_C and PRIx64 macros
#include <inttypes.h>
// Make this a 64-bit literal value
#define MAX UINT64_C(0xdeadbeaf12)
int main()
{
// Use PRIx64 which inserts the correct printf specifier for
// a hex format of a 64-bit value
printf(" 0x%" PRIx64 " \n", MAX);
}
#define MAX 0xdeadbeaf12LL
Will tell the compiler to use the longest available integer type (which will then be cast to an appropriate type wherever MAX is used).
On most platforms, the numeric literal suffix LL will correspond to signed long long, this is 64bit (8 bytes) on a 32 bit system. C's excellent typing system and compiler warnings will take care of the rest for you.
Your printf then needs to use the ll modifier:
printf(" 0x %2llx \n", MAX);

Resources