so I'm trying to shift these values left to store all this data into a 64 bit value. Unfortunately the numbers turn negative right at the first shift, what's causing this? Isn't it only suppose to store the first 41 bits of mil_t time into x? Also why would the remainder of serial and userid be zero?
long int gen_id(){ printf("Calling gen_id...\n"); unsigned long int mil_t = 1623638363132; unsigned long int serial = 10000; unsigned int rowId = 5; unsigned int userId = 30000; printf("Original mil_t: %ld\n", mil_t); unsigned long int x = mil_t << 41; printf("GEN_ID | MIL_T shift left 41: %ld\n", x); unsigned long int tbusMod = userId % serial; printf("GEN_ID | tbusMod = userId mod serial: %ld\n", tbusMod); x += tbusMod << (64 - 41 - 13); printf("GEN_ID | x1 : %ld\n", x); x += (rowId % 1024); printf("GEN_ID | x2 : %ld\n", x); return x; } OUTPUT:
Original mil_t: 1623638647191 GEN_ID | MIL_T shift left 41: -4136565053832822784 GEN_ID | tbusMod = userId mod serial: 0 GEN_ID | x1 : -4136565053832822784 GEN_ID | x2 : -4136565053832822779 FINAL: -4136565053832822779 TOTAL BYTES: 68
%luis the conversion specifier forunsigned long, you are printing as a signed value...rowId % 1024, just dorowid & 0x3ff. In the case of an unsigned operand, the compiler will probably do this anyway as an optimization, but I prefer not to use the remainder operator in the first place. If the operand is signed, then the compiler may need to do additional work to handle a negative operand when replacing the%operator.