In my search for an example of a software phase lock loop I came across the following question
Software Phase Locked Loop example code needed
In the answer by Adam Davis a site is given that is broken and I have tried the new link that is given in a comment but I cant get that to work either.
The answer from Kragen Javier Sitaker gave the following code as a simple example of a software phase locked loop.
main(a,b){for(;;)a+=((b+=16+a/1024)&256?1:-1)*getchar()-a/512,putchar(b);}
Also included in his answer was a link to what should be a much more readable example but this link is also broken. Thus I have been trying to translate the above code into simpler and more readable code.
I have come this far:
main(a,b){
for(;;){
// here I need to break up the code somehow into a if() statement('s).
if(here I get lost){
a = a+1;
if(here i get lost some more){
b = b+1;
}
}
}
Thanks to the SO question What does y -= m < 3 mean?
I know it is possible to break up the a+= and b+= into if statements.
But the (&256? 1 : -1)*getchar()-a/512,putchar(b); part in the code is killing me. I have been looking on Google and on SO to the meaning of the symbols and functions that are used.
I know the & sign indicates an address in memory.
I know that the : sign declares a bit field OR can be used in combination with the ? sign which is a conditional operator. The combination of the two I can use like sirgeorge answer in what does the colon do in c?
Theory Behind getchar() and putchar() Functions
I know that getchar() reads one character
I know that putchar() displays the character
But the combination of all these in the example code is not readable for me and . I can not make it readable for my self even do I know what they all separately do.
So my question: How do I read this software phase lock loop code?
main(a,b){for(;;)a+=((b+=16+a/1024)&256?1:-1)*getchar()-a/512,putchar(b);}
What I get is:
main (a, b)
{
char c;
for (;;)
{
c = getchar();
b = (b + 16 + (a / 1024));
if(!(b & 256))
{
c = c * -1;
}
a = a + c - (a/512);
putchar(b);
}
}
I had to add a c variable to not get lost.
What the program does:
Take a and b.
Infinite loop:
get a char input in c
calculate b
If (b bitwise AND 256)
c = -c
Calculate a
Print b
It seems it translate input into something else, I have to see the code in action to understand better myself.
Hope it helped!
Hint:
https://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B
a+= => a = a +
a?b:c => if(a){return b;} else {return c;} (As a function itself, it don t truly return)
Add parentheses, it help.
a & b is bitwise AND:
a/b |0|1|
0|0|0|
1|0|1|
Related
What is the "hanging else" problem? (Is that the right name?)
Following a C++ coding standard (forgot which one) I always
use brackets (block) with control structures. So I don't
normally have this problem (to which "if" does the last(?)
else belong), but for understanding possible problems in
foreign code it would be nice with a firm understanding of
this problem. I remember reading about it in a book about
Pascal many years ago, but I can't find that book.
Ambiguous else.
Some info here: http://theory.stanford.edu/~amitp/yapps/yapps-doc/node3.html
But the classic example is:
if a then
if b then
x = 1;
else
y = 1;
vs.
if a then
if b then
x = 1;
else
y = 1;
Which if does the else belong to?
if (a < b)
if (c < d)
a = b + d;
else
b = a + c;
(Obviously you should ignore the indentation.)
That's the "hanging else problem".
C/C++ gets rid of the ambiguity by having a rule that says you can't have an-if-without-an-else as the if-body of an-if-with-an-else.
Looking at this from a langauge design point of view.
The standard BNF-like grammar for if-else:
Statement :- .. STUFF..
| IfStatement
IfStatement :- IF_TOKEN '(' BoolExpression ')' Statement IfElseOpt
IfElseOpt :- /* Empty */
| ELSE_TOKEN Statement
Now from a parsers point of view:
if (cond1) Statement1
if (cond2) Statement2
else Statement3
When you get to the ELSE_TOKEN the parser has two options, SHIFT or REDUCE. The problem is that which to choose requires another rule that the parser must follow. Most parsers generators default to SHIFT when given this option.
I don't see the problem for Pascal?
This one is incorrectly indented.
if a then
if b then
x = 1;
else
y = 1;
Removing the semi-colon from after x = 1 would make it correctly indented.
This one correctly indented
if a then
if b then
x = 1;
else
y = 1;
From this answer, I saw this:
unsigned long
hash(unsigned char *str)
{
unsigned long hash = 5381;
int c;
while (c = *str++)
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
return hash;
}
The problem is that I don't see how the while stops from executing. Generally an assignment isn't resulted in true? I mean if(a = 5) will be true.
Also the compiler gave me this warning:
warning: suggest parentheses around assignment used as truth value [-Wparentheses]
Can anyone step me trough on what exactly goes on with the loop? I would strongly suggests that an example would be the best approach here.
Also where should the parentheses go to make this more clear?
The value of an assignment is the value that gets assigned. For example, this code:
int a;
printf("%d\n", a=5);
… will print out 5.
So, this loop runs until c is assigned something false.
And in C, 0 is false, and strings are null-terminated, so at the end of the string, the NUL character, 0, will end the loop.
The warning is because if (a = 5) is a typo for if (a == 5) more often than it's intentional code. Putting extra parentheses around an assignment, like if ((a == 5)), is an idiomatic way to say "I meant to use the value of this assignment". With some compilers, you may get a different, stronger warning in the case where the value is constant, as in my example, than in examples like yours, but the issue is the same: if you meant to test the value of an assignment, and you don't want to disable the warning globally, the way to convince GCC to leave you along is with extra parentheses: while ((c = *str++)).
See this question for more details. You may also want to search the GCC mailing lists for threads like this one discussing the warning.
I have learnt that using getchar_unlocked is fast way of reading input. I have seen the code to read at many places but was unable to understand. Can anyone please help me understand how to read using getchar_unlocked ?
Thanks in Advance.
void scanint(int &x)
{
register int c = getchar_unlocked();
x = 0;
for(;(c<48 || c>57);c = getchar_unlocked())
;
for(;c>47 && c<58;c = getchar_unlocked())
{
x = (x<<1) + (x<<3) + c - 48;
}
}
I have seen many other codes as well. I dont particularly understand the purpose of shifting the number. Any help regarding that is appreciated
getch_lock reads a character at a time. here in the given code we are trying to read an integer. the purpose of first for loop is to read digit character if any present and neglect it. The second for loop reads a char which must be digit and performs
n=n*10+c
As C is in Ascii we have subtracted 48 ie Ascii code of '0' . To make code faster instead of using multiplication shift is used.
n*10=n*(8+2)=n*8+n*2=n<<3+n<<1
getchar_unlocked() is like getchar() except that it does not check for multi-thread locks.
So, it is faster, but it is not thread-safe.
I think you might have the wrong idea of the purpose of getchar_unlocked(). Really.
When doing single-character I/O from a human user, it's fantastically hard to believe that you need to focus on being "fast", since the human will be very slow.
The function you included looks like it's reading an integer using getchar_fast(), and is written in a pretty horrible style. It certainly doesn't look like part of a solution to anything in particular. It's also totally broken in its handling of the x pointer variable.
In short, your question is not very clear.
I am trying to modify a value in an array using the C programming language and I seem to be hitting a blank wall with this seemingly easy operation. Please see code snippet below:
while(1) {
printf("Current prime candidate is %i\n",nextPrimeCandidate);
int innerSieve;//=2;
int currentPrimeCandidate=0;
for (innerSieve=2;innerSieve<SIEVELIMIT;innerSieve++) {
currentPrimeCandidate = nextPrimeCandidate * innerSieve;
//printf("Inner Sieve is b4 funny place %i,%i\n",innerSieve,currentPrimeCandidate);
//initArray[currentPrimeCandidate]=5;
//VERY UNIQUE LINE
myArray[currentPrimeCandidate] = 0;
//printf("Inner Sieve after funny place is %i,%i \n",innerSieve,currentPrimeCandidate);
}
nextPrimeCandidate=getNextPrimeCandidate(myArray,++nextPrimeCandidate);
if ((nextPrimeCandidate^2) > SIEVELIMIT ) break;
}
The problem is with the line highlighted with the VERY UNIQUE LINE comment. For some reason, when the innerSieve variable reaches 33 and gets to that line, it sets the contents of the innerSieve variable to the value of that line ( which currently is 0) and basically forces the loop into an infinite loop( the SIEVELIMIT variable is set at 50). It seems that there is some funny stuff going on in the registers when I checked using the Eclipse Debug facility but I am not too sure what I should be looking for.
If you need the whole code listing, this can be provided.( with a particular variable which is not yet initialised in the code being initialised at the precise point that the innerSieve variable hits 32)
Any help will be greatly appreciated.
Guessing that currentPrimeCandidate is greater than the maximum index of myArray, and you're overwriting innerSieve (which likely follows myArray on the stack).
#ruslik hit on it in the comment. The problem is this line:
if ((nextPrimeCandidate^2) > SIEVELIMIT ) break;
In C, the ^ operator is not the power operator, it is the bitwise xor operator. You're iterating far too many times than you intend, which is resulting in an array-index-out-of-bounds error, so you're overwriting random memory and getting strange results.
There is no power operator in C (though there is the pow function). Since you're just squaring a number, the simplest fix is to multiply the number by itself:
if ((nextPrimeCandidate * nextPrimeCandidate) > SIEVELIMIT ) break;
What is the meaning of == and how does it differ from =?
How do I know which one to use?
== is a test for equality. = is an assignment.
Any good C book should cover this (fairly early on in the book I would imagine).
For example:
int i = 3; // sets i to 3.
if (i == 3) printf("i is 3\n"); // prints it.
Just watch out for the heinous:
if (i = 4) { }
which is valid C and frequently catches people out. This actually assigns 4 to the variable i and uses that as the truth value in the if statement. This leads a lot of people to use the uglier but safer:
if (4 == i) {}
which, if you accidentally use = instead of ==, is a compile-time error rather than something that will bite you on the backside while your program is running :-)
The logical-or operator is two vertical bar characters, one after the other, not a single character. Here it is lined up with a logical-and, and a variable called b4:
||
&&
b4
No magic there.
a == b is a test if a and b are equal.
a = b is called an assignment, which means to set the variable a to having the same value as b.
(You type | with Shift-\ in the US keyboard layout.)
== tests equality
= assigns a value
neither are related to ||
I might add that in Finnish and Swedish keyboards. Pipe symbol; |; of OR is AltGr (the right alt) and < key. IF you are using Mac on the other hand it is Alt-7 key.
Gave me a lot of sweat when I first started typing on these keyboards.
Now that you know the difference between '==' and '=", let me put you some words of caution. Although '==' is used as a standard test of equality between comparable variables and '=' used as an internally type-casted assignment, the following programming error is quiet common.
In the below example and similar codes, '=' is know as "Always true" conditional operator.
#include<stdio.h>
int main()
{
int i = 10, j = 20;
if ( i = j )
printf("Equal\n");
else
printf("NOT Equal\n");
return 0;
}
So, the word of caution is "Never use '=' in if statements, unless you have something evil in your mind."