I just hit a strange behavior when compiling a small C++ program with g++ (4.6.3). Compare the two floats celsius and test:
#include <iostream>
using namespace std;
int main () {
float fahrenheit = 0;
float celsius = 0;
float test = 0;
cout << "Temperature in °F: " << endl;
cin >> fahrenheit;
celsius = 5 / 9 * (fahrenheit - 32);
test = 5 * (fahrenheit - 32) / 9;
cout << "\nWrong:\t" << fahrenheit << " °F = " << celsius << " °C" << endl;
cout << "Correct:" << fahrenheit << " °F = " << test << " °C" << endl;
}
I compiled this with just "g++ test.cpp -o test".
This is the output of the program:
$ ./test
Temperature in °F:
1000
Wrong: 1000 °F = 0 °C
Correct:1000 °F = 537.778 °C
Can someone explain to me why g++ does (reproducibly) compute celsius to 0, whereas test contains the correct solution? Does it have anything to do with some optimization, although I didn't set any args for that? Or is this really a bug in some way?
5 / 9 = 0
0 * anything = 0
When you divide to integers, you get an integer back. You can just say 5.0 / 9 and it should be a lot better.
When you're writing code and don't get what you expect, your first inclination should be "what dod I do wrong?" not "what did the compiler do wrong?"
It'll help you look in the right place most of the time.
Related
Im working on this for class but I am getting stuck with getting the right output.
#include<iostream>
using namespace std;
double celsiusToFahrenheit (double);
double fahrenheitToCelsius (double);
int main ()
{
double f;
double c;
cout.setf (ios::fixed);
cout.precision (2);
cout << "Celsius \t" << "Fahrenheit \t" << "| \t" << "Fahrenheit \t" << "Celsius" << endl;
cout << fahrenheitToCelsius (c) << "\t\t" << celsiusToFahrenheit (c) <<
endl;
return 0;
}
double celsiusToFahrenheit (double f)
{
double fahrenheit;
for (double celsius = 40.0; celsius >= 31.0; celsius--)
{
fahrenheit = (9.0 / 5.0) * celsius + 32.0;
cout << celsius << "\t\t" << fahrenheit << "\t\t|" << endl;
}
return fahrenheit;
}
double fahrenheitToCelsius (double c)
{
double celsius;
for (double fahrenheit = 120.0; fahrenheit >= 30.0;
fahrenheit = fahrenheit - 10)
{
celsius = (fahrenheit - 32.0) * 5.0 / 9.0;
cout << fahrenheit << "\t\t" << celsius << endl;
}
cout << endl;
return celsius;
}
what i get when i run the code
Celsius Fahrenheit | Fahrenheit Celsius
40.00 104.00 |
39.00 102.20 |
38.00 100.40 |
37.00 98.60 |
36.00 96.80 |
35.00 95.00 |
34.00 93.20 |
33.00 91.40 |
32.00 89.60 |
31.00 87.80 |
120.00 48.89
110.00 43.33
100.00 37.78
90.00 32.22
80.00 26.67
70.00 21.11
60.00 15.56
50.00 10.00
40.00 4.44
30.00 -1.11
-1.11 87.80
There is one design flaw in your approach.
You assigned additional tasks to your conversion functions "celsiusToFahrenheit" and "fahrenheitToCelsius". In your approach they do also generate output. The functionalities / tasks should be separated in your program. You may have even noticed, that you do not use the functions parameters.
So, let us redesign and refactor the code and do some improvements:
We eliminate all const literals from the functions and define them on the top of the program as constexpr values. With that, we can change a value on exactly one central place and it will have an impact in all functions.
The column width on the output screen is a calculated value. It depends on the longest used text.
We define the conversion functions above function main. That eliminates the need for forward declarations
The conversion functions are stripped down to their essential functionality
We put all ios flags into the output stream, together with all other manipulators
We define a logic for the output of 2 different long lists in one line. Basically, we check, if a conversion should be printed or not. If the celsius to fahrenheit part is done, then we will print spaces instead for the current line
We calculate the next value to be converted in different places
We run all this in a loop. At the beginning of the loop, we assume that we are done (and should stop the loop), but, if we print a value, then we will continue the loop.
Please note. There are many many different solutions. Other solutions are also very much shorter. But I created this "verbose" solution for you to get a better understanding. Please see that I added many comments in the code. This should always be done. Otherwise nobody else will understand what is coded, and even you will not understand it one month later. . .
#include<iostream>
#include<iomanip>
#include<string>
#include<algorithm>
// The ranges for that we will do the calculations
// For Fahrenheit values to be converted into Celcius
constexpr double FahrenheitStart = 120.0; // Start value (inclusive)
constexpr double FahrenheitEnd = 0.0; // End value (inclusive)
constexpr double FahrenheitStep = 5; // Decrement step
// For Celcius values to be converted into Fahrenheit
constexpr double CelsiusStart = 30.0; // Start value (inclusive)
constexpr double CelsiusEnd = -5.0; // End value (inclusive)
constexpr double CelsiusStep = 1.0; // Decrement step
// Global texts that may be used in different places
constexpr std::string_view Fahrenheit{ "Fahrenheit" };
constexpr std::string_view Celcius{ "Celcius" };
// The delimiter
constexpr std::string_view Delimiter{ " | " };
// The field width of the columns shall be the maximum text length +1
constexpr size_t FieldWidth = std::max(Fahrenheit.length(), Celcius.length()) + 1;
// Conversion functions
double celsiusToFahrenheit(const double celsius) {
return (9.0 / 5.0) * celsius + 32.0;
}
double fahrenheitToCelsius(const double fahrenheit) {
return (fahrenheit - 32.0) * 5.0 / 9.0;
}
// Print a conversion list for temperatures in Fahrenheit and Celcius
int main()
{
// Set ios flags and print header
std::cout << std::right << std::setiosflags(std::ios::fixed) << std::setprecision(2) <<
std::setw(FieldWidth) << Celcius << std::setw(FieldWidth) << Fahrenheit << Delimiter <<
std::setw(FieldWidth) << Fahrenheit << std::setw(FieldWidth) << Celcius << "\n";
// Set start values for conversion functions
double f = FahrenheitStart;
double c = CelsiusStart;
// We want to run a loop;
bool doCalculation = true;
// Calculate all values
while (doCalculation) {
// We assume that we are maybe done with all values
doCalculation = false;
// Check, if we have printed all Celcius values
if ((c >= CelsiusEnd)) {
// Print Celcius values and its conversions
std::cout << std::setw(FieldWidth) << c << std::setw(FieldWidth) << celsiusToFahrenheit(c) << Delimiter;
// Calculate next value to convert
c -= CelsiusStep;
// No, not done, continue the loop
doCalculation = true;
}
else {
// If all Celcius values have been printed already, then print spaces, if needed
if (f >= FahrenheitEnd) std::cout << std::setw(FieldWidth * 2) << "" << Delimiter;
}
// Check, if we have printed all Fahrenheit values
if (f >= FahrenheitEnd) {
// Print Fahrenheit values and its conversions
std::cout << std::setw(FieldWidth) << f << std::setw(FieldWidth) << fahrenheitToCelsius(f);
// Calculate next value to convert
f -= FahrenheitStep;
// No, not done, continue the loop
doCalculation = true;
}
std::cout << "\n";
}
return 0;
}
My if-else statement doesn't seem to work, anyone have any ideas?
So I created this simple Fahrenheit-Celcius conversion console app using C++. The program uses a simple if-else statement to determine which conversion they want, Fahrenheit-Celcius or Celcius-Fahrenheit.
The code currently doesn't work, however, it instantly converts Celcius-Fahrenheit and completely ignores the std::cin I put to grab user input. Instead, they put in the value of 0 everytime I run the program.
#include<iostream>
using namespace std;
int main() {
unsigned short int fahrenheit{}, celsius{};
char unit;
cout << "Choose what unit you want to start with" << endl;
cin >> unit;
if (unit == 'c') {
cout << "Enter the temperature in Celsius : " << endl;
cin >> celsius;
fahrenheit = (celsius * 9.0) / 5.0 + 32;
cout << "The temperature in Fahrenheit : " << fahrenheit << endl;
} else {
cout << "Enter the temperature in Fahrenheit : " << endl;
cin >> fahrenheit;
fahrenheit = (celsius * 9.0) / 5.0 + 32;
cout << "The temperature in Celcius : " << celsius << endl;
}
std::cin.clear(); // reset any error flags
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // ignore any characters in the input buffer until we find an enter character
std::cin.get(); // get one more char from the user
return 0;
}
in the if condition, use unit=='C' || unit=='c'. May be you entered uppercase. and remove unsign for negative value, and convert int to double for floating answer. in the else condition fahrenheit = (celsius * 9.0) / 5.0 + 32; is wrong, it will be celsius = ( fahrenheit - 32) * 5.0 / 9.0..
In else block, you have not set value for celsius.
I guess you want to do something like that:
celsius = (fahrenheit - 32) * 5 / 9.0;
But, your code is
fahrenheit = (celsius * 9.0) / 5.0 + 32;
I have written a simple program to output different temperature units using conversions given. When I run the code on Visual Studios, it won't run due to build errors but no errors are shown. I have seen similar questions asked but couldn't really see any answer that solved my issue. I was also wondering whether I should be declaring the variables before or after the main function.
#include <iostream>
using namespace std;
int fahrenheit, i=0;
float celsius, absolute_value;
main() {
cout.width(20);
cout << "Fahrenheit" << "Celsius" << "Absolute value\n";
for (i = 0; i = 15; i += 1) {
fahrenheit = i * 20;
celsius = ((fahrenheit - 30) * 5) / 9;
absolute_value = celsius + 273.15;
cout.width(20); /*each item in next output will have width of at least 20*/
cout << fahrenheit << celsius << absolute_value;
}
system("pause");
return 0;
}
#include <iostream>
int main() {
std::cout << "Fahrenheit\t" << "Celsius\t\t" << "Absolute value\n";
for (int i = 0; i <= 15; i++)
{
const int fahrenheit = i * 20;
const float celsius = ((fahrenheit - 32.0) * 5) / 9;
const float absolute_value = celsius + 273.15;
std::cout << fahrenheit << "\t\t" << celsius << "\t\t"<< absolute_value << "\n";
}
system("pause");
return 0;
}
Issues fixed:
main must return int
loop had assignement instead of comparison
variables should not be global
using namespace std; should be avoided
formula for fahrenheit to celsius was wrong
celsius was calculated with interger arithmetic despite being float
const correctness
cosmetic: formatted output with tabs
You need to add the int return type to the main signature.
In c++, the standard expects the main function to return an int, just as it expects the function to be called main. The return is most often used as an exit code, where 0 usually means successful execution without error.
Adding this in should allow your program to compile and run.
I fixed some coding errors. I think there are still some logical errors but now the code compile and program should run
#include <iostream>
using namespace std;
int main() {
cout.width(20);
cout << "Fahrenheit" << "Celsius" << "Absolute value\n";
for (int i = 0; i <= 15; i += 1) {
int fahrenheit = i * 20;
float celsius = ((fahrenheit - 30) * 5) / 9;
float absolute_value = celsius + 273.15;
cout.width(20); /*each item in next output will have width of at least 20*/
cout << fahrenheit << ' ' << celsius << ' ' << absolute_value << '\n';
}
system("pause");
return 0;
}
You are missing the includes for iostream and the return type for the main function. I also moved the declaration of the global variables to where the variables are used the first time. The for loop was an endless loop. So I changed i = 15 to i <= 15. Maybe you wanted a loop condition like i < 15. I also added whitespaces and linebreaks between the values.
**** It now works the way I want it to, thank you everyone!! :) :)
*** Thank you! The Celsius works now, but why does the Kelvin still become 0?
** Thank you! I seem to have fixed the problem of the program ending after entering "kelvin" or "celsius". I also changed the spelling of Fahrenheit in my code. Now, the problem is that the answer I get is always 0, instead of the conversion...
Original code
// This program converts from Farenheight to Celsius or Kelvin
#include <iostream>
#include <string>
using namespace std;
int main() {
string input, Celsius, Kelvin;
double farenheight, celsius, kelvin;
cout <<"Hi! What is the weather today in Farenheight?? "<< endl;
cin >>farenheight;
cout <<"Would you like to convert this temperature to Celsius or Kelvin?"<<endl;
cin >> input;
if(input == Celsius)
{
cout << "Today's weather in Celsius is " <<celsius << " degrees Celsius! " << endl;
celsius = (5*(farenheight - 32)) / 9 ;
}
else if(input == Kelvin)
{
cout << "Today's weather in Kelvin is "<<kelvin <<" degrees Kelvin! " <<endl;
kelvin = (farenheight + 459.67)*(5/9);
}
}
Final code
// This program converts from Fahrenheit to Celsius or Kelvin
#include <iostream>
#include <string>
using namespace std;
int main() {
string input;
double Fahrenheit, celsius, kelvin;
cout << "Hi! What is the weather today in Fahrenheit?? "<< endl;
cin >> Fahrenheit;
cout << "Would you like to convert this temperature to Celsius or Kelvin?"<< endl;
cin >> input;
if(input == "Celsius")
{
celsius = (5*(Fahrenheit - 32)) / 9 ;
cout << "Today's weather in Celsius is " <<celsius << " degrees! " << endl;
}
else if(input == "Kelvin")
{
kelvin = (5*(Fahrenheit + 459.67)) / 9 ;
cout << "Today's weather in Kelvin is "<<kelvin <<" degrees!" <<endl;
}
return 0;
}
Problems with original code
I'm trying to make it so it asks for an input of how many degrees in Fahrenheit you want, then asks whether you want to convert it to Celsius or Kelvin, and then proceeds to follow the equation and give the conversion. However, it seems to end after I type in I want Kelvin or Celsius — even if I just use the equation, the answer always comes out as 0...
Output is:
Hi! What is the weather today in Farenheight??
60
Would you like to convert this temperature to Celsius or Kelvin?
Celsius
Exit code: 0 (normal program termination)
I have corrected (using that word loosely here) the code that you've shared. Like others mentioned in the comments, your variable names are misspelled and were not initialized with a value.
Another mistake was that you were dividing 5 by 9 using integer division (farenheight + 459.67)*(5 / 9);. This causes type coercion, since both operands are of type int the result is coerced to an int, dropping any numbers after the decimal place. In this case 5 / 9 results in 0, so your entire result is multiplied by 0.
Another issue that would cause the results to be incorrect is that you are outputting the variables to the stream before you are declaring what the variables should contain. If you do this, whatever was stored in memory, the null string, will be output to the screen.
Here is the corrected code:
// This program converts from Farenheight to Celsius or Kelvin
#include <iostream>
#include <string>
using namespace std;
int main() {
string input, Celsius, Kelvin;
double farenheight = 0.0, celsius = 0.0, kelvin = 0.0;
cout << "Hi! What is the weather today in Farenheight?? " << endl;
cin >> farenheight;
cout << "Would you like to convert this temperature to Celsius or Kelvin?" << endl;
cin >> input;
if (input == "Celsius")
{
celsius = (5.0 * (farenheight - 32.0)) / 9.0;
cout << "Today's weather in Celsius is " << celsius << " degrees Celsius! " << endl;
}
else if (input == "Kelvin")
{
kelvin = (farenheight + 459.67)*(5.0 / 9.0);
cout << "Today's weather in Kelvin is " << kelvin << " degrees Kelvin! " << endl;
}
}
Two examples of output are here:
Hi! What is the weather today in Farenheight??
100.0
Would you like to convert this temperature to Celsius or Kelvin?
Celsius
Today's weather in Celsius is 37.7778 degrees Celsius!
Hi! What is the weather today in Farenheight??
100.0
Would you like to convert this temperature to Celsius or Kelvin?
Kelvin
Today's weather in Kelvin is 310.928 degrees Kelvin!
Press any key to continue . . .
You declare variables called Celsius and Kelvin; however, their default value is set to "" (empty string). You forgot to initialize them.
If you want to make your program work, you need to initialize these variables to their expected values (which are probably "Celsius" and "Kelvin") like this:
string Celsius = "Celsius", Kelvin = "Kelvin";
However, even better solution here would be not to make any variables at all for these 2 options and compare it in the condition directly with the string literal. Like this:
if(input == "Celsius")
{
...
}
else if(input == "Kelvin")
{
...
}
Also another thing I have noticed. You are calculating values for celsius and kelvin after you have printed them. You should do it before.
I am currently writing a program that estimates Pi values using three different formulas pictured here: http://i.imgur.com/LkSdzXm.png .
This is my program so far:
{
double leibniz = 0.0; // pi value calculated from Leibniz
double counter = 0.0; // starting value
double eulerall = 0.0; // value calculated from Euler (all integers)
double eulerodd = 0.0; // value calculated from Euler (odds)
double eulerallans; // pi value calculated from Euler series (all integers)
double euleroddans; // pi value calculated from Euler series (odd integers)
int terms;
bool negatives = false;
cin >> terms;
cout << fixed << setprecision(12); // set digits after decimal to 12
while(terms > counter){
leibniz = 4*(pow(-1, counter)) / (2*counter+1) + leibniz;
eulerall = (1/pow(counter+1,2)) + eulerall;
eulerodd = 32*(pow(-1, counter)) / (pow(2*counter + 1, 3)) + eulerodd;
counter++;
eulerallans = sqrt(eulerall*6);
euleroddans = pow(eulerodd, 1.0/3.0);
cin >> terms;
if (terms < 0){
if(!negatives)
negatives=true;
}
}
cout << right << setw(14) << "# TERMS" << setw(15) << "LEIBINZ" << setw(15) << "\
EULER-ALL" << setw(15) << "EULER-ODD" << endl;
cout << right << setw(14) << terms << " " << leibniz << " " << eulerallans << " "\
<< euleroddans <<endl;
cout << "There were " << negatives << " negative values read" << endl;
return 0;
}
The sample input file that I am using is:
1
6
-5
100
-1000000
0
And the sample output for this input file is:
1 4.000000000000 2.449489742783 3.174802103936
6 2.976046176046 2.991376494748 3.141291949057
100 3.131592903559 3.132076531809 3.141592586052
When I run my program all I get as an output is:
# TERMS LEIBINZ EULER-ALL EULER-ODD
1
4.000000000000
2.449489742783
1.000000000000
So, I have two problems with my program:
1) It is only reading the first value in the input file and stopping.
2) The equation for eulerodd seems to be off, but I can't figure out what the problem is.
EDIT: Thanks to #RaphaelMiedl, I solved problem 2. Now I only have problem 1 to deal with.
Help is greatly appreciated.
I don't have the time to go through all of your code but
euleroddans = pow(32*eulerodd, 1/3);
immediately jumped me when I skimmed over it. 1/3 is integer arithmetic and gives you 0. Probably not what you wanted, you probably want 1.0/3.0 or something of the like there.
Now a bit of a late addition since I had time to look at your code again. #paddy is right that you only got one input statement in your code.
I'd probably put the whole pi calculation and outputting in a function and then loop over the input like:
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
void my_pi_func(int term);
int main()
{
int term;
cout << fixed << setprecision(12); // set digits after decimal to 12
while (cin >> term){
my_pi_func(term);
}
return 0;
}
void my_pi_func(int term)
{
if (term <= 0){
cout << "\n\nNegative value or 0 read\n\n" << endl;
return;
}
double leibniz = 0.0; // pi value calculated from Leibniz
int counter = 0; // starting value
double eulerall = 0.0; // value calculated from Euler (all integers)
double eulerodd = 0.0; // value calculated from Euler (odds)
double eulerallans = 0.0; // pi value calculated from Euler series (all integers)
double euleroddans = 0.0; // pi value calculated from Euler series (odd integers)
while(term > counter){
leibniz = 4*(pow(-1, counter)) / (2*counter+1) + leibniz;
eulerall = (1/pow(counter+1,2)) + eulerall;
eulerodd = (pow(-1, counter)) / (pow(2*counter + 1, 3)) + eulerodd;
counter++;
eulerallans = sqrt(eulerall*6);
euleroddans = pow(32*eulerodd, 1.0/3.0);
}
cout << right << setw(14) << "# TERMS" << setw(15) << "LEIBINZ" << setw(15)
<< "EULER-ALL" << setw(15) << "EULER-ODD" << endl;
cout << right << setw(14) << term << " " << leibniz << " " << eulerallans
<< " " << euleroddans <<endl;
}
You can see a working version here. Note that I made some more slight adjustments. For one I changed terms into term since that plural s was somehow bothering me. Also I changed counter to be an int since a counter as double variable doesn't make sense in my opinion. Also I changed how negative/0 values output. But all in all you should get what you should change if you compare with yours.