Problem with numbers.

Hi, I'm doing a computational chemistry course as part of my chemistry degree, and I essentially have 0 knowledge of programming. One of the tasks I have been set, is to make a program that can work out the ratio of boltzmann populations. TBH that is irrelevant to the problem. My problem is that I have two energies (numerical values), that need to be put into the program and stored. I have called these values E1 and E2. For the calculation to work, E1 needs to be less than E2. So I have made a loop that causes the program to ask the user to re input these values if E2 is less than E1. However for some reason, when running this program it seems to get confused and say values of E2 which are obviously greater than that of E1, are less and ask the user to put new values in. Does anyone have any idea why this could be, is there some glaringly obvious mistake I have over looked?

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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//Boltzmann population program.
//Libraries being used.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main()
{
int temperature,data;
double k;
long answer,deltaE,E1,E2;
E1 = 0;
E2 = 0;
temperature = 0;
k = 1.3806488e-23;

//Introductory Message
Introduction:
printf("This Program calculates the Botlzmann population ratio for two energy levels at differeing temperatures.\n");

//Asks the user to input the two energy levels being considered.
energies:
if (E1!=0)
if (E2!=0)
{
    goto temp;
}
printf("\nPlease would you enter the two energy levels you would like to workout the Boltzmann ratio for in Joules.\n");

//Energy1
printf("\nE1=");
scanf("%lg",&E1);

//Energy2
printf("E2=");
scanf("%lg",&E2);

//Definies DeltaE
deltaE=E2-E1;

//Ensure E2 is bigger than E1
if (E1<E2)
{
    goto temp;
}
else if (E1==E2)
{
    printf("Please ensure E2 is larger than E1\n");
    E1 = 0;
    E2 =0;
    goto energies;
}
else if (E1>E2)
{
    printf("Please ensure E2 is larger than E1\n");
    E1 = 0;
    E2 =0;
    goto energies;
}

//Asks the user to input the temperature the two energy levels being considered are at.
temp:
if (temperature!=0)
{
    goto datacheck;
}
printf("\nPlease input the temperature of the system in Kelvins.");

//Temperature
printf("\nTemp=");
scanf("%d",&temperature);

//Ensures the temperature is a valid value.
if (temperature>0)
{
    goto datacheck;
}
else if (temperature<=0)
{
    printf("Please input a temperature greater than 0 K.\n");
    temperature = 0;
    goto temp;
}

//Checks if the data is correct for the calculation.
datacheck:
printf("\nYour temperature is %d K, E1 is %lg J and E2 is %lg J, are these the correct values for your calculation.\n",temperature,E1,E2);
printf("To change just your energy levels, please type and enter 1.\n");
printf("To change just your temperatures, please type and enter 2.\n");
printf("To change both your energy levels and temperatures, please type and enter 3.\n");
printf("To continute with the already entered values please type and enter 4.\n");
printf(":");
scanf("%d",&data);

//Decides how to proceed.
if (data==1)
{
    E1=0;
    E2=0;
    goto energies;
}
else if (data==2)
{
    temperature = 0;
    goto temp;
}
else if (data==3)
{
    E1 = 0;
    E2 = 0;
    temperature = 0;
    goto energies;
}
else if (data==4)
{
    goto calculation;
}

//The Calculation Part
calculation:

printf("%lg\n",deltaE);
answer=exp(-deltaE/(temperature*k));
printf("Your answer is %lg .\n",answer);

return 0;

}

Hmmm...

For the program you're attempting to code, you should absolutely no gotos or labels. goto is very very very very very very very evil!

Read up about do-while loops and rework you i/p routine using that.

e.g.
http://www.cplusplus.com/doc/tutorial/control/

Have you not been given any tuition on basic flow control?

Andy
Last edited on
The variables answer,deltaE,E1,E2 should be double, not long. Long is an integer type.

Next - don't use goto's, they are very very bad - forget that the language has goto's. Use functions instead.

There is a problem comparing doubles, as the binary fraction representation means that direct comparisons often fail.

Google numeric_limits<double>epsilon for some clues how to do comparisons with doubles.

HTH Good luck !!!!!


Edit:

http://www.cplusplus.com/forum/articles/3827/


The is a snippet half way down which does an equality test.
Last edited on
In this case I would just drop the equality test: the message displayed (and the response) for the == and > tests is the same, so I would just use an else with the < test.
Last edited on
I've re-arranged the code using small functions for the main parts of the program.

I don't normally use scanf(), so this may not be ideal, but I think it's along the right lines.

I don't think there are any problems comparing floating-point values here. The biggest problem I had was selecting suitable values to test the 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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//Boltzmann population program.
//Libraries being used.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void   getEnergies(double & E1, double & E2);
double getTemperature();
void   calculation(double E1, double E2, double temperature);

int main()
{
    int option;
    double E1;
    double E2;
    double temperature;

    // Introductory Message
    printf("This Program calculates the Botlzmann population ratio for two ");
    printf("energy levels at differing temperatures.\n");

    getEnergies(E1, E2);  // Asks the user to input the two energy levels.

    temperature = getTemperature();  //Asks the user to input the temperature.

    // Checks if the option is correct for the calculation.

    do
    {
        printf("\nYour temperature is %g K, E1 is %g J and E2 is %g J,", temperature,E1,E2);
        printf("\n\n Are these the correct values for your calculation?\n\n");

        printf(" 1. Change just your energy levels\n");
        printf(" 2. Change just your temperature\n");
        printf(" 3. Change both your energy levels and temperature\n");
        printf(" 4. Continute with the already entered values\n");
        printf(" 0. EXIT the program\n");
        printf("\n Please type and enter an option: ");
        scanf("%d",&option);

        switch (option)
        {
            case 1:
                getEnergies(E1, E2);
                break;

            case 2:
                temperature = getTemperature();
                break;

            case 3:
                getEnergies(E1, E2);
                temperature = getTemperature();
                break;

            case 4:
                calculation(E1, E2, temperature);
                break;
        }

    } while (option != 0);

    return 0;
}
//-----------------------------------------------------------------------------
void getEnergies(double & E1, double & E2)
{
    printf("\nPlease would you enter the two energy levels you would ");
    printf("like to workout the Boltzmann ratio for in Joules.\n");

    while (true) {

        E1 = 0.0;
        E2 = 0.0;

        // Energy1
        printf("\n E1 = ");
        scanf("%lg",&E1);

        // Energy2
        printf(" E2 = ");
        scanf("%lg",&E2);


        if ((E1 == 0.0) || (E2 == 0.0))
        {
            printf("Please ensure E1 and E2 are non zero\n");
            continue;
        }

        if (E2 > E1) {
            break;  // SUCCESS, E2 is bigger than E1
        }

        printf("Please ensure E2 is larger than E1\n");

    }

}
//-----------------------------------------------------------------------------
double getTemperature()
{
    printf("\nPlease input the temperature of the system in Kelvins.");

    double result;

    while (true)
    {
        result = 0.0;

        printf("\n\n Temp = ");
        scanf("%lg",&result);

        // Ensures the temperature is a valid value.
        if (result > 0.0) {
            return result;
        }

        printf("Please input a temperature greater than 0 K.\n");
    }
}
//-----------------------------------------------------------------------------
void calculation(double E1, double E2, double temperature)
{
    const double k = 1.3806488e-23;

    double deltaE = E2-E1;

    double answer = exp(-deltaE/(temperature*k));

    printf("\n\n  Your answer is %g \n", answer);

    printf("\n  Press enter to continue\n");
    // wait for a key press
    fflush(stdin);
    getchar();

}
//------------------------------------------------------------------------------ 
Last edited on
Thankyou very much for the help everyone. I took on board what you had all told me, and have re-wrote the code. The calculation seems to be producing correct answers which is good, I'm having just one problem. I want the user to be able to go back to the start and change the values of any of the numbers if they decide they have input the wrong amount. My problem is, is it possible to have while with multiple options. Like, while selection = 1 or 2. So that something will repeat while the selection is 1 or 2. Not both at the same time? Rather than re-writing my code for me, was just wondering if someone could point me in the right direction because I was having trouble searching for this on google because I don't really know the technical terms. If it's needed, just for people to look at, here is my coding.

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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
//A program to work out the boltzmann population ratio.
//The following libraries will be used.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
using namespace std;

double energyvalues(double E1, double E2)//Calculates "Delta E".
{
    double deltaE;//Defines the variable "deltaE" in this function.
    deltaE=E2-E1;//Calculates "deltaE", using the variables from "int main()".
    return (deltaE);//Returns "deltaE" to "int main()".
}

double calculation(double deltaE, int temp)//Calculates the boltzmann ration.
{
    double answer, k;//Defines the variable "answer" and "k" in this function.
    k=1.3806488e-23;
    answer=exp(-deltaE/(temp*k));//Calculates "answer".
    return (answer);//Returns "answer" to "int main()".
}

int main()
{
    do {
    //Asks the user to enter the two energy levels.
    double E1,E2,deltaE;//Defines the variables being used to calculate "deltaE".
    do {
    printf("Please input the two energy levels you would like to work out the\nBotlzmann ratio for in Joules.\n");
    printf("E1=");
    scanf("%lg",&E1);//Allows the user to input "E1".
    printf("E2=");
    scanf("%lg",&E2);//Allows the user to input "E2".
    deltaE = energyvalues(E1,E2);//Sets the value of the variable "deltaE", by running the variables "E1" and "E2" in the function "double energyvalues(double E1, double E2)".
    if (E2-E1<1e-100)
    {
        printf("Please ensure E2 is greater than E1\n\n");
    }
    } while (E2-E1<1e-100);//Loop ensures E2 is bigger than E1.


    //Asks the user to enter the temperature.
    int temp;//Defines the variable which holds the temperature.
    do {
    printf("\nPlease input the temperature in Kelvins.\n");
    printf("Temperature=");
    scanf("%d",&temp);//Allows the user to input "temp".
    if (temp<=0)
    {
        printf("Please ensure that your temperature is greater than 0K\n\n");
    }
    } while (temp<=0);//Loop ensure temperature is greater than 0K.


    //Prints the Energy levels and temperatures.
    printf("\nE1 is %lg J, E2 is %lg J and the temperature of the system is %d K.\n",E1,E2,temp);

    //Checks to see if the Energy levels and temperatures are correct.
    int selection;
    printf("\nAre these values correct?\n");
    printf("To continue with these values type and enter 1\n");
    printf("To change just the Energy levels type and enter 2\n");
    printf("To change just the temperature type and enter 3\n");
    printf("To change both the temperature and energy levels enter 4\n");
    printf(":");
    scanf("%d",&selection);
    } while //???????
    

    //The Calculation.
    double answer;//Defines the variable "answer" in the "int main()"function.
    answer = calculation(deltaE,temp);//Calculates the answer, by running the variables "deltaE" and "temp" in the function "calculation".
    printf("\nThe Boltzmann population ratio is %lg.\n\n",answer);//Prints the answer.

   return 0;
}
So what you do now is make a while loop that runs the calculations that the user has inputted so far and give the option of changing a variable or two. Think of your whole code up to now as loading-up or populating information for this final loop.

1
2
3
4
5
6
7
8
9
10
11
12
13
main()
{
    user input, user input, user input
    calculation
    answer

       while(user doesn't want to exit)
       { 
             ask if something needs to be changed (user input)
             calculation
             answer
       }
} 


You have all that you need for this final loop, you just have to do the hard labor of retyping what you need to put in there, that's why using functions is such a boon.
Last edited on
Using functions helps in that it (a) saves repeatedly typing more-or-less the same code, and just as important, (b) it allows the main control structure, such as a menu selection loop, to be kept clear and uncluttered, so it is easier to understand and modify as required. I'm not going to offer any code at this stage, however, some of the ideas from my previous version might still be useful.
@sidnake

I would get into the habit of indenting each scope, not just the topmost. And stick to one style of braces.

i.e. rather than

1
2
3
4
5
6
7
8
9
10
11
    //Asks the user to enter the temperature.
    int temp;//Defines the variable which holds the temperature.
    do {
    printf("\nPlease input the temperature in Kelvins.\n");
    printf("Temperature=");
    scanf("%d",&temp);//Allows the user to input "temp".
    if (temp<=0)
    {
        printf("Please ensure that your temperature is greater than 0K\n\n");
    }
    } while (temp<=0);//Loop ensure temperature is greater than 0K. 


use e.g. (where I've gone for K&R braces)

1
2
3
4
5
6
7
8
9
10
    //Asks the user to enter the temperature.
    int temp;//Defines the variable which holds the temperature.
    do {
        printf("\nPlease input the temperature in Kelvins.\n");
        printf("Temperature=");
        scanf("%d",&temp);//Allows the user to input "temp".
        if (temp<=0) {
            printf("Please ensure that your temperature is greater than 0K\n\n");
        }
    } while (temp<=0);//Loop ensure temperature is greater than 0K. 

Last edited on
Okay thanks everyone for being patient and trying to help me, I appreciate it. I've re-written the code again, I see what you mean about the functions making things less cluttered. I was struggling to try and fix my problem before, so I have re-written the code with less stuff in int main(), and more in seperate functions which can be ran fron int main(). I was wondering about how I can pass on more than one variable from a function to int main(), as far as I am aware this is not possible with return, or that is what I have been told. If I wanted to print E1, and E2 in the int main() function is there any way for me to do this? Thanks
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
64
65
66
67
//A program to work out the boltzmann population ratio.
//The following libraries will be used.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
using namespace std;

double energyvalues()//Calculates "Delta E" using the values of the two energy levels being considered.
{
double deltaE,E1,E2;//Defines the variables used.
do {// Acts as the loop ensuring E2 is greater than E1.

    printf("Please input the values of the two energy levels you are considering\nin Joules.\n");//Asks the user to input the values.
    printf("E1=");
    scanf("%lg",&E1);//Allows the user to input "E1".
    printf("E2=");
    scanf("%lg",&E2);//Allows the user to input "E2".

    if (E2-E1<1e-100)//Prints the message telling the user that E2 needs to be greater than E1, if they input an E1 calue greater than E2.
    {
        printf("Please ensure E2 is greater than E1\n\n");
    }

}while (E2-E1<1e-100);//Loop ensures E2 is bigger than E1.

deltaE=E2-E1;//Calculates "deltaE", using the variables from "int main()".
return (deltaE);//Returns "deltaE" to "int main()".
}

int temperature()//Asks the user to input the temperature the system is at.
{
int temp;//Defines the temperature variable.
do {//Loop to ensure temperature is greater than 0K.

    printf("\nPlease input the temperature in Kelvins.\n");
    printf("Temperature=");
    scanf("%d",&temp);//Allows the user to input "temp".

    if (temp<=0)
    {
        printf("Please ensure that your temperature is greater than 0K\n\n");
    }

} while (temp<=0);//Loop to ensure temperature is greater than 0K.
return (temp);//Returns "temp" to "int main()"//
}

double calculation(double deltaE, int temp)//Does the calculation.
{
    double answer, k;//Defines the variable "answer" and "k" in this function.
    k=1.3806488e-23;
    answer=exp(-deltaE/(temp*k));//Calculates "answer".
    return (answer);//Returns "answer" to "int main()".
}

int main()
{
    int temp; double deltaE,answer;
    printf("Program to calculate the Boltzmann population ratio.\n\n");//Introductory Message.
    deltaE=energyvalues();
    temp=temperature();
    printf("\nThe Energy difference is %lg J.\nThe temperature of the system is %d K.",deltaE,temp);
    answer=calculation(deltaE,temp);
    printf("\n\nThe Boltzmann population ratio is %lg",answer);
    return 0;
}
Topic archived. No new replies allowed.