Unmatched cpp output

For http://coliru.stacked-crooked.com/a/3efa0cbe9dc22d0c , why is it not time_ps-(double)number_of_baud_clocks_passed*(double)BAUD_OUT_PERIOD = 1.01561×10^14 − 974979×104167000 = 362507000 instead of 5.20734 X 10^7 ?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <cassert>
#include <cstdlib>
#include <cstdio>
#include <math.h>

using namespace std;

#define HALF_48MHz_PERIOD 10416.7
#define BAUD_OUT_PERIOD 104167000

double time_ps = 0;
unsigned int number_of_baud_clocks_passed = 0;
bool finished=false;

void update_clk(void) {

	time_ps = time_ps + HALF_48MHz_PERIOD/2;  

	/*******************************************/

	time_ps = time_ps + HALF_48MHz_PERIOD; 

	/*******************************************/

	time_ps = time_ps + HALF_48MHz_PERIOD/2;
}

int main()
{
    while(!finished){
        update_clk();
        number_of_baud_clocks_passed = (unsigned int)(time_ps/(double)BAUD_OUT_PERIOD);
        
    	if ( (number_of_baud_clocks_passed == 974979) && ((time_ps-(double)number_of_baud_clocks_passed*(double)BAUD_OUT_PERIOD <= (double)BAUD_OUT_PERIOD/2+(double)HALF_48MHz_PERIOD) && (time_ps-(double)number_of_baud_clocks_passed*(double)BAUD_OUT_PERIOD >= (double)BAUD_OUT_PERIOD/2-(double)HALF_48MHz_PERIOD)) ) {
            cout << "number_of_baud_clocks_passed = " << number_of_baud_clocks_passed << "\ttime_ps = " << time_ps << endl;
            
            cout << "(double)number_of_baud_clocks_passed = " << (double)number_of_baud_clocks_passed << endl;
            cout << "(double)BAUD_OUT_PERIOD = " << (double)BAUD_OUT_PERIOD << endl;
            
            cout << "time_ps-(double)number_of_baud_clocks_passed*(double)BAUD_OUT_PERIOD = " << time_ps-(double)number_of_baud_clocks_passed*(double)BAUD_OUT_PERIOD << endl;
            
            cout << "(double)BAUD_OUT_PERIOD/2+(double)HALF_48MHz_PERIOD = " << (double)BAUD_OUT_PERIOD/2+(double)HALF_48MHz_PERIOD << endl;
            cout << "(double)BAUD_OUT_PERIOD/2-(double)HALF_48MHz_PERIOD = " << (double)BAUD_OUT_PERIOD/2-(double)HALF_48MHz_PERIOD << endl;
            
    	    finished=true;
    	}
    }
}
Last edited on
I’ve got no idea what your code should do, but you can try to send to terminal the steps of execution and analyse what’s wrong with your calculation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <iostream>
#include <limits>


constexpr double HALF_48MHz_PERIOD =     10416.7;
constexpr double BAUD_OUT_PERIOD   = 104167000.0;


void update_clk(double& mytime);
void waitForEnter();


int main()
{
    double time_ps = 0.0;
    unsigned int number_of_baud_clocks_passed = 0;
    bool finished = false;
    while(!finished){
        update_clk(time_ps);
        number_of_baud_clocks_passed = (unsigned int)(time_ps/BAUD_OUT_PERIOD);
        std::cout << "time_ps: " << time_ps
                  << "; number_of_baud_clocks_passed: "
                  << number_of_baud_clocks_passed
                  << "; ";
        if (   (number_of_baud_clocks_passed == 974979) 
            && ((time_ps-(double)number_of_baud_clocks_passed*BAUD_OUT_PERIOD 
                    <= BAUD_OUT_PERIOD/2+HALF_48MHz_PERIOD) 
                    && (time_ps-(double)number_of_baud_clocks_passed*BAUD_OUT_PERIOD 
                    >= BAUD_OUT_PERIOD/2-HALF_48MHz_PERIOD)) ) {
            std::cout << "\nnumber_of_baud_clocks_passed = " 
                      << number_of_baud_clocks_passed 
                      << "\ttime_ps = " << time_ps
                      << "\n(double)number_of_baud_clocks_passed = " 
                      << (double)number_of_baud_clocks_passed
                      << "\nBAUD_OUT_PERIOD = " << BAUD_OUT_PERIOD
                      << "\ntime_ps-(double)number_of_baud_clocks_passed*(double)BAUD_OUT_PERIOD = " 
                      << time_ps-(double)number_of_baud_clocks_passed*BAUD_OUT_PERIOD
                      << "\n(double)BAUD_OUT_PERIOD/2+HALF_48MHz_PERIOD = " 
                      << BAUD_OUT_PERIOD/2+HALF_48MHz_PERIOD
                      << "\nBAUD_OUT_PERIOD/2-HALF_48MHz_PERIOD = " 
                      << BAUD_OUT_PERIOD/2-HALF_48MHz_PERIOD 
                      << '\n';
            finished = true;
        }
    }
    waitForEnter();
    return 0;
}


void update_clk(double& mytime)
{
    mytime += HALF_48MHz_PERIOD / 2;
    mytime += HALF_48MHz_PERIOD; 
    mytime += HALF_48MHz_PERIOD / 2;
}


void waitForEnter()
{
    std::cout << "\nPress ENTER to continue...\n";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}


What I’ve verified is after 4 minutes of execution, “number_of_baud_clocks_passed” has become just 26, so, to get to 974979... well...
@Enoizat ,could you try http://coliru.stacked-crooked.com/a/3efa0cbe9dc22d0c ?

I am not sure why your modified code does not match with what I have at https://paste2.org/mxZDgKFf
Last edited on
user123random, could you try my code?
Of course if you remove the output the execution become much faster, but if you want to debug your program, perhaps you need to look into the execution and not only the final result.

So, if you want:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <iostream>
#include <limits>


constexpr double HALF_48MHz_PERIOD =     10416.7;
constexpr double BAUD_OUT_PERIOD   = 104167000.0;


void update_clk(double& mytime);
void waitForEnter();


int main()
{
    double time_ps = 0.0;
    unsigned int number_of_baud_clocks_passed = 0;
    bool finished = false;
    while(!finished){
        update_clk(time_ps);
        number_of_baud_clocks_passed = (unsigned int)(time_ps/BAUD_OUT_PERIOD);
        /*std::cout << "time_ps: " << time_ps
                  << "; number_of_baud_clocks_passed: "
                  << number_of_baud_clocks_passed
                  << "; ";*/
        if (   (number_of_baud_clocks_passed == 974979) 
            && ((time_ps-(double)number_of_baud_clocks_passed*BAUD_OUT_PERIOD 
                    <= BAUD_OUT_PERIOD/2+HALF_48MHz_PERIOD) 
                    && (time_ps-(double)number_of_baud_clocks_passed*BAUD_OUT_PERIOD 
                    >= BAUD_OUT_PERIOD/2-HALF_48MHz_PERIOD)) ) {
            std::cout << "\nnumber_of_baud_clocks_passed = " 
                      << number_of_baud_clocks_passed 
                      << "\ttime_ps = " << time_ps
                      << "\n(double)number_of_baud_clocks_passed = " 
                      << (double)number_of_baud_clocks_passed
                      << "\nBAUD_OUT_PERIOD = " << BAUD_OUT_PERIOD
                      << "\ntime_ps-(double)number_of_baud_clocks_passed*(double)BAUD_OUT_PERIOD = " 
                      << time_ps-(double)number_of_baud_clocks_passed*BAUD_OUT_PERIOD
                      << "\n(double)BAUD_OUT_PERIOD/2+HALF_48MHz_PERIOD = " 
                      << BAUD_OUT_PERIOD/2+HALF_48MHz_PERIOD
                      << "\nBAUD_OUT_PERIOD/2-HALF_48MHz_PERIOD = " 
                      << BAUD_OUT_PERIOD/2-HALF_48MHz_PERIOD 
                      << '\n';
            finished = true;
        }
    }
    waitForEnter();
    return 0;
}


void update_clk(double& mytime)
{
    mytime += HALF_48MHz_PERIOD / 2;
    mytime += HALF_48MHz_PERIOD; 
    mytime += HALF_48MHz_PERIOD / 2;
}


void waitForEnter()
{
    std::cout << "\nPress ENTER to continue...\n";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}


Output:
number_of_baud_clocks_passed = 974979   time_ps = 1.01561e+014
(double)number_of_baud_clocks_passed = 974979
BAUD_OUT_PERIOD = 1.04167e+008
time_ps-(double)number_of_baud_clocks_passed*(double)BAUD_OUT_PERIOD = 5.20734e+007
(double)BAUD_OUT_PERIOD/2+HALF_48MHz_PERIOD = 5.20939e+007
BAUD_OUT_PERIOD/2-HALF_48MHz_PERIOD = 5.20731e+007

Press ENTER to continue...

Is that of any help? I don’t think so.
Use my previous code to analyse the steps of your operation. Casting from double to unsigned int is likely to be the part which causes errors in your calculation, whatever it should be.

Anyway, look over your update_clk() function. The following steps:
1
2
3
time_ps = time_ps + HALF_48MHz_PERIOD/2;  
time_ps = time_ps + HALF_48MHz_PERIOD; 
time_ps = time_ps + HALF_48MHz_PERIOD/2;

could be compressed this way:
time_ps += HALF_48MHz_PERIOD * 2;

You can try yourself:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <limits>


constexpr double HALF_48MHz_PERIOD =     10416.7;
constexpr double BAUD_OUT_PERIOD   = 104167000.0;


void update_clk(double& mytime);
void waitForEnter();


int main()
{
    double time_ps = 0.0;
    unsigned int number_of_baud_clocks_passed = 0;
    bool finished = false;
    while(!finished){
        update_clk(time_ps);
        number_of_baud_clocks_passed = (unsigned int)(time_ps/BAUD_OUT_PERIOD);
        /*std::cout << "time_ps: " << time_ps
                  << "; number_of_baud_clocks_passed: "
                  << number_of_baud_clocks_passed
                  << "; ";*/
        if (   (number_of_baud_clocks_passed == 974979) 
            && ((time_ps-(double)number_of_baud_clocks_passed*BAUD_OUT_PERIOD 
                    <= BAUD_OUT_PERIOD/2+HALF_48MHz_PERIOD) 
                    && (time_ps-(double)number_of_baud_clocks_passed*BAUD_OUT_PERIOD 
                    >= BAUD_OUT_PERIOD/2-HALF_48MHz_PERIOD)) ) {
            std::cout << "\nnumber_of_baud_clocks_passed = " 
                      << number_of_baud_clocks_passed 
                      << "\ttime_ps = " << time_ps
                      << "\n(double)number_of_baud_clocks_passed = " 
                      << (double)number_of_baud_clocks_passed
                      << "\nBAUD_OUT_PERIOD = " << BAUD_OUT_PERIOD
                      << "\ntime_ps-(double)number_of_baud_clocks_passed*(double)BAUD_OUT_PERIOD = " 
                      << time_ps-(double)number_of_baud_clocks_passed*BAUD_OUT_PERIOD
                      << "\n(double)BAUD_OUT_PERIOD/2+HALF_48MHz_PERIOD = " 
                      << BAUD_OUT_PERIOD/2+HALF_48MHz_PERIOD
                      << "\nBAUD_OUT_PERIOD/2-HALF_48MHz_PERIOD = " 
                      << BAUD_OUT_PERIOD/2-HALF_48MHz_PERIOD 
                      << '\n';
            finished = true;
        }
    }
    waitForEnter();
    return 0;
}


void update_clk(double& mytime)
{ mytime += HALF_48MHz_PERIOD * 2; }


void waitForEnter()
{
    std::cout << "\nPress ENTER to continue...\n";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}


Output:
number_of_baud_clocks_passed = 974979   time_ps = 1.01561e+014
(double)number_of_baud_clocks_passed = 974979
BAUD_OUT_PERIOD = 1.04167e+008
time_ps-(double)number_of_baud_clocks_passed*(double)BAUD_OUT_PERIOD = 5.20906e+007
(double)BAUD_OUT_PERIOD/2+HALF_48MHz_PERIOD = 5.20939e+007
BAUD_OUT_PERIOD/2-HALF_48MHz_PERIOD = 5.20731e+007

Press ENTER to continue...

@user123random

You must vastly simplify your code to make it readable ... to yourself and others. There is much repetition and the number of unnecessary casts just add to the complexity.

Introduce some intermediate variables; e.g.
1
2
3
double t0 = time_ps - number_of_baud_clocks_passed * BAUD_OUT_PERIOD;
double t1 = 0.5 * BAUD_OUT_PERIOD - HALF_48MHz_PERIOD;
double t2 = 0.5 * BAUD_OUT_PERIOD + HALF_48MHz_PERIOD;


Your if statement then reduces to
if ( number_of_baud_clocks_passed == 974979 && t0 >= t1 && t0 <= t2 )
and your cout statements could be considerably shortened.

As you have originally posted,
- each call to update_clk() increases time_ps by 2*HALF_48MHz_PERIOD; so you will need 5000 of these (give or take floating point rounding) to reach one BAUD_OUT_PERIOD
- for
number_of_baud_clocks_passed == 974979
you would need about 5000 * 974979 passes through that loop.
- if there was perfect precision then
t0 = time_ps - number_of_baud_clocks_passed * BAUD_OUT_PERIOD 
would be zero ... so the latter two conditions in the if statement would never be met.


I should go back and greatly simplify your code. Don't write massive long statements repeatedly and don't make it complicated by unnecessary casts.

You might like to actually state what your code is intending to do in words.
Topic archived. No new replies allowed.