I'm making a Gravitational Force Calculator for my Physics class and when I input numbers in scientific notation, the output for the solved problem is always infinity. I've been inputting masses like these: 9.932e+22. I'm not sure where I went wrong, or if I'm just missing something in my code.
Code:
#include <iostream>
#include <cmath>
int main() {
double m1, m2, r, answer;
double G = 6.67e-11d;
std::cout << "Please enter Mass 1, Mass 2, and Radius :)\n";
std::cout << "Mass 1:";
std::cin >> m1;
std::cout << "Mass 2:";
std::cin >> m2;
std::cout << "Radius:";
std::cin >> r;
answer = G*((m1*m2)/(r*r));
std::cout << answer;
return 0;
}
The "d" as the end of the initialized G indicates that it's a double
Well I've never heard of that before. It doesn't make much sense since it's also a double without it since that's the default. You need to append an f to make it a float literal.
Has anyone else heard of this d thing? What is it's purpose?
PLEASE ALWAYS USE CODE TAGS (the <> formatting button) when posting code.
It makes it easier to read your code and also easier to respond to your post. http://www.cplusplus.com/articles/jEywvCM9/ http://www.cplusplus.com/articles/z13hAqkS/
Hint: You can edit your post, highlight your code and press the <> formatting button.
You can use the preview button at the bottom to see how it looks.
Using your code this is what I changed and the output I got:
#include <iostream>
#include <cmath>
int main()
{
constexprdouble G = 6.67e-11;
double m1{}, m2{}, r{}, answer{};
std::cout << "Please enter Mass 1, Mass 2, and Radius :)\n";
std::cout << "Mass 1: ";
std::cin >> m1;
std::cout << "Mass 2: ";
std::cin >> m2;
std::cout << "Radius: ";
std::cin >> r;
answer = G*((m1*m2) / (r*r));
std::cout << '\n' << answer << std::endl;
// The next line may not be needid. If you have to press enter to see the prompt it is not needed.
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // <--- Requires header file <limits>.
std::cout << "\n\n Press Enter to continue";
std::cin.get();
return 0;
}
Please enter Mass 1, Mass 2, and Radius :)
Mass 1: 9.932e+22
Mass 2: 1.989e+27
Radius: 4.22e+8
7.39899e+22
Press Enter to continue
It is always a good idea and programming to initialize you variables when they are defined.
As JLBorges did in his example I made gravity a constant as it should be because it should never change.
Making the changes to your program I received the same answer as JLBorges.
It is always a good idea and programming to initialize you variables when they are defined.
Why?
And (more importantly for this particular problem) to what values?
If I don't initialise variables then the compiler (with suitable error checking switched on) can tell me there's a problem.
If I do initialise them - as here, to an unphysical value - then the program will proceed without me knowing there is anything wrong.
More important, I think, are:
(a) to turn error checking right up when compiling;
(b) to understand the physics of the problem.
Sorry, just playing devil's advocate here! I think that some of the advice that is often given about this (and a few other things that often come up in the forum) come from times when compilers were not as capable as they are now. Sometimes it would be good to revisit it.
BTW, the extra d is a gcc extension (apparently). Strangely, the OP's code actually ran in c++ shell.
I would say the variable initialization is less important than making sure std::cin fails or not. If std::cin fails, your program isn't going to do what you want it to do, whether that produces undefined behavior from uninitialized variables, or incorrect (but at least defined) behavior.
If std::cin is correctly checked for failure, then uninitialized variables or 0.0-value variables will never be used.
In Andy's defense, all of us (most?) are always telling beginners to initialise.
If we are going to go for the golden rule of always initialising, then there is the caveat that 0 is not always a good choice, because in this case we have division. So perhaps a better value might have been 1.0 . Or maybe negative going with the convention that all magnitude values that might combined with a direction to make a math vector should be positive, so a negative is obviously wrong.
Notice in JLBorges code, there is declaration, input, assignment one after the other, and more importantly a check they are all > 0.0 . That seems the best: validation code to ensure values are in the correct range, and satisfy invariants. Sometimes I wish we had a built in unsigneddouble, to easily enforce things like this with the type system. I guess one could use a user defined literal to do that these days.
Another way to look at it is to declare and initialise when there is a sensible value, but that doesn't apply when getting input. I am sure we have all done it both ways.
That is fair comment, @TheIdeasMan. I was just trying to ask people to consider whether what we do automatically is always such a good idea. Undoubtably I appreciate @HandyAndy's sincere input, even where I don't necessarily agree with him.
Agreed, too, that the nice thing about @JLBorges' code was the input check if( m1 > 0 && m2 > 0 && r > 0 )
(Actually, I quite liked the appearance of units as well, but that's a different issue!)
No worries, I wasn't meaning to be critical either, I shouldn't have used the word "defense". It is good to have these discussions - who knows what we might learn :+)
With the user defined literals, I am having trouble seeing how to get input, then turn it into a literal. That is probably not the point of them, being a literal . Maybe it is useful for constants, otherwise just use a plain struct.
It is always a good idea and programming to initialize you variables when they are defined.
I think he meant 'declared' here. Giving it the value is defining.
Suppose we have
1 2
int k {};
k = 1;
Isn't this basically two assignments, or are they optimized out if nothing interesting happens between declaration and definition?
I believe we should be striving for minimalism here, and as long as we understand the idea of indeterminate values, then an explicit initialization shouldn't be necessary in most cases.
Of course, a classic beginner error is
1 2
int sum;
sum += 100;
, but even this helps the learning process by concluding, "hey, <indeterminate>+100 doesn't actually make sense"
If we are going to go for the golden rule of always initialising, then there is the caveat that 0 is not always a good choice, because in this case we have division.
If anything, I would say that because there's division, 0 is a great default value. Either you do float division and get some nonsense, or you do integer division and the program (usually) aborts immediately. In both cases it's completely obvious that something is wrong. The worst kind of garbage is the kind that doesn't smell like garbage.
EDIT:
Isn't this basically two assignments, or are they optimized out if nothing interesting happens between declaration and definition?
Yes, there are two assignments. Yes, the compiler is free to generate only a single mutation in this example.
Thanks to all of you for giving your input on my problem. All of you have been a great help and I will certainly be keeping everything mentioned (Tips and all) in mind for future projects.
Again, your help is greatly appreciated.