I'm trying to add two binary numbers together using only logical statements and binary arithmetic operators. But I'm confused on how to actually change the bits. It is mostly the out variable that I am trying to change, but it keeps getting zeroed every time I print it.
#include <stdio.h>
void execute_add(int a, int b){
int i = 0;
int bit;
int bit2;
int carryOut = 0;
int out = 10;
int overflow = 0;
for(i = 0; i <32 ; i++){
bit = (a >> i) & 1;
bit2 = (b >> i) & 1;
if(bit==1 && bit2==1 && carryOut == 0){
carryOut = 1;
out = 0 | (0x1 >> i);
}else if(bit==1 && bit2==1 && carryOut == 1){
carryOut = 1;
out = 1 | (0x1 >> i);
}else if(bit==0 && bit2==0 && carryOut == 0){
carryOut = 0;
out= 0 | (0x1 >> i);
}else if(bit==0 && bit2==0 && carryOut == 1){
carryOut = 0;
out = 1 | (0x1 >> i);
}else if(bit==1 && bit2==0 && carryOut == 0){
carryOut = 0;
out = 1 | (0x1 >> i);
}else if(bit==1 && bit2==0 && carryOut == 1){
carryOut = 1;
out = 0 | (0x1 >> i);
}else if(bit==0 && bit2==1 && carryOut == 0){
carryOut = 0;
out = 1 | (0x1 >> i);
}else if(bit==0 && bit2==1 && carryOut == 1){
carryOut = 1;
out = 0 | (0x1 >> i);
}else{
}//if else
}//for loop
printf("\n");
bit = (a >> 31) & 1;
bit2 = (a >> 31)& 1;
int bit3 = (out >> 31) & 1;
if( bit == 1 && bit2== 1 && bit3 == 0){
overflow = 1;
}else if (bit == 0 && bit2 == 0 && bit3 == 1){
overflow = 1;
}else{
}//overflow check
int j;
int g = 0;
for(j = 31; j>=0; j--){
if(g%4==0 && g!=0){
printf(" ");
}
bit2 = (out >> j) & 1;
printf("%d", bit2);
g++;
}
printf("\n");
}
int main (){
int a = 34;
int b = 17;
execute_add(a, b);
return 0;
}
With each of these statements in your for loop:
out = 0 | x;
You're resetting out, and clearing away all the work you've already done. You probably mean to do:
out = out | x
Or, equivalently,
out |= x
You also are right-shifting 1 all over the place, which is not what you're looking for; for any shift greater than zero, that's going to give you zero. I think you're often looking for a left-shift where you use a right shift.
I would second kaylum's comment about using a debugger; even if you flip the appropriate shifts and | with out properly, you're still going to have logic errors that will be easily fixed with a debugger.
Related
I have a C function to convert decimal to a hex string hexConversion:
int hexConversion(int num){
char hex_buffer[9];
unsigned int mask = 4026531840;
for(int i = 0; i < 9; i++){
int temp = mask & num;
if(temp < 10){
hex_buffer[i] = temp + '0';
}
else if(temp == 10){
hex_buffer[i] = 'A';
}
else if(temp == 11){
hex_buffer[i] = 'B';
}
else if(temp == 12){
hex_buffer[i] = 'C';
}
else if(temp == 13){
hex_buffer[i] = 'D';
}
else if(temp == 14){
hex_buffer[i] = 'E';
}
else if(temp == 15){
hex_buffer[i] = 'F';
}
mask >>= 4;
}
hex_buffer[8] = '\0';
for(int i = 0; i < sizeof(hex_buffer); i++){
printf("%c", hex_buffer[i]);
}
}
with driver code:
int main(){
hexConversion(2);
hexConversion(255);
hexConversion(-1);
hexConversion(INT_MAX);
hexConversion(INT_MIN);
hexConversion(0xDEADBEEF);
}
My output is:
00000002 0000000F 0000000F 0000000F 00000000 0000000F
Every output has the last value correct, but all the values before the last one are not evaluating. I believe this is because my temp = mask & num is not producing a value that is not 0-15. My question is, how do I consider only 4 bits at a time so that all of my temp values will be within this range?
The first remark looking at your code without considering the problem is why do you manage well the case 0..9 but you separate the case A and B ... and F rather than to do the same as you do for the digit ?
so
int hexConversion(int num){
char hex_buffer[9];
unsigned int mask = 4026531840;
for(int i = 0; i < 9; i++){
int temp = mask & num;
if(temp < 10){
hex_buffer[i] = temp + '0';
}
else if (temp < 16) {
hex_buffer[i] = temp - 10 + 'A';
}
else {
hex_buffer[i] = '?';
}
mask >>= 4;
}
hex_buffer[8] = '\0';
for(int i = 0; i < sizeof(hex_buffer); i++){
printf("%c", hex_buffer[i]);
}
}
I added the test if (temp < 16) normally useless if the code is the right one, but the result is :
Compilation and execution :
pi#raspberrypi:/tmp $ gcc -g -pedantic -Wextra h.c
h.c: In function ‘hexConversion’:
h.c:23:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for(int i = 0; i < sizeof(hex_buffer); i++){
^
pi#raspberrypi:/tmp $ ./a.out
00000002000000?F0??????F???????F000000000??????F
so in your solution you do not write on some indexes, because of the error in your code
One way to do is :
void hexConversion(int num){
char hex_buffer[9];
for(size_t i = 0; i < sizeof(hex_buffer) -1; i++){
int temp = (num >> (28-4*i)) & 0xf;
if(temp < 10){
hex_buffer[i] = temp + '0';
}
else {
hex_buffer[i] = temp - 10 + 'A';
}
}
hex_buffer[8] = 0;
puts(hex_buffer);
}
Compilation and execution :
pi#raspberrypi:/tmp $ gcc -g -pedantic -Wextra h.c
pi#raspberrypi:/tmp $ ./a.out
00000002
000000FF
FFFFFFFF
7FFFFFFF
80000000
DEADBEEF
Note your code suppose int on 32b, to be independent on the size (but supposing a char is on 8bits) :
void hexConversion(int num){
char hex_buffer[sizeof(int)*2 + 1];
for(size_t i = 0; i < sizeof(int)*2; i++){
int temp = (num >> (sizeof(int)*8-4-4*i)) & 0xf;
if(temp < 10){
hex_buffer[i] = temp + '0';
}
else {
hex_buffer[i] = temp - 10 + 'A';
}
}
hex_buffer[sizeof(int)*2] = 0;
puts(hex_buffer);
}
It depends on your system but if you want to extract nybbles out of your value
you can eventually apply 0xF (masks >> (4 * n)) over your values
For instance
if i got a binary data looking like this 0x4602 = 0100 0110 0000 0010
and i need to extract only the 1rst part of this one
i could use a 0xF000 = 1111 0000 0000 0000 with a & mask over this 0x4602
to get the first part of this value
This would give us
0xF000 = 1111 0000 0000 0000
&0x4602 = 0100 0110 0000 0010
result would be 0x4000 = 0100 0000 0000 0000
to get the nth part of this value you could drift the (0xF000) with the >> 4 n times
You need to run loop from 0-7 and also move the number after applying the mask to lower nibble.
for(int i = 0; i < 8; i++){
int temp = (mask & num) >> (28 -4*i);
I am trying to program a disease simulator in C. For some reason after around 20-25 iterations of the while(1) loop, it segfaults. It is completely random. I have been trying to fix this problem for several hours, so any help would be much appreciated.
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
typedef struct space {
int type;
int x, y;
} space_t;
space_t space[40][40];
int main(){
bool infected = false;
int i = 0;
int x = 0;
int y = 0;
srand(time(NULL));
while(i < 1600){
space[x][y].x = x;
space[x][y].y = y;
if(rand() % 9 == 0 && !infected){
space[x][y].type = 1;
infected = true;
}
if(rand() % 20 == 8){
space[x][y].type = 2;
}
x++;
i++;
if(x == 40){
x = 0;
y++;
}
}
system("clear");
int count;
int inf = 0;
while(1){
x = 0;
y = 0;
i = 0;
while(i < 1600){
if(space[x][y].type == 1){
inf++;
}
if(space[x][y].type == 1 && rand() % 9 > 4){
if(rand() % 9 > 4){
space[x+(rand() % 3)][y].type = 1;
} else {
space[x+(-(rand() % 3))][y].type = 1;
}
} else if(space[x][y].type == 1 && rand() & 9 > 4){
if(rand() % 9 > 4){
space[x][y+(rand() % 3)].type = 1;
} else {
space[x][y+(-(rand() % 3))].type = 1;
}
}
if(space[x][y].type == 1){
printf("[I]");
} else if(space[x][y].type == 2){
printf("[D]");
} else printf("[ ]");
x++;
i++;
if(x == 40){
printf("\n");
x = 0;
y++;
}
}
count++;
printf("%d\n", count);
printf("%d\n", inf);
sleep(1);
system("clear");
}
return 0;
}
Code generates random offsets for an index but does not insure in proper range.
if(space[x][y].type == 1 && rand() % 9 > 4){
if(rand() % 9 > 4){
// Nothing forces `x+(rand() % 3)` in legal index range.
space[x+(rand() % 3)][y].type = 1;
} else {
space[x+(-(rand() % 3))][y].type = 1;
}
}
Instead
if(space[x][y].type == 1 && rand() % 9 > 4) {
int r = rand();
if(r % 9 > 4) {
int offset = x + r%3;
if (offset < 40) space[offset][y].type = 1;
} else {
int offset = x - r%3;
if (offset >= 0) space[offset][y].type = 1;
}
}
... // similar change for next block
Note: later on code, certainly rand() & 9 should be rand() % 9 (% not &).
I have the following vars:
char seed[NBITS + 1], x0[NBITS + 1], y0[NBITS + 1], z0[NBITS + 1], dT0[NBITS + 1];
And i want to change it values on this function:
void lfsr(char *bin, char *output)
{
//bits significativos para fazer o xor NBITS -> NBITS,126,101,99;
int bits[4];
int bit;
if(bin[0] == '0')
bits[0] = 0;
else if(bin[0] == '1')
bits[0] = 1;
if(bin[2] == '0')
bits[1] = 0;
else if(bin[2] == '1')
bits[1] = 1;
if(bin[21] == '0')
bits[2] = 0;
else if(bin[21] == '1')
bits[2] = 1;
if(bin[19] == '0')
bits[3] = 0;
else if(bin[19] == '1')
bits[3] = 1;
bit = bits[0] ^ bits[1] ^ bits[2] ^ bits[3] ^ 1;
//reconstruir o vector de char depois do lfsr
for(int i = 127; i >= 1; i--)
{
bin[i] = bin[i - 1];
}
bin[0] = (char)(48 + bit);
output = bin;
}
The way that I put the value in y0 from x is, for example, calling the lfsr functions like this:
lfsr(x0, y0);
What am I doing wrong?
I have to do 3 Fibonacci Linear Feedback Shift Register starting from x0.
x0 = 10101010101010
y0 = lfsr(101010101010)
z0 = lfsr(y0)
dT0 = lfsr(z0);
The results are good, but when I do the above code the value of x0 will be the same as dT0 if i use pointers.
Can anyone help me?
Thanks. Cumps!
Consider the following:
The numbers correspond to the taps. The bits are actually 15..0, left to right. The following is my implementation of the Fibonacci Linear Feedback Shift Register:
#include <stdio.h>
uint16_t fibLfsr(const uint16_t num)
{
uint16_t tempNum;
tempNum = (num) ^ (num >> 2) ^ (num >> 3) ^ (num >> 5);
tempNum = (tempNum & 0x1) << 15;
tempNum = (tempNum | (num >> 1));
return tempNum;
}
int main(void)
{
uint16_t testNum = 0xACE1;
printf("%#X\n", testNum);
testNum = fibLfsr(testNum);
printf("%#X\n", testNum);
return 0;
}
I'm not quite sure why you're using strings and converting them to binary. If this is necessary, you'll need some of the standard library APIs in stdlib and string to convert the string to an uint16_t before calling fibLfsr() and back to a string afterwards.
Need some help in the last part of this function:
char *lfsr(char *bin)
{
//bits significativos para fazer o xor 128 -> 128,126,101,99;
int bits[4];
int bit;
if(bin[0] == '0')
bits[0] = 0;
else if(bin[0] == '1')
bits[0] = 1;
if(bin[2] == '0')
bits[1] = 0;
else if(bin[2] == '1')
bits[1] = 1;
if(bin[21] == '0')
bits[2] = 0;
else if(bin[21] == '1')
bits[2] = 1;
if(bin[19] == '0')
bits[3] = 0;
else if(bin[19] == '1')
bits[3] = 1;
bit = bits[0] ^ bits[1] ^ bits[2] ^ bits[3] ^ 1;
//reconstruir o vector de char depois do lfsr
for(int i = 127; i >= 1; i--)
{
bin[i] = bin[i - 1];
}
bin[0] = (int)bit;
return bin;
}
Why the value of bin[0] is a strange character instead 0 or 1?
Anyone can help me please?
Thanks in advance. Cumps!
The problem is character '0' and integer 0 being different. character '0' is actually the ascii value 48.
try bin[0] = (char)(48 + bit);
I'm a C language psychic and my crystal ball tells me that somewhere in your program you did this:
printf("the value in bit[0] is %c\n", bit[0]);
Well, probably one of your if-elses didn't work.
Either bin[0], bin[2], bin[21] or bin[19] is neither '0', nor '1'.
Try running this code with your test data:
char *lfsr(char *bin)
{
//bits significativos para fazer o xor 128 -> 128,126,101,99;
int bits[4];
int bit;
if(bin[0] == '0')
bits[0] = 0;
else
{
if(bin[0] == '1')
bits[0] = 1;
else
printf("First if-else failed. bin[0] : %c\n", bin[0]);
}
if(bin[2] == '0')
bits[1] = 0;
else
{
if(bin[2] == '1')
bits[1] = 1;
else
printf("Second if-else failed. bin[2] : %c\n", bin[2]);
}
if(bin[21] == '0')
bits[2] = 0;
else
{
if(bin[21] == '1')
bits[2] = 1;
else
printf("Third if-else failed. bin[21] : %c\n", bin[21]);
}
if(bin[19] == '0')
bits[3] = 0;
else
{
if(bin[19] == '1')
bits[3] = 1;
else
printf("Fourth if-else failed. bin[19] : %c\n", bin[19]);
}
bit = bits[0] ^ bits[1] ^ bits[2] ^ bits[3] ^ 1;
//reconstruir o vector de char depois do lfsr
for(int i = 127; i >= 1; i--)
{
bin[i] = bin[i - 1];
}
bin[0] = (int)bit;
return bin;
}
How do you
Read a 16 bit stereo raw audio file in binary mode
Convert it's values to integer for right and for left.
Save those integers back to a new 16 bit stereo raw audio file.
The final two files should be the same, with my code, they are not. Why?
My code:
char ergebnis[80];
sprintf(ergebnis,"%s.neu.raw",Datei);
FILE* ausgabe = fopen(ergebnis, "wb");
FILE* f = fopen(Datei, "rb");
if (f == NULL)
return;
int i = -1;
int r1 = 0;
int r2 = 0;
int l1 = 0;
int l2 = 0;
int l = 0;
int r = 0;
while((getc(f))!=EOF)
{
i++;
if (i == 0)
r1 = (unsigned)fgetc(f);
if (i == 1)
{
r2 = (unsigned)fgetc(f);
r = r1 | r2 << 8;
}
if (i == 2)
l1 = (unsigned)fgetc(f);
if (i == 3)
{
l2 = (unsigned)fgetc(f);
l = l1 | l2 << 8;
putc(r,ausgabe);
putc(l,ausgabe);
i = -1;
}
}
fclose(f);
fclose(ausgabe);
exit(-1);
EDIT: Solved it with
int wo = 0;
while(wo !=EOF)
{
wo = getc(f);
i++;
if (i == 0)
r1 = (unsigned)wo;
if (i == 1)
{
r2 = (unsigned)wo;
r = (r2<<8)+r1; //r1 | r2 << 8;
}
if (i == 2)
l1 = (unsigned)wo;
if (i == 3)
{
l2 = (unsigned)wo;
l = (l2<<8)+l1; //l1 | l2 << 8;
putc((char) ( r & 0xff),ausgabe);
putc((char) ((r >> 8) & 0xff),ausgabe);
putc((char) ( l & 0xff),ausgabe);
putc((char) ((l >> 8) & 0xff),ausgabe);
i = -1;
}
}
Getc in the while will skip one character.
Also if you have 16bit per channel instead of
putc(r,ausgabe);
putc(l,ausgabe);
do
putc((char) ( r & 0xff),ausgabe);
putc((char) ((r >> 8) & 0xff),ausgabe);
putc((char) ( l & 0xff),ausgabe);
putc((char) ((l >> 8) & 0xff),ausgabe);
Possibly you want a different endianness then just swaplines 1 and 2 and lines 3 and 4