This is a java function, i converted to golang code, but appear error.
How can I solve this problem? please teach.
java code:
int p = -1;
int x = 0;
x |= 0x1 << p;
p++;
golang code:
var p int = -1
var x int = 0
x |= 0x1 << p
p++
shift code type int, must be unsigned integer
This is an error because as per Go specifications, bit shifting only works on unsigned ints:
left shift integer << unsigned integer
right shift integer >> unsigned integer
Related
I am trying to figure out, how to use an unsigned char type of a variable inside a for loop, while not "breaking" out of range for unsigned char, which can vary form 0 to 255.
main(void) {
TRISC = 0;
LATC = 0;
unsigned char j;
for (j = 0; j <= 255 ; j++){
LATC = j;
__delay_ms(1000);
}
return;
}
This is code in C, where PIC is programmed. "TRISC = 0" means setting port C as an output and "LATC" is referring to port C itself. Basically I want to assign values from including 0 to 255 to this port. But if I try to compile this, the compiler (xc8) returns following two warnings:
I cannot quite understand what these two are saying, but I assume it has to do something with variable j exceeding the limit value of unsigned char, that is 255 (in last iteration j = 256, which is not allowed/defined).
However, this code gets compiled and works as meant. But I still want to write and understand a code that assigns port C the value of 255 without entering "prohibited" range of values.
*P.S. I would use any other variable type than unsigned char or char, however to ports in PICs only these two types can be applied directly (without conversion).
j <= 255 is always true if j is only 8 Bit wide.
This version should work:
main(void) {
TRISC = 0;
LATC = 0;
int j;
for (j = 0; j <= 255 ; j++){
LATC = (unsigned char)j;
__delay_ms(1000);
}
return;
}
First, in microcontroller firmware, you should not return from main(). Your main() should include some kind of endless loop.
j <= 255 is always true for a uint8_t variable. Because j can't be 256. Adding 1 to j when it's 255, makes it 0, not 256.
As others have suggested, using an 16-bit integer, signed or unsigned, is the easiest and the cleanest way. However, in performance sensitive loops you may prefer to stick with 8 bit loop counters as these are the fastest ones for a 8-bit PIC microcontroller.
This particular one-time loop can be written as:
uint8_t j = 0;
do {
LATC = j++;
__delay_ms(1000);
} while (j != 0);
code like this:
#include <stdio.h>
int main(){
struct{
unsigned char a:4;
unsigned char b:4;
}i;
struct{
unsigned char a:4;
unsigned char b:4;
unsigned char c:4;
}j;
i.a = 1;
i.b = 1;
j.a = 1;
j.b = 1;
j.c = 1;
printf("size of i is: %d, size of j is: %d", sizeof(i), sizeof(j));
return 0;
}
why the output is 1 2? means size of i possess 1 byte, j possess 2 bytes. we know unsigned char have 1 byte, so why i not equal 2? i am sorry for my english.
All variables in C++ are padded upto next byte.
In struct i, both a and b are of 4 bit summing up to 1 byte.
In j, variables sum up to 12 bits, but size is 2 byte due to padding.
Reference: http://www.cplusplus.com/forum/general/51911/
I need to convert rgba8 to rgba5551 manually. I found some helpful code from another post and want to modify it to convert from rgba8 to rgba5551. I don't really have experience with bitewise stuff and haven't had any luck messing with the code myself.
void* rgba8888_to_rgba4444( void* src, int src_bytes)
{
// compute the actual number of pixel elements in the buffer.
int num_pixels = src_bytes / 4;
unsigned long* psrc = (unsigned long*)src;
unsigned short* pdst = (unsigned short*)src;
// convert every pixel
for(int i = 0; i < num_pixels; i++){
// read a source pixel
unsigned px = psrc[i];
// unpack the source data as 8 bit values
unsigned r = (px << 8) & 0xf000;
unsigned g = (px >> 4) & 0x0f00;
unsigned b = (px >> 16) & 0x00f0;
unsigned a = (px >> 28) & 0x000f;
// and store
pdst[i] = r | g | b | a;
}
return pdst;
}
The value of RGBA5551 is that it has color info condensed into 16 bits - or two bytes, with only one bit for the alpha channel (on or off). RGBA8888, on the other hand, uses a byte for each channel. (If you don't need an alpha channel, I hear RGB565 is better - as humans are more sensitive to green). Now, with 5 bits, you get the numbers 0 through 31, so r, g, and b each need to be converted to some number between 0 and 31, and since they are originally a byte each (0-255), we multiply each by 31/255. Here is a function that takes RGBA bytes as input and outputs RGBA5551 as a short:
short int RGBA8888_to_RGBA5551(unsigned char r, unsigned char g, unsigned char b, unsigned char a){
unsigned char r5 = r*31/255; // All arithmetic is integer arithmetic, and so floating points are truncated. If you want to round to the nearest integer, adjust this code accordingly.
unsigned char g5 = g*31/255;
unsigned char b5 = b*31/255;
unsigned char a1 = (a > 0) ? 1 : 0; // 1 if a is positive, 0 else. You must decide what is sensible.
// Now that we have our 5 bit r, g, and b and our 1 bit a, we need to shift them into place before combining.
short int rShift = (short int)r5 << 11; // (short int)r5 looks like 00000000000vwxyz - 11 zeroes. I'm not sure if you need (short int), but I've wasted time tracking down bugs where I didn't typecast properly before shifting.
short int gShift = (short int)g5 << 6;
short int bShift = (short int)b5 << 1;
// Combine and return
return rShift | gShift | bShift | a1;
}
You can, of course condense this code.
I'm working in C on a PC, trying to leverage as little C++ as possible, working with binary data stored in unsigned char format, although other formats are certainly possible if worthwhile. The goal is subtracting two signed integer values (which can be ints, signed ints, longs, signed longs, signed shorts, etc.) in binary without converting to other data formats. The raw data is just prepackaged as unsigned char, though, with the user basically knowing which of the signed integer formats should be used for reading (i.e. we know how many bytes to read at once). Even though data is stored as an unsigned char array, data are meant to be read signed as two's-complement integers.
One common way we're often taught in school is adding the negative. Negation, in turn, is often taught to be performed as flipping bits and adding 1 (0x1), resulting in two additions (perhaps a bad thing?); or, as other posts point out, flipping bits past the first zero starting from the MSB. I'm wondering if there is a more efficient way, that may not be easily described as a pen-and-paper operation, but works because of the way data is stored in bit format. Here are some prototypes I've written, which may not be the most efficient way, but which summarizes my progress so far based on textbook methodology.
The addends are passed by reference in case I have to manually extend them to balance their length. Any and all feedback will be appreciated! Thanks in advance for considering.
void SubtractByte(unsigned char* & a, unsigned int & aBytes,
unsigned char* & b, unsigned int & bBytes,
unsigned char* & diff, unsigned int & nBytes)
{
NegateByte(b, bBytes);
// a - b == a + (-b)
AddByte(a, aBytes, b, bBytes, diff, nBytes);
// Restore b to its original state so input remains intact
NegateByte(b, bBytes);
}
void AddByte(unsigned char* & a, unsigned int & aBytes,
unsigned char* & b, unsigned int & bBytes,
unsigned char* & sum, unsigned int & nBytes)
{
// Ensure that both of our addends have the same length in memory:
BalanceNumBytes(a, aBytes, b, bBytes, nBytes);
bool aSign = !((a[aBytes-1] >> 7) & 0x1);
bool bSign = !((b[bBytes-1] >> 7) & 0x1);
// Add bit-by-bit to keep track of carry bit:
unsigned int nBits = nBytes * BITS_PER_BYTE;
unsigned char carry = 0x0;
unsigned char result = 0x0;
unsigned char a1, b1;
// init sum
for (unsigned int j = 0; j < nBytes; ++j) {
for (unsigned int i = 0; i < BITS_PER_BYTE; ++i) {
a1 = ((a[j] >> i) & 0x1);
b1 = ((b[j] >> i) & 0x1);
AddBit(&a1, &b1, &carry, &result);
SetBit(sum, j, i, result==0x1);
}
}
// MSB and carry determine if we need to extend:
if (((aSign && bSign) && (carry != 0x0 || result != 0x0)) ||
((!aSign && !bSign) && (result == 0x0))) {
++nBytes;
sum = (unsigned char*)realloc(sum, nBytes);
sum[nBytes-1] = (carry == 0x0 ? 0x0 : 0xFF); //init
}
}
void FlipByte (unsigned char* n, unsigned int nBytes)
{
for (unsigned int i = 0; i < nBytes; ++i) {
n[i] = ~n[i];
}
}
void NegateByte (unsigned char* n, unsigned int nBytes)
{
// Flip each bit:
FlipByte(n, nBytes);
unsigned char* one = (unsigned char*)malloc(nBytes);
unsigned char* orig = (unsigned char*)malloc(nBytes);
one[0] = 0x1;
orig[0] = n[0];
for (unsigned int i = 1; i < nBytes; ++i) {
one[i] = 0x0;
orig[i] = n[i];
}
// Add binary representation of 1
AddByte(orig, nBytes, one, nBytes, n, nBytes);
free(one);
free(orig);
}
void AddBit(unsigned char* a, unsigned char* b, unsigned char* c,
unsigned char* result) {
*result = ((*a + *b + *c) & 0x1);
*c = (((*a + *b + *c) >> 1) & 0x1);
}
void SetBit(unsigned char* bytes, unsigned int byte, unsigned int bit,
bool val)
{
// shift desired bit into LSB position, and AND with 00000001
if (val) {
// OR with 00001000
bytes[byte] |= (0x01 << bit);
}
else{ // (!val), meaning we want to set to 0
// AND with 11110111
bytes[byte] &= ~(0x01 << bit);
}
}
void BalanceNumBytes (unsigned char* & a, unsigned int & aBytes,
unsigned char* & b, unsigned int & bBytes,
unsigned int & nBytes)
{
if (aBytes > bBytes) {
nBytes = aBytes;
b = (unsigned char*)realloc(b, nBytes);
bBytes = nBytes;
b[nBytes-1] = ((b[0] >> 7) & 0x1) ? 0xFF : 0x00;
} else if (bBytes > aBytes) {
nBytes = bBytes;
a = (unsigned char*)realloc(a, nBytes);
aBytes = nBytes;
a[nBytes-1] = ((a[0] >> 7) & 0x1) ? 0xFF : 0x00;
} else {
nBytes = aBytes;
}
}
The first thing to notice is that signed vs. unsigned doesn't matter to the generated bit pattern in two's complement. All that changes is the interpretation of the result.
The second thing to notice is that an addition has carried if the result is less than either input when done with unsigned arithmetic.
void AddByte(unsigned char* & a, unsigned int & aBytes,
unsigned char* & b, unsigned int & bBytes,
unsigned char* & sum, unsigned int & nBytes)
{
// Ensure that both of our addends have the same length in memory:
BalanceNumBytes(a, aBytes, b, bBytes, nBytes);
unsigned char carry = 0;
for (int j = 0; j < nbytes; ++j) { // need to reverse the loop for big-endian
result[j] = a[j] + b[j];
unsigned char newcarry = (result[j] < a[j] || (unsigned char)(result[j]+carry) < a[j]);
result[j] += carry;
carry = newcarry;
}
}
i have an unsigned char test_SHA1[20] of 20 bytes which is a return value from a hash function. With the following code, I get this output
unsigned char test_SHA1[20];
char hex_output[41];
for(int di = 0; di < 20; di++)
{
sprintf(hex_output + di*2, "%02x", test_SHA1[di]);
}
printf("SHA1 = %s\n", hex_output);
50b9e78177f37e3c747f67abcc8af36a44f218f5
The last 9 bits of this number is 0x0f5 (= 245 in decimal) which I would get by taking a mod 512 of test_SHA1. To take mod 512 of test_SHA1, I do
int x = (unsigned int)test_SHA1 % 512;
printf("x = %d\n", x);
But x turns out to be 158 instead of 245.
I suggest doing a bit-wise and with 0x1ff instead of using the % operator.