First of all, I know the problem with the code and how to get it to work. I'm mainly looking for an explanation why my output is what it is.
The following piece of code replicates the behaviour:
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println("start");
for(int i = 0; i < 70000; i++) {
if((i % 2000) == 0)
Serial.println(i);
}
}
Obviously the for loop will run forever because i will overflow at 32,767. I would expect it to overflow and print -32000.
Expected| Actually printed
0 | 0
2000 | 2000
4000 | 4000
... | ...
30000 | 30000
32000 | 32000
-32000 | 33536
-30000 | 35536
It looks like it prints the actual iterations, since if you overflow and count to -32000 you would have 33536 iterations, but I can't figure out how it's able to print the 33536.
The same thing happens every 65536 iterations:
95536 | 161072 | 226608 | 292144 | 357680
97536 | 163072 | 228608 | 294144 | 359680
99072 | 164608 | 230144 | 295680 | 361216
101072 | 166608 | 232144 | 297680 | 363216
EDIT
When I change the loop to add 10.000 every iteration and only print every 1.000.000 to speed it up the Arduino crashes (or at least, the prints stop) at '2.147.000.000'. Which seems to point to the 32-bit idea of svtag**
EDIT2
The edits I made for the 2.147.000.000-check:
void loop() {
Serial.println("start");
for(int i = 0; i < 70000; i+=10000) {
if((i % 1000000) == 0)
Serial.println(i);
}
}
They work in the same trend with the previous example, printing 0, 1000000, 2000000,...
However, when I update the AVR package from 1.6.17 to the latest 1.6.23 I get only 0's. The original example (% 2000 & i++) still gives the same output.
The compiler may have automatically casted the i to usigned int when you are doing the println or the value is going to the wrong overload. Try using Serial.println((int)i);
Related
I was wondering how can I do it ,to print certain number of spaces using printf in C
I was thinking something like this,but also my code doesn't print after the first printf statement,my program compiles perfectly fine tho.I'm guessing I have to print N-1 spaces but I'm not quite sure how to do so.
Thanks.
#include <stdio.h>
#include <limits.h>
#include <math.h>
int f(int);
int main(void){
int i, t, funval,tempL,tempH;
int a;
// Make sure to change low and high when testing your program
int low=-3, high=11;
for (t=low; t<=high;t++){
printf("f(%2d)=%3d\n",t,f(t));
}
printf("\n");
if(low <0){
tempL = low;
tempL *=-1;
char nums[low+high+1];
for(a=low; a <sizeof(nums)/sizeof(int);a+5){
printf("%d",a);
}
}
else{
char nums[low+high];
for(a=low; a <sizeof(nums)/sizeof(int);a+5){
printf("%d",a);
}
}
// Your code here...
return 0;
}
int f(int t){
// example 1
return (t*t-4*t+5);
// example 2
// return (-t*t+4*t-1);
// example 3
// return (sin(t)*10);
// example 4
// if (t>0)
// return t*2;
// else
// return t*8;
}
the output should be something like this:
1 6 11 16 21 26 31
| | | | | | |
Printing n spaces
printf has a cool width specifier format that lets you pass an int to specify the width. If the number of spaces, n, is greater than zero:
printf("%*c", n, ' ');
should do the trick. It also occurs to me you could do this for n greater than or equal to zero with:
printf("%*s", n, "");
Printing 1, 6, 11, ... pattern
It's still not fully clear to me what you want, but to generate the exact pattern you described at the bottom of your post, you could do this:
for (i=1; i<=31; i+=5)
printf("%3d ", i);
printf("\n");
for (i=1; i<=31; i+=5)
printf(" | ");
printf("\n");
This outputs:
1 6 11 16 21 26 31
| | | | | | |
Had your objective been :
Start printing at a specified width using printf
You could achieve it like below :
printf("%*c\b",width,' ');
Add the above stuff before printing actual stuff, eg. before a for-loop.
Here the \b positions the cursor one point before the current position thereby making the output appear to start at a particular width, width in this case.
This C++11 program takes on average between 7.42s and 7.79s to run.
#include <iostream>
#include <chrono>
using namespace std;
using c = chrono::system_clock;
using s = chrono::duration<double>;
void func(){
int n=0;
const auto before = c::now();
for(int i=0; i<2000000000; i++){
n += i;
}
const s duration = c::now() - before;
cout << duration.count();
}
if I replace n += i with n += 2 * i * i it takes between 5.80s and 5.96s. how come?
I ran each version of the program 20 times, alternating between the two. Here are the results:
n += i | n += 2 * i * i
---------+----------------
7.77047 | 5.87978
7.69226 | 5.83551
7.77375 | 5.84888
7.73748 | 5.84629
7.72988 | 5.84356
7.69736 | 5.83784
7.72597 | 5.84246
7.72722 | 5.81678
7.73291 | 5.81237
7.71871 | 5.81016
7.7478 | 5.80119
7.64906 | 5.80058
7.7253 | 5.9078
7.42734 | 5.96399
7.72573 | 5.84733
7.65591 | 5.81793
7.76619 | 5.83116
7.76963 | 5.84424
7.79928 | 5.87078
7.79274 | 5.84689
I have compiled it with (GCC) 9.1.1 20190503 (Red Hat 9.1.1-1). No optimization levels
g++ -std=c++11
We know that the maximum integer is ~ 2 billion. So, when i ~ 32000, can we say that the compiler predicts that the calculation will overflow?
https://godbolt.org/z/B3zIsv
You'll notice that with -O2, the code used to calculate 'n' is removed completely. So the real questions should be:
Why are you profiling code without -O2?
Why are you profiling code that has no observable side effects? ('n' can be removed completely - e.g. printing the value of 'n' at the end would be more useful here)
Why are you not profiling code in a profiler?
The timing results you have, result from a deeply flawed methodology.
I'm trying to find a nice solution for following problem:
My input is a set of boolean variables b0 to bn and
a set of if statements calling some function in case the expression (conjunction of my boolean vars) is true.
For example:
void test(bool b0, bool b1, bool b2, bool b3, bool b4) {
if(b0&&b1) { action1(); }
if(b0&&b1&&b3) { action2(); }
if(b0&&b1&&b4) { action2(); }
if(b0&&b2) { action3(); }
}
Obviously this code could be optimized in order to minimize the number of comparisons.
For instance:
void test(bool b0, bool b1, bool b2, bool b3, bool b4) {
if(b0) {
if(b1) {
action1();
if(b3) { action2(); }
if(b4) { action2(); }
}
if(b2) { action3(); }
}
}
Is there an algorithm that solves/optimizes this problem (maybe even in an optimal way)?
It's obvious that it can be represented as a graph, table, etc. but somehow I still couldn't find a smart solution.
Update: I think I did not explain the problem well enough. Think about the problem as a truth table with multiple outputs. The inputs are the boolean variables and the outputs are the actions. So it is not just something that can be solved with KV map or Quine–McCluskey algorithm. Guess it is more complicated.
The table for the example above would be (I left out the "no output" cases):
b0| b1| b2| b3| b4 || action1 | action2 | action3
1 | 1 | 0 | 0 | 0 || 1 | 0 | 0
1 | 1 | 0 | 1 | 0 || 1 | 1 | 0
1 | 1 | 0 | 0 | 1 || 1 | 1 | 0
1 | 0 | 1 | 0 | 0 || 0 | 0 | 1
Don't optimise prematurely.
If you are thinking about such kind of optimizations you have to measure first. Make sure that this function is your hotspot in the production code. Thus,
Turn on the highest optimisation level (-O3)
Use a proper tool to locate hotspots, such as perf or Intel's vTune
Then if you find that this is your hotspot. Change it and measure again. You will be surprised in a lot of cases. It is quite possible, that the compiler will do this optimisation job for you.
Nevertheless, I think that the second version of your code can be read more fluently.
In general, if you need to deal with a bunch of boolean flags, merge them into a single uint32, which will allow you to test them fairly easily...
#include <cstdint>
enum Flags
{
kB0 = 1 << 0,
kB1 = 1 << 1,
kB2 = 1 << 2,
kB3 = 1 << 3,
kB4 = 1 << 4,
kB5 = 1 << 5,
};
inline bool testFlagsSet(uint32_t testFlags, uint32_t flags)
{
return (testFlags & flags) == testFlags;
}
void test(uint32_t flags) {
if(testFlagsSet(kB0 | kB1, flags)) { action1(); }
if(testFlagsSet(kB0 | kB1 | kB3, flags)) { action2(); }
if(testFlagsSet(kB0 | kB1 | kB4, flags)) { action3(); }
if(testFlagsSet(kB0 | kB2, flags)) { action4(); }
}
You can ch:ek the difference between the approaches here: https://godbolt.org/z/3P06fL
Also worth noting that of the original two methods you posted, the second one is better: https://godbolt.org/z/YTbYxh
I understand what you are asking. There are optimizing tools available to help to transform such code. But basically, it is not necessary.
And your new code is not better. It has even 5 if-statements. Performance wise, the compiler's optimizer will take care. It will detect the common subexpression and optimize that away.
This should also be basically done by the software developer / designer. A peer review will detect that code and fix the semantic problem.
You know of course that boolean expressions can be minimized via Quine&McCluskey or others. But I understand that this is not your question.
Static code analysis by Coverity / QAC / SonarCube can detect it, but will not fix it. This needs to be done manually.
Or you need to evaluate source code optimizers like PVS Studio
Please check.
I want to know the details about the execution of recursive functions.
#include<iostream>
int a=0;
int fac(int n) {
if (n <= 1)
return n;
int temp = fac(n-2) + fac(n - 1);
a++;
return temp;
}
int main() {
fac(4);
std::cout<<a;
}
The output is 4.
I want to know when int temp = fac(n-2) + fac(n - 1); is executed, for example fac(4-2)+fac(4-1) ---> fac(2)+fac(3), at this time, compiler will finish fac(2) first? or finish it together?
I'm not good at English, I hope that there is no obstacle to your reading.
Analysing this code purely in an algorithmic sense with no respect to C++ implementation intricacies,
fac(4)
fac(2) + fac(3)
|----------------------------|
fac(0) + fac(1) fac(1) + fac(2)
1 + 1 1 + fac(0) + fac(1)
+ 1 + 1
How can I create a trace which shows the call order where there is recursion?
First, I want to make note that the compiler output produced by the compiler will not match one-to-one with the code you write. The compiler applies different levels of optimization based on the flags provided to it with the highest level being -O3 and the default being -O0 but those seem out of scope of this question. Creating a trace influences this process itself as the compiler now needs to meet your expectations of what the trace looks like. The only true way to trace the actual execution flow is to read the assembly produced by the compiler.
Knowing that, we can apply a trace to see the call order by printing to screen when execution enters the called method. Note, I have removed a as it does not really trace anything and only adds to the complexity of the explanation.
int fac(int n) {
std::cout << "fac(" << n << ")" << std::endl;
if (n <= 1)
return n;
int temp = fac(n-2) + fac(n - 1);
return temp;
}
int main() {
fac(4);
}
// Output
fac(4)
fac(2)
fac(0)
fac(1)
fac(3)
fac(1)
fac(2)
fac(0)
fac(1)
As seen by this output on my PC, execution has proceeded from left to right depth first. We can number our call tree with this order to obtain a better picture,
// Call order
1. fac(4)
2. fac(2) + 5. fac(3)
|----------------------------|
3. fac(0) + 4. fac(1) 6. fac(1) + 7. fac(2)
+ 8. fac(0) + 9. fac(1)
Note: This does not mean that the results will be the same on every implementation nor does it mean that the order of execution is preserved when you remove the trace and allow compiler optimisations but it demonstrates how recursion works in computer programming.
First fac(2) will be finished and then fac(1). The output is 4.
The call stack would be like this (from bottom to top) -
|---fac(1)
|--- fac(2) |
|---- fac(3) | |---fac(0)
| |
| |----fac(1)
|
fac(4) |
|
| |---- fac(1)
|---- fac(2) |
|---- fac(0)
fac() function will be returned when n <= 1
while practicing recursive functions, I have written this code for fibonacci series and (factorial) the program does not run and shows the error "Control reaches end of non-void function" i suspect this is about the last iteration reaching zero and not knowing what to do into minus integers. I have tried return 0, return 1, but no good. any suggestions?
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <ctime>
using namespace std;
int fib(int n) {
int x;
if(n<=1) {
cout << "zero reached \n";
x= 1;
} else {
x= fib(n-1)+fib(n-2);
return x;
}
}
int factorial(int n){
int x;
if (n==0){
x=1;
}
else {
x=(n*factorial(n-1));
return x;
}
}
Change
else if (n==1)
x=1;
to
else if (n==1)
return 1;
Then fib() should work for all non-negative numbers. If you want to simplify it and have it work for all numbers, go with something like:
int fib(int n) {
if(n<=1) {
cout << "zero reached \n";
return 1;
} else {
return fib(n-1)+fib(n-2);
}
}
"Control reaches end of non-void function"
This is a compile-time warning (which can be treated as an error with appropriate compiler flags). It means that you have declared your function as non-void (in this case, int) and yet there is a path through your function for which there is no return (in this case if (n == 1)).
One of the reasons that some programmers prefer to have exactly one return statement per function, at the very last line of the function...
return x;
}
...is that it is easy to see that their functions return appropriately. This can also be achieved by keeping functions very short.
You should also check your logic in your factorial() implementation, you have infinite recursion therein.
Presumably the factorial function should be returning n * factorial(n-1) for n > 0.
x=(factorial(n)*factorial(n-1)) should read x = n * factorial(n-1)
In your second base case (n == 1), you never return x; or 'return 1;'
The else section of your factorial() function starts:
x=(factorial(n)*factorial(n-1));
This leads to infinite recursion. It should be:
x=(n*factorial(n-1));
Sometimes, your compiler is not able to deduce that your function actually has no missing return. In such cases, several solutions exist:
Assume
if (foo == 0) {
return bar;
} else {
return frob;
}
Restructure your code
if (foo == 0) {
return bar;
}
return frob;
This works good if you can interpret the if-statement as a kind of firewall or precondition.
abort()
(see David Rodríguez's comment.)
if (foo == 0) {
return bar;
} else {
return frob;
}
abort(); return -1; // unreachable
Return something else accordingly. The comment tells fellow programmers and yourself why this is there.
throw
#include <stdexcept>
if (foo == 0) {
return bar;
} else {
return frob;
}
throw std::runtime_error ("impossible");
Not a counter measure: Single Function Exit Point
Do not fall back to one-return-per-function a.k.a. single-function-exit-point as a workaround. This is obsolete in C++ because you almost never know where the function will exit:
void foo(int&);
int bar () {
int ret = -1;
foo (ret);
return ret;
}
Looks nice and looks like SFEP, but reverse engineering the 3rd party proprietary libfoo reveals:
void foo (int &) {
if (rand()%2) throw ":P";
}
Also, this can imply an unnecessary performance loss:
Frob bar ()
{
Frob ret;
if (...) ret = ...;
...
if (...) ret = ...;
else if (...) ret = ...;
return ret;
}
because:
class Frob { char c[1024]; }; // copy lots of data upon copy
And, every mutable variable increases the cyclomatic complexity of your code. It means more code and more state to test and verify, in turn means that you suck off more state from the maintainers brain, in turn means less maintainer's brain quality.
Last, not least: Some classes have no default construction and you would have to write really bogus code, if possible at all:
File mogrify() {
File f ("/dev/random"); // need bogus init
...
}
Do not do this.
There is nothing wrong with if-else statements. The C++ code applying them looks similar to other languages. In order to emphasize expressiveness of C++, one could write for factorial (as example):
int factorial(int n){return (n > 1) ? n * factorial(n - 1) : 1;}
This illustration, using "truly" C/C++ conditional operator ?:, and other suggestions above lack the production strength. It would be needed to take measures against overfilling the placeholder (int or unsigned int) for the result and with recursive solutions overfilling the calling stack. Clearly, that the maximum n for factorial can be computed in advance and serve for protection against "bad inputs". However, this could be done on other indirection levels controlling n coming to the function factorial. The version above returns 1 for any negative n. Using unsigned int would prevent dealing processing negative inputs. However, it would not prevent possible conversion situation created by a user. Thus, measures against negative inputs might be desirable too.
While the author is asking what is technically wrong with the recursive function computing the Fibonacci numbers, I would like to notice that the recursive function outlined above will solve the task in time exponentially growing with n. I do not want to discourage creating perfect C++ from it. However, it is known that the task can be computed faster. This is less important for small n. You would need to refresh the matrix multiplication knowledge in order to understand the explanation. Consider, evaluation of powers of the matrix:
power n = 1 | 1 1 |
| 1 0 | = M^1
power n = 2 | 1 1 | | 1 1 | | 2 1 |
| 1 0 | * | 1 0 | = | 1 1 | = M^2
power n = 3 | 2 1 | | 1 1 | | 3 2 |
| 1 1 | * | 1 0 | = | 2 1 | = M^3
power n = 4 | 3 2 | | 1 1 | | 5 3 |
| 2 1 | * | 1 0 | = | 3 2 | = M^4
Do you see that the matrix elements of the result resemble the Fibonacci numbers? Continue
power n = 5 | 5 3 | | 1 1 | | 8 5 |
| 3 2 | * | 1 0 | = | 5 3 | = M^5
Your guess is right (this is proved by mathematical induction, try or just use)
power n | 1 1 |^n | F(n + 1) F(n) |
| 1 0 | = M^n * | F(n) F(n - 1) |
When multiply the matrices, apply at least the so-called "exponentiation by squaring". Just to remind:
if n is odd (n % 2 != 0), then M * (M^2)^((n - 1) / 2)
M^n =
if n is even (n % 2 == 0), then (M^2)^(n/2)
Without this, your implementation will get the time properties of an iterative procedure (which is still better than exponential growth). Add your lovely C++ and it will give a decent result. However, since there is no a limit of perfectness, this also can be improved. Particularly, there is a so-called "fast doubling" for the Fibonacci numbers. This would have the same asymptotic properties but with a better time coefficient for the dependence on time. When one say O(N) or O(N^2) the actual constant coefficients will determine further differences. One O(N) can be still better than another O(n).