This program declares an 8x8 character array and then uses a loop to store the following data into the array(one character per array element). Then it prints this array to the screen:
BRBRBRBR
RBRBRBRB
BRBRBRBR
RBRBRBRB
BRBRBRBR
RBRBRBRB
BRBRBRBR
RBRBRBRB
The program works fine. However, I am having trouble understanding the logic behind the if statement:
if((i+j) & 1)
I don't understand how if adding i + j 'and' 1 is true set array to 'R' else set it to 'B'. This might have a rather obvious answer, but I am new to C. Can someone help clarify why this program works with this logic? Thank You!
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i, j;
char letter[8][8];
for(i=0; i<8; i++) {
for(j=0; j<8; j++) {
//This if-statement
if ((i+j) & 1)
letter[i][j] = 'R';
else
letter[i][j] = 'B';
printf("%c" , letter[i][j]);
}
printf("\n");
}
return 0;
}
(i+j) & 1 will evaluate to true when i+j is odd and false when i+j is even.
The & in that expression is the bitwise AND operator, not the logical AND operator.
The code would be so much more readable if written as:
int is_odd(int n)
{
return ((n&1) == 1);
}
...
if ( is_odd(i+j) )
There's a pattern here - the last bit of the value is constantly flipped:
i = 0, j = 0 --> i + j = 0 --> 2'b00
i = 0, j = 1 --> i + j = 1 --> 2'b01
i = 0, j = 2 --> i + j = 2 --> 2'b10
...and so on
The & operator then does a bit-wise and operation on the bits of the value:
//this evaluates to false, and 'B' is printed
2'b00 & 1 == 2'b00 & 2'b01 == 2'b(0&0)(0&1) == 2'b00
//this evaluates to true, and 'R' is printed
2'b01 & 1 == 2'b01 & 2'b01 == 2'b(0&0)(1&1) == 2'b01
Related
for example, if I enter 12, I want to get 81 41 as the set bits in 12 are 1100
This is what I have for now, I do not think I am implementing the for loop correctly
#include <stdio.h>
void bin(unsigned n)
{
char list[6];
int x = 0, y = 1;
/* step 1 */
if (n > 1)
bin(n / 2);
/* step 2 */
list[x] = n % 2;
x++;
/*for(int i = 0; i < x; i++) {
printf("%d\n",list[i]);
}*/
for(int i = 0; i < 5; i++) {
if(list[i] == 1 && i == 5) {
printf("32%i",y);
}
if(list[i] == 1 && i == 4) {
printf("16%i",y);
}
if(list[i] == 1 && i == 3) {
printf("8%i",y);
}
if(list[i] == 1 && i == 2) {
printf("4%i",y);
}
if(list[i] == 1 && i == 1) {
printf("2%i",y);
}
if(list[i] == 1 && i == 0) {
printf("1%i",y);
}
}
}
I checked that I was correctly storing the bytes in the array, and it outputted correctly, but when I try to look for them one at a time in a loop, it seems to get stuck on the 32 bit integer, so for 12, it would print 321 321
This program has Undefined Behaviour from accessing uninitialized values of list. I'm going to refactor this code so its easier to talk about, but know this refactored code is still incorrect.
x is always 0. y is always 1. x++ has no effect. This function can be rewritten as:
void bin(unsigned n)
{
char list[6];
if (n > 1)
bin(n / 2);
list[0] = n % 2;
for (int i = 0; i < 5; i++) {
if (list[i] == 1) {
switch (i) {
case 5: printf("321"); break;
case 4: printf("161"); break;
case 3: printf("81"); break;
case 2: printf("41"); break;
case 1: printf("21"); break;
case 0: printf("11"); break;
}
}
}
}
There are some problems here.
Firstly, list is not shared between calls to bin, nor are any other variables.
In every call to bin, only list[0] is assigned a value - all others indices contain uninitialized values. You are (un)lucky in that these values are seemingly never 1.
With your example of 12 as the starting value:
When you initially call bin(12), what happens is:
bin(12) calls bin(6), bin(6) calls bin(3), bin(3) calls bin(1).
Starting from the end and working backwards, in bin(1):
n = 1, so list[0] = n % 2; assigns 1. The loop checks each element of list for the value 1, finds it when the index (i) equals 0, and prints 11.
This is repeated in bin(3), as 3 % 2 is also 1, and again this result is assigned to the first element of list. Again, we print 11.
In bin(6), 6 % 2 is 0. The loop finds no elements of list that equal 1. Nothing is printed.
And again, this is repeated in bin(12), as 12 % 2 is 0. Nothing is printed.
To reiterate, it is pure luck that this program appears to work. Accessing list[1] through list[4] (i < 5 ensures you never access the last element) in each function call is Undefined Behaviour. It is generally not worth reasoning about a program once UB has been invoked.
When dealing with bits, it would be a good time to use some bitwise operators.
Here is a program that more-or-less does what you have described.
It assumes 32-bit unsigned (consider using fixed width types from <stdint.h> to be more precise).
This program works by repeatedly shifting the bits of our initial value to the right b number of places and testing if the rightmost bit is set.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
unsigned num = argc > 1 ? atoi(argv[1]) : 42;
unsigned b = 32;
while (b--)
if ((num >> b) & 1)
printf("%u1 ", 1 << b);
putchar('\n');
}
$ ./a.out 12
81 41
so i was working on the school 42 subjects on my own, and i dont fully understand the code here.
I understand that this part is used to print the result on the screen
void ft_putchar(char c)
{
write(1, &c, 1);
}
and that the following part is the setup of the limit and the incrementation, but i have my first question here :
Why does i starts at '-1' ?
My second question is concerning the division and modulus part, i dont understand much here, for example,how do the '-1' from the beginning becomes "00 01" ?
For the last part if i understand correctly it just adds a ',' and ' ' evrywhere to separate the combinaisons except at the very end.
#include <unistd.h>
void ft_putchar(char c)
{
write(1, &c, 1);
}
void ft_print_comb2(void)
{
int i;
int j;
i = -1 ;
while (++i <= 98)
{
j = i;
while (++j <= 99)
{
ft_putchar((char)(i/10) + '0');
ft_putchar((char)(i%10) + '0');
ft_putchar(' ');
ft_putchar((char)(j/10) + '0');
ft_putchar((char)(j%10) + '0');
if ( (i != 98))
{
ft_putchar(',');
ft_putchar(' ');
}
}
}
}
int main()
{
ft_print_comb2();
return(0);
}
ft_print_comb2 C00
Why does i starts at '-1' ?
Because its incremented before the evaluation of the loop
while (++i <= 98)
how do the '-1' from the beginning becomes "00 01" ?
i = -1 ;
while (++i <= 98) // i is 0 now
{
j = i; //j is equal to i (==0)
while (++j <= 99) // j is 1 now
about the division you are saying that the first char (who is going to be < 98) is the second digit so you divide it by 10 to get it. And since you are working with ints the fraction gets cut off.
Ex:
i = 25
i/10 => 2.5 => 2
And % modulus does the same but for the 1st digit
i=49
i%10 => remainder of 49/10 => 9
Then you do (char) to convert from int to char although it's redundant since you have the + '0' there
I hope you passed the piscine!
So I'm trying to create a program where the user enters a 12-bit binary hamming code sequence like "100010010001" and it should print out its corresponding ASCII character, which in this case is 'A'.
I'm trying to get my program to ignore the 4 parity bits which are positioned in _ _ 0 _ 1 0 0 _ 0 0 0 1 and shift the other 8 bits over so they're together. In the else statement, I tried to convert the remaining 8 bits to a character. When I attempt to run the program however, the program crashes after I type my binary sequence and press enter. This is the part of the program that I'm struggling with and I was wondering if someone could help me or give me hints as to what I'm doing wrong?
char charToBin(char usersInput[]) {
char c = " ";
for (int i = 12; i >= 0; i--) {
if((i == 0) || (i == 1) || (i == 3) || (i == 7)){
usersInput[i] = usersInput[i + 1];
}else{
c = strtol(usersInput[i], (char **)NULL, 2);
}
}
return c;
}
For your code, you can't use "strtol" without a twist. The char array that you give to "strtol" may not end with "\0". Also, does not matter what you do your array will always have 12 indexes unless you copy a "\0" to index 9 so that "strtol" know that it is the end of the input.
Also, sometimes loops are not the best. For your case, you already know how many indexes you are working with. There is no point in using a loop. Nonetheless, I wrote two methods and included the test code as an example below.
#include <stdio.h>
/*
* This function generate a hammer binary digit string for testing.
* It does not care about the validity of the hammer bit.
* The array that is passed to this function should be the length of 12.
*/
void generateChar(int value, char * output){
output[0] = '0';
output[1] = '0';
output[3] = '0';
output[7] = '0';
output[2] = (value & 0b10000000) > 0? '1' : '0';
output[4] = (value & 0b01000000) > 0? '1' : '0';
output[5] = (value & 0b00100000) > 0? '1' : '0';
output[6] = (value & 0b00010000) > 0? '1' : '0';
output[8] = (value & 0b00001000) > 0? '1' : '0';
output[9] = (value & 0b00000100) > 0? '1' : '0';
output[10] = (value & 0b00000010) > 0? '1' : '0';
output[11] = (value & 0b00000001) > 0? '1' : '0';
}
/*
* First method.
*
*/
char charToBin(char usersInput[]) {
char c = 0;
c = usersInput[2] == '1'? c | 0b10000000 : c;
c = usersInput[4] == '1'? c | 0b01000000 : c;
c = usersInput[5] == '1'? c | 0b00100000 : c;
c = usersInput[6] == '1'? c | 0b00010000 : c;
c = usersInput[8] == '1'? c | 0b00001000 : c;
c = usersInput[9] == '1'? c | 0b00000100 : c;
c = usersInput[10] == '1'? c | 0b00000010 : c;
c = usersInput[11] == '1'? c | 0b00000001 : c;
return c;
}
/*
* Second method.
*/
char charToBin2(char usersInput[]) {
char temp[9];
int pos = 0;
temp[8] = '\0'; // Protect from overflow.
for ( int i = 2; i < 12; i++ ){
if ( i == 3 || i == 7 ) continue;
temp[pos] = usersInput[i];
pos++;
}
return (char) strtol(temp, (char **)NULL, 2);
}
int main(){
char a[] = "100010010001";
char t[12];
int b;
// Test for method 1
for ( int i = 0; i < 256; i++ ){
generateChar(i, t);
b = charToBin(t);
printf("%d ", (unsigned char) b );
}
printf("\n\n");
// Test for method 2
for ( int i = 0; i < 256; i++ ){
generateChar(i, t);
b = charToBin2(t);
printf("%d ", (unsigned char) b );
}
return 0;
}
if((i == 0) || (i == 1) || (i == 3) || (i == 7)){
usersInput[i] = usersInput[i + 1];
}else{
In here your if (condition), the curly bracket after that is not necessary.
if((i == 0) || (i == 1) || (i == 3) || (i == 7))
usersInput[i] = usersInput[i + 1];
else{
that would fix a bit maybe
You program has two compile error:
You can not assign string to character ( c= " ") ;
The strtol call takes a string, not a character
After fixing the compile error, two fixes are needed to logic:
1. Perform the filtering of the input string from left to right, to avoid copying position 12 to 11, 11 to 10, which will result in duplicating the last positions. An extra counter is needed to help with the compaction.
2. Perform the strtol once, after the input is fully compacted.
char charToBin(char usersInput[]) {
char j = 0 ;
// Copy relevant input positions, INCLUDING terminating NUL byte at position 12.
for (int i = 0; i <= 12 ; i++) {
if((i == 0) || (i == 1) || (i == 3) || (i == 7)){
continue ;
} ;
usersInput[j] = usersInput[i] ;
j++ ;
} ;
char c = strtol(usersInput, (char **)NULL, 2);
return c;
}
Alternatively you could use bit operations. Something like:
char charToBin(char usersInput[]) {
unsigned c = strtol(usersInput, NULL, 2);
unsigned part1 = c & 0xFu;
unsigned part2 = c >> 1u & 0x70u;
unsigned part3 = c >> 2u & 0x80u;
return (char) (part1 | part2 | part3);
}
Which would give with your input of
char userInput[] = "100010010001";
char ch = charToBin(userInput);
printf("result: %c(%d)\n", ch, ch);
the following output on the console:
result: A(65)
I am fighting some simple question.
I want to get prime numbers
I will use this algorithm
and... I finished code writing like this.
int k = 0, x = 1, n, prim, lim = 1;
int p[100000];
int xCount=0, limCount=0, kCount=0;
p[0] = 2;
scanf("%d", &n);
start = clock();
do
{
x += 2; xCount++;
if (sqrt(p[lim]) <= x)
{
lim++; limCount++;
}
k = 2; prim = true;
while (prim && k<lim)
{
if (x % p[k] == 0)
prim = false;
k++; kCount++;
}
if (prim == true)
{
p[lim] = x;
printf("prime number : %d\n", p[lim]);
}
} while (k<n);
I want to check how much repeat this code (x+=2; lim++; k++;)
so I used xCount, limCount, kCount variables.
when input(n) is 10, the results are x : 14, lim : 9, k : 43. wrong answer.
answer is (14,3,13).
Did I write code not well?
tell me correct point plz...
If you want to adapt an algorithm to your needs, it's always a good idea to implement it verbatim first, especially if you have pseudocode that is detailed enough to allow for such a verbatim translation into C-code (even more so with Fortran but I digress)
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main (void){
// type index 1..n
int index;
// var
// x: integer
int x;
//i, k, lim: integer
int i, k, lim;
// prim: boolean
bool prim;
// p: array[index] of integer {p[i] = i'th prime number}
/*
We cannot do that directly, we need to know the value of "index" first
*/
int res;
res = scanf("%d", &index);
if(res != 1 || index < 1){
fprintf(stderr,"Only integral values >= 1, please. Thank you.\n");
return EXIT_FAILURE;
}
/*
The array from the pseudocode is a one-based array, take care
*/
int p[index + 1];
// initialize the whole array with distinguishable values in case of debugging
for(i = 0;i<index;i++){
p[i] = -i;
}
/*
Your variables
*/
int lim_count = 0, k_count = 0;
// begin
// p[1] = 2
p[1] = 2;
// write(2)
puts("2");
// x = 1
x = 1;
// lim = 1
lim = 1;
// for i:=2 to n do
for(i = 2;i < index; i++){
// repeat (until prim)
do {
// x = x + 2
x += 2;
// if(sqr(p[lim]) <= x) then
if(p[lim] * p[lim] <= x){
// lim = lim +1
lim++;
lim_count++;
}
// k = 2
k = 2;
// prim = true
prim = true;
// while (prim and (k < lim)) do
while (prim && (k < lim)){
// prim = "x is not divisible by p[k]"
if((x % p[k]) == 0){
prim = false;
}
// k = k + 1
k++;
k_count++;
}
// (repeat) until prim
} while(!prim);
// p[i] := x
p[i] = x;
// write(x)
printf("%d\n",x);
}
// end
printf("x = %d, lim_count = %d, k_count = %d \n",x,lim_count,k_count);
for(i = 0;i<index;i++){
printf("%d, ",p[i]);
}
putchar('\n');
return EXIT_SUCCESS;
}
It will print an index - 1 number of primes starting at 2.
You can easily change it now--for example: print only the primes up to index instead of index - 1 primes.
In your case the numbers for all six primes up to 13 gives
x = 13, lim_count = 2, k_count = 3
which is distinctly different from the result you want.
Your translation looks very sloppy.
for i:= 2 to n do begin
must translate to:
for (i=2; i<=n; i++)
repeat
....
until prim
must translate to:
do {
...
} while (!prim);
The while prim... loop is inside the repeat...until prim loop.
I leave it to you to apply this to your code and to check that all constructs have been properly translated. it doesn't look too difficult to do that correctly.
Note: it looks like the algorithm uses 1-based arrays whereas C uses 0-based arrays.
Can I please have some help understanding some bitwise and, and if shorthand? I put comments on what I thought it is.
//Bitwise AND not sure how it decides 32 or 0, then set board[i]
board[i] = (randNum & 1024) ? 32 : 0;
//it the j variable j in the neighborOffset array, then mods it by 2048
//then takes that variable from the board array, then shifts 1 to 32
//then bitwise and of those 2 variables.
if(board[(i + neighborOffset[j]) % 2048] & (1 << 5))
//Not sure about this one. Can someone please explain it?
board[i] |= ((board[i] ^ 34) && (board[i] ^ 35)) ? ( (board[i]^3) ? 0 : (1<<4)) : (1<<4);
//Not sure how it decides if it uses 'X' or ' '
putchar(board[i] ? 'X':' ');
-----------------------------------------------
I figured out this one.
putchar(board[i] ? 'X':' ');
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <stdlib.h>
//#include <dos.h>
int main()
{
int board[2048] = {0};
board[0] = 5;
board[1] = 9;
board[2] = 0;
board[3] = 2;
putchar(board[0] ? 'X':' ');
putchar(board[1] ? 'X':' ');
putchar(board[2] ? 'X':' ');
putchar(board[3] ? 'X':' ');
printf(" \n");
return (0);
}
Output
XX X
The reason on success putchar returns 1.
http://www.cplusplus.com/reference/cstdio/putchar/
Not sure about this one. Can someone please explain it?
board[i] |= ((board[i] ^ 34) && (board[i] ^ 35)) ? ( (board[i]^3) ? 0 : (1<<4)) : (1<<4);
Don't ask for a fish, ask how to catch fish. Instead of explaining this to you, let me teach you how to explain it to yourself.
I don't understand this crazy code any more than you do right now, so I'm going to write down the process that I would use to understand this code.
We begin to understand it by first reformatting it so that indentation gives us a clue:
board[i] |=
((board[i] ^ 34) && (board[i] ^ 35)) ?
((board[i]^3) ?
0 :
(1<<4)) :
(1<<4);
OK, that's not much better. Let's try to understand it by introducing two explanatory variables.
int original = board[i];
int result =
((original ^ 34) && (original ^ 35)) ?
((original ^ 3) ?
0 :
(1<<4)) :
(1<<4);
board[i] = original | result;
That's still not very clear. Let's try to undestand it by turning conditional expressions into conditional statements.
int original = board[i];
int result;
if ((original ^ 34) && (original ^ 35))
{
if (original ^ 3)
result = 0;
else
result = 1 << 4;
}
else
result = 1 << 4;
board[i] = original | result;
Still not very clear, but now we can notice that the structure of the "if" statements is bizarre: we have two possible results, and in one of them all three conditions must be met, so why do we have nested if statements at all? Rewrite.
int original = board[i];
int result;
if ((original ^ 34) && (original ^ 35) && (original ^ 3))
result = 0;
else
result = 1 << 4;
board[i] = original | result;
OK, we're getting a lot simpler now. Let's think about those three conditions. What does
(original ^ 34) && ...
mean? Well, the condition will be considered to be true if and only if the result is not zero, so let's introduce three more explanatory variables and make that clear.
int original = board[i];
int result;
int condition34 = (original ^ 34) != 0;
int condition35 = (original ^ 35) != 0;
int condition3 = (original ^ 3) != 0;
if (condition34 && condition35 && condition3)
result = 0;
else
result = 1 << 4;
board[i] = original | result;
OK, now let's ask ourselves "what does (x ^ y) != 0 even mean? Under what circumstances can this be false? Only if x^y is zero. Under what circumstances can x^y being zero be true? Only if x and y have all the same bits. Under what circumstances can x and y have all bits the same? Only if they are equal. So the condition is false if and only if the operands are equal, and therefore it is true if and only if they are unequal. So we can rewrite this as:
int original = board[i];
int result;
int condition34 = (original != 34);
int condition35 = (original != 35);
int condition3 = (original != 3);
if (condition34 && condition35 && condition3)
result = 0;
else
result = 1 << 4;
board[i] = original | result;
Now we are getting somewhere. Now let's look at the action on board[i]. If result is zero then original|result is a no-op. The only other possibility is that result is 16. So let's rewrite this again, this time to eliminate result:
int original = board[i];
int condition34 = (original != 34);
int condition35 = (original != 35);
int condition3 = (original != 3);
if (condition34 && condition35 && condition3)
{ /* do nothing */ }
else
board[i] = original | 16;
Now let's notice that we can invert the if and eliminate the "do nothing" case:
int original = board[i];
int condition34 = (original != 34);
int condition35 = (original != 35);
int condition3 = (original != 3);
if (!(condition34 && condition35 && condition3))
board[i] = original | 16;
Now we can use the fact that
!(a && b)
is the same thing as
!a || !b
So:
int original = board[i];
int condition34 = (original != 34);
int condition35 = (original != 35);
int condition3 = (original != 3);
if ((!condition34) || (!condition35) || (!condition3))
board[i] = original | 16;
But now we are inverting a not-equals, which seems silly. Turn them into equals and eliminate the inversion.
int original = board[i];
int condition34 = (original == 34);
int condition35 = (original == 35);
int condition3 = (original == 3);
if (condition34 || condition35 || condition3)
board[i] = original | 16;
Now let's eliminate the explanatory variables again:
if ((board[i] == 34) || (board[i] == 35) || (board[i] == 3))
board[i] |= 16;
And there you go. Now we have the program fragment in a form that can be understood. If the board position is 34, 35 or 3, then set the 16 bit, otherwise, do nothing.
I have no idea why someone would want to write the original program fragment when the way I've shown is so much more clear, but sometimes people write strange code.
This is what you do when you encounter code you can't make sense of: rewrite it into exactly equivalent code that you can make sense of. Simplifying complex expressions by extracting sub-expressions into explanatory variables is a great technique for that.
//Bitwise AND not sure how it decides 32 or 0, then set board[i]
board[i] = (randNum & 1024) ? 32 : 0;
The & operator is performing a bitwise AND operation
xxxxxxxxxxx
& 10000000000
--------------
?0000000000
The ? will be 1 if the number had a 1 in the 1024 location and will be 0 other wise.
Once this test is performed if the result was 1 then the anser 32 is returned, else 0 is returned. This if else conditional is performed using the ? ternary operator.
//Not sure how it decides if it uses 'X' or ' '
putchar(board[i] ? 'X':' ');
Here a similar test is being done with the ? ternary check. If the element at board[i] evaluates true then X else ' '