0

I'm trying to do a "1-liner" for fun purposes and for some reason i can't make the code work properly. Note: that's C, not C++, however the issue persists in both.

The "unfolded" version:

#include <stdio.h>
#include <math.h>

int main() {
    double iter = 1;
    double res = 0;
    double elem = 0;
    double fib_c = 1;
    double fib_p = 1;
    double power = 4;
    double fact = 1;

    while (iter < 15) {
        fib_c += fib_p; //fibonacci current
        fib_p = fib_c - fib_p; //fibonacci previous
        fact *= iter; //factorial
        power *= 4; //power of 4
        elem = (fib_c * power * sqrt(iter+1)) / fact; //element of series
        res += elem; //series

        printf("----\nelem = %2.3f\nres = %2.3f\n", elem, res);

        iter++;
    }

    return 0;
}

It's a series (i don't know the mathematical term for it in english) and here the element goes up from 45 to 1264 and then goes back down to 47.

Here's the "wrapped" version i'm trying to make work:

#include <stdio.h>
#include <math.h>

int main() {
    double iter = 1;
    double res = 0;
    double elem = 0;
    double fib_c = 1;
    double fib_p = 1;
    double power = 4;
    double fact = 1;

    while (iter < 15) {
        res += (elem = (fib_c += ((fib_p = fib_c - fib_p)) * (power*=4) * sqrt(iter+1)) / (fact*=iter));

        printf("----\nelem = %2.3f\nres = %2.3f\n", elem, res);

        iter++;
    }

    return 0;
}

Here the element goes beyond integer in less than 5 iterations. So obviously, something is wrong. But what?

By the way, if i print out each value (fib_c, power, fact) each iteration, i will see the correct values (current fibonacci number, power of 4, ongoing factorial, accordingly). So i made a guess that there is something weird happening "behind the scenes" and i don't know how to manage it.

Any ideas?

keke
  • 105
  • 2
  • 2
  • 14
  • 4
    Don't write code like that, it is unmaintainable and the side benefit is weird undefined behavior won't happen. A quick look says you are modifying `fib_c` and reading it within the same sequence point which is classical C undefined behavior. See [Why are these constructs (using ++) undefined behavior?](http://stackoverflow.com/q/949433/1708801). – Shafik Yaghmour Mar 17 '15 at 17:05
  • 1
    As i said, "for fun purposes". Nobody's going to maintain the code after me. – keke Mar 17 '15 at 17:08
  • @ohyou Undefined behavior is not fun, so Shafik's point stands ;) – Borgleader Mar 17 '15 at 17:20
  • @ShafikYaghmour I see no UB there under either version of the sequencing wording. – T.C. Mar 17 '15 at 17:34
  • @T.C. note I did use the term sequence point, so in C and pre C++11 reading other than to determine the new value and modifying the same variable within the same sequence point is UB. In C++11 and C11(*although C11 does retain the sequence point terminology and so either analysis should have the same result*) and as far as I can tell this is still UB in C++11. – Shafik Yaghmour Mar 17 '15 at 17:43
  • 1
    @ShafikYaghmour it *is* reading fib_c to determine the value to be stored into it. – T.C. Mar 17 '15 at 17:44
  • @T.C. yes but there is an assignment to `fib_p` that intervenes which I believe changes the analysis since `fib_c` has to be read to assign the value to that. – Shafik Yaghmour Mar 17 '15 at 19:29
  • 1
    @ShafikYaghmour How does that change the analysis? Both reads of `fib_c` (one from `+=` and one from `fib_p = fib_c - fib_p`) occur as part of the computation of the value to be assigned to `fib_c`. That the second read also occurs as part of the computation of the value to be assigned to `fib_p` doesn't change anything. – T.C. Mar 17 '15 at 19:33

1 Answers1

1
(fib_c += ((fib_p = fib_c - fib_p))

is not the same as

fib_c += fib_p; //fibonacci current
fib_p = fib_c - fib_p; //fibonacci previous

It is the same as

fib_p = fib_c - fib_p; //fibonacci previous
fib_c += fib_p; //fibonacci current
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Wow thanks for that, i missed that somehow. The correct line (in terms of algorithm) would be `(fib_p = (fib_c += fib_p) - fib_p)` if somebody is interested. – keke Mar 17 '15 at 17:20
  • "you are using fib_c on both sides of the += operator" are you seriously claiming that `i += i;` is UB? – T.C. Mar 17 '15 at 17:36
  • @T.C., no. I am claiming `i += (i + 10);` is UB. That's a hunch. I might be mistaken. – R Sahu Mar 17 '15 at 17:40
  • That expands into `i = i + (i + 10);`. How is that UB? – T.C. Mar 17 '15 at 17:55
  • @T.C., After reading more on the sequence points and what constitutes UB, I concluded that my hunch is not right. – R Sahu Mar 17 '15 at 18:25