Unknown issue when calculating bouyancy in C++ - c++

I'll cut to the chase: I made a program in C++ that calculates if a spherical object is bouyant or not for a class. However, after I (from what I thought) successfully made the program in Visual Studio 2013 when I submitted it where I need to (Pearon's terrible myProgrammingLab) I get the wrong output compared to Pearon's. (IE: Mine says it floats, they say it sinks, but don't show the calculations themselves.)
Here is my code:
// Bouyancy formula:
// Fb = V * y
// Where:
// Fb is the bouyant force
// V is the volume of the submerged object
// y is the specific weight of the fluid
// If Fb is greater than or equal to the weight of the object, then it will float, otherwise it will sink.
// Sphere volume formula:
// (4/3)pi(radius cubed)
#include "stdafx.h"
#include <iostream>
#define _USE_MATH_DEFINES // Used with math.h to provide access to M_PI (used in calculation of volume)
#include <math.h> // M_PI is the value of pie (3.14..)
using namespace std;
int main()
{
float sphere_radius, sphere_weight; // Stores the value of the Sphere's radius and weight in feet and pounds respectively.
double water_weight = 62.4; // Value set to 62.4lb /cubic feet, this value is the "y" value in the above formula.
double bouyant_force, volume; // Defines Fb and V in the Bouyancy formula listed above.
cout << "Enter the radius of the sphere, in feet: ";
cin >> sphere_radius;
cout << "\nEnter the weight of the sphere, in pounds: ";
cin >> sphere_weight;
cout << endl;
volume = ((4.0 / 3.0) * M_PI * (pow(sphere_radius, 3))); // Calculates the volume of the sphere
bouyant_force = (volume * water_weight);
if (bouyant_force >= sphere_weight)
{
cout << "The sphere will float." << endl;
}
else if (bouyant_force < sphere_weight)
{
cout << "The sphere will sink." << endl;
}
else { cout << "Something went terribly, terribly, wrong.. Oh dear.."; }
char x;
cin >> x; //Waits for user to press a key before closing the program.
return 0;
}
Can anyone please help me understand why this isn't correct or why it isn't being registered as correct? Thanks in advance!

Judging by your code, the error seems to be you directly comparing the weight you accept against the buoyant force. You should be multiplying the mass you accept(the pound is a unit of mass) by g in the unit system you are using. That seems to account for you getting that it flaots while the other side calculates that it sinks.

Related

Keep asking for user input until condition met C++

I'm trying to write a script where the user will be inputting a radius and then the console will display the Volume and Surface Area of a sphere. If the input radius is negative, the user will be prompted to enter a positive radius until the condition is met. I've managed to do this but without validating the positive radius bit. How can I achieve this?
My code:
/*
* Calculate the volume and surface area of a sphere.
*
*/
#include <iostream>
#include <string>
#include <sstream>
#include <cmath> // Include cmath for M_PI constant
using namespace std;
int main()
{
const double pi = M_PI; /// Value of PI defined by C++
string input = ""; /// Temporary input buffer
double r = 0.0; /// Sphere radius
double A = 0.0; /// Sphere area
double V = 0.0; /// Sphere volume
// Request radius
cout << "Please enter radius of sphere (positive only): ";
// Get string input from user (up to next press of <enter> key)
getline(cin, input);
// Try to convert input to a double
r = stod(input);
// making sure r is positive
if (r > 0)
{
// Calculate area and volume
// Ensure floating-point division instead of integer division by
// explicitly writing 4.0/3.0
A = 4.0 * pi * r * r;
V = (4.0 / 3.0) * pi * r * r * r;
// Write out result
cout << "Sphere radius: " << r << endl;
cout << "Sphere area: " << A << endl;
cout << "Sphere volume: " << V << endl;
}
else
{
while (r < 0)
{
cout << "Please enter radius of sphere (positive only): " << endl;
}
}
// Return success
return 0;
}
First, this code is not awful. Compared to what I've seen from some other beginners, this code demonstrates that there is a decent understanding of fundamentals up to this point.
The biggest issue facing your code is the order of operations. If you want input from the user, you need to validate it before processing it. Currently, you're doing a bit of both at the same time. As mentioned, create a loop that does not exit until you have valid inputs. Then go ahead and do your math. This is separating your concerns and is a best practice.
Other nitpicks include using namespace std; as a bad practice, and one you should get out of doing sooner than later. Front-declaring your variables is also bad practice. Declare at or near first use. std::string input; suffices for a default string, there is no need to = "";.
And as I commented, stod() can throw an exception and abort your program if the input cannot be converted. You don't mention whether you're allowed to assume your input will always be a number or not so I can't assume it is.
/*
* Calculate the volume and surface area of a sphere.
*
*/
#include <cmath>
#include <iostream>
#include <numbers>
#include <string>
int main() {
double radius = 0.0;
bool inputIsInvalid = true;
do {
std::string input;
std::cout << "Enter a radius: ";
std::getline(std::cin, input);
std::size_t pos = 0;
try {
radius = std::stod(input, &pos);
} catch (const std::exception& e) {
std::cerr << "Unable to convert to double. Reason: " << e.what() << '\n';
continue;
}
// We're still not done checking. We need to ensure that the entire string
// was converted. If not, the input was invalid.
if (pos != input.length()) {
std::cerr << "Invalid characters added. Try again.\n";
continue;
}
// Making it here means a valid double was typed in.
// Now we ensure that the double is positive.
if (radius < 0.0) {
std::cerr << "Please enter a positive number. Try again.\n";
continue;
}
// Making it here should mean that we have a valid input.
inputIsInvalid = false;
} while (inputIsInvalid);
// Now we can do math!
using namespace std::numbers; // C++20 stuff for pi
double surfaceArea = 4.0 * pi * std::pow(radius, 2);
double volume = (4.0 / 3.0) * pi * std::pow(radius, 3);
std::cout << "For a sphere of radius: " << radius << '\n'
<< "Surface area: " << surfaceArea << '\n'
<< "Volume: " << volume << '\n';
}
Output:
❯ ./a.out
Enter a radius: foo
Unable to convert to double. Reason: stod: no conversion
Enter a radius: 3o
Invalid characters added. Try again.
Enter a radius: -3
Please enter a positive number. Try again.
Enter a radius: 3
For a sphere of radius: 3
Surface area: 113.097
Volume: 113.097
As you can see, all of the getting of input and validation occurs within the big do/while loop. If we are out of the loop, we know that we have a valid value, and doing the math is now very straightforward.
There is no need for complicated statements.
You just need to understand that IO operation notice, when there was a problem. And then they set failure bits, which you can check.
Please look in the CPP reference at this link. There is a long description of what could happen and what failure bit will be set and how it can be tested.
So, if you use for example the stand extraction operator >> like in std::cin >> radius then this operator will try to read a value from the console and convert it to a double. If it cannot do that, because you entered for example "abc" instead of a number, a failure bit will be set. The std::cinis then in state fail and does not work any longer.
If you want to continue to use std::cin then you must clear the fail bits with the clear() function. So, you need to write std::cin.clear();.
But this is not sufficient. There might be still some other characters in the input buffer. And those need to be removed. Imagine that you enter "XYZ" instead of a number, then std::cin will go into failure state after reading the first character 'X'. We need to eliminate all the wrong characters, because otherwise, they will be read again with the next >> operation.
For this we have the function ignore. Please read here about the function and look at the example at the bottom of the page. Exactly what you need.
Next: How can we check for an error of an IO operation?
You may have heard that we can chain IO operations. For example: int a,b; std::cin >> a >> b; or, for the output case std::cout << value << "\n";
Why does this work? You need to understand the the extraction and inserter operator >> and << return a reference to the stream for which they have been called.
So, std::cin >> a; will return a reference to std::cin. And that is the reason why you can chain IO operations.
std::cin >> a >> b; will first do std::cin >> a which will return std::cin. The rest of the expression will now be std::cin >> b;. also this will be performed and again std::cin will be returned.
And this we can use. The basic:ios has 2 operators to check the failure state.
the bool operator
the not operator !
So, you can check the state of std::cin simply with if (std::cin). And because the if-statement expects a bool expression, it will call the streams bool operator. And with that get the state.
And now, what we learned above: if (std::cin >> a) will try to read a value into "a" then return std::cin and then its bool operator is called.
Now we found a possibility to check for a correct IO operation with if (std::cin >> radius) But of course we can do more test in the if statement. You have often seen and && or or|| operators in conditions. You can make use of it. And especially you can make use of boolean shortcut evaluation.
Meaning, if the outcome of a condition is already clear by evaluation the first term, then the second term will not be evaluated.
So, we can write if ((std::cin >> radius) and (radius > 0.0)) to check for a valid input. If the reading of the input fails, then the check for greater than 0 will not be executed. It will only be executed, if the input was successful.
With all the above, we can now draft the below very simple solution:
#include <iostream>
#include <limits>
int main() {
double radius = 0.0;
bool valueOK = false;
while (not valueOK) {
std::cout << "\n\nInsert radius. A positive value: ";
if ((std::cin >> radius) and (radius > 0.0))
valueOK = true;
else {
std::cout << "\n\n***Error: invalid input\n";
}
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
const double PI = 3.14159265358979323846;
std::cout << "\n\nSphere Radius:\t" << radius
<< "\nSphere area:\t" << 4.0 * PI * radius * radius
<< "\nSphere volume:\t" << 4.0 / 3.0 * PI * radius * radius * radius << '\n';
}
No need for complicated statements.
You could use std::from_chars within an infinite loop to read a radius of type double (see here):
It receives a couple of const char* to the beginning and end of the string you want to parse, and a reference to a double value (that will be set if the parsing went OK).
It returns a pointer pointing to the first character that didn't match the pattern for a double value, and an error.
If the error is "empty" (just value-initialized), and the pointer points to the end of the input string, it means that all the characters were used to parse the double value (i.e. there were no extra characters at the beginning or at the end in the input string).
[Demo]
#include <charconv> // from_chars
#include <iostream> // cin, cout
#include <numbers> // Include cmath for M_PI constant
#include <sstream>
#include <string> // getline
#include <system_error> // errc
int main() {
// Request radius
double r = 0.0; /// Sphere radius
for (;;) {
std::cout << "Please enter radius of sphere (positive only): ";
// Get string input from user (up to next press of <enter> key)
std::string input = ""; /// Temporary input buffer
getline(std::cin, input);
std::cout << input << "\n";
// Try to convert input to a double
auto [ptr, ec] = std::from_chars(input.data(), input.data() + input.size(), r);
if (ec != std::errc{} or ptr != input.data() + input.size() or r < 0) {
std::cout << "Invalid input: '" << input << "'\n";
} else {
break;
}
}
// Calculate area and volume
// Ensure floating-point division instead of integer division by
// explicitly writing 4.0/3.0
double A = 4.0 * std::numbers::pi_v<double> * r * r; /// Sphere area
double V = (4.0 / 3.0) * std::numbers::pi_v<double> * r * r * r; /// Sphere volume
// Write out result
std::cout << "Sphere radius: " << r << "\n";
std::cout << "Sphere area: " << A << "\n";
std::cout << "Sphere volume: " << V << "\n";
// Return success
return 0;
}
// Outputs:
//
// Please enter radius of sphere (positive only): -5
// Invalid input: '-5'
// Please enter radius of sphere (positive only): hola
// Invalid input: 'hola'
// Please enter radius of sphere (positive only): 25abc
// Invalid input: '25abc'
// Please enter radius of sphere (positive only): 1.5
// Sphere radius: 1.5
// Sphere area: 28.2743
// Sphere volume: 14.1372

C++: Is there a way to distinguish a user input if its on centimeter or not?

Heres the given:
Write a program to compute for the surface area and volume of a sphere if the unit of the radius
is in centimeters (cm).
Filename: exer10.cpp
Formulas: area = 4*pi*radius2
Volume = (4/3)*pi*radius3
I was skeptical because of the "if" on the given as you read it, now I don't know if what I did is right. But I have some ideas on how to do it
I Have a 2 ideas in mind 1st is where if I input a value there will be a formula to distinguish if that value is in centimeter, the thing is I don't know how.
2nd idea is I will use the if else method where after I input a value, it will ask if its in centimeter or not, if I type "Y" it will do its thing and continue its computation but if I type "N" it`ll will not compute and end the program.
Any suggestion guys?
By the way here's my code (My given ideas are not written here)
#include <iostream>
using namespace std;
int main()
{
float radius, area, volume;
cout << "This program computes for the surface area and volume of a sphere (centimeters)"
"\n\n";
cout << "Input the radius of a sphere    : ";
cin >> radius;
area = (4 * 3.1416 * radius * radius);
volume = (4 / 3) * (3.1416 * radius * radius * radius);
cout << "The surface area of a sphere is : " << area << "\n";
cout << "The volume of a sphere is       : " << volume;
return 0;
}
You can ask the user to input the unit. Consider this example, if it's in centimeters then perform the operation/task or else exit the program.
#include <iostream>
#include <string>
#include <cstdio>
int main() {
int radius;
std::string unit;
std::cout << "Enter radius of sphere in centimeters (e.g. 5 cm) : ";
std::cin >> radius >> unit;
if (unit != "cm") {
std::cout << "\nPlease enter in centimeters (e.g. 5 cm)";
exit(1);
}
// perform operation
return 0;
}

Problem rounding numbers in C++ with a BMI calculator

I', trying to make a simple BMI calculator using C++. When I input my personal height and weight, I get the correct result but I can't round the number to the nearest whole number. I looked up some videos and some articles and many of them suggested using the "round()" function. I tried that and the result I got was 0!
All feedback helps. Thanks!
#include <iostream>
#include <cmath>
using namespace std;
float Calculate(float kilo, float centimeter)
{
float meter = centimeter * 100;
return kilo / (meter * meter);
}
int main()
{
float kilo, centimeter;
float bmi;
cout << "BMI calculator." << endl;
cout << "Please enter your weight in kilograms. ";
cin >> kilo;
cout <<"Please enter your height in centimeters. ";
cin >> centimeter;
bmi = Calculate(kilo, centimeter);
cout << round(bmi) << endl;
return 0;
}
Your formula for calculating BMI is wrong just change the line float meter = centimeter/100;.
because according to your formula any number multiplied by 100 and then squared becomes so big that you get very small floating point number after the division with weight that is eventually rounded that's why you always get 0 in output.

How to solve c++ unwanted mathematical error

I'm new to c++ so what I like to do is make numerous calculators of anything, varying from area calculators to quadradic formula and etc. Anyways I'm creating a triangle area calculator but there is one small problem but first here's my code:
#include <iostream>
#include <cmath>
using namespace std;
int triangle()
{
int base;
int height;
int area;
cout << "Enter base: ";
cin >> base;
cout << "Enter height: ";
cin >> height;
area = base * height /2;
cout << area;
return area;
}
int main ()
{
cout << "Formula Calculator \n";
cout << triangle();
return 0;
}
The input is this:
Enter base: (I enter 4)
Enter height: (I enter 5)
1010
As you can see the 5 * 4 * 1/2 is not 10 for some reason every number that the area is, is always digit doubled if you know what I mean for ex if the area is 20 the program will show 2020, please help.
You output the area twice.
cout << area; // here's once
cout << triangle(); // here's twice
I would suggest rethinking your code. Should the triangle function just compute the area or should it ask for input and do output? If the latter, why cout << triangle();?
When you are inside your function triangle(), check it's 2nd last line, It is cout<<area, let's say you have given input 4 and 5 so inside the body of the function, at cout<<area it will output the area. Now it returns area which is then outputted by 2nd last line of your program i.e cout<< traingle()//return value is outputted so that's why we are seeing 2 outputs. It is not only in the case of 4 and 5, but it will also output area 2 times in every case.

C++: Buoyancy program does not output as planned

I attempted to make a program that asks for the input for the radius of a sphere, and the weight of the sphere. it uses these inputs to calculate the buoyancy of the sphere and the program determines whether or not it can float in water. However, I keep getting "6.95207e-308", no matter what my inputs are
These are the instructions for the programming assignment:
"Buoyancy is the ability of an object to float. Archimede's Principle
states that the buoyant force is equal to the weight of the fluid that
is displaced by the submerged object. The buoyant force can be
computed by:
buoyant force = (object volume) times (specific gravity of the fluid)
If the buoyant force is greater than or equal to the weight of the
object then it will float, otherwise it will sink.
Write a program that inputs the weight (in pounds) and radius (in
feet) of a sphere and outputs whether the sphere will sink or float in
water. Use 62.4 lb/cubic foot as the specific weight of water. The
volume of a sphere is computed by (4/3)π times the radius cubed."
This is my code:
//Written by: Edward Santiago
//Assignment: HW_03_No14.cpp
//Class: CO SCI 243
//Date: October 17, 2014
//Description: Prime Numbers
#include <iostream>
#include <cmath>
#include <math.h>
using namespace std;
double sphere_volume (double);
double buoy_force (double,double);
int main ()
{
double rad,volume,force,buoyancy;
double weight;
double water = 62.4;
cout << "~~Buoyancy calculator~~" << endl;
cout << "Please enter the radius of your sphere" << endl;
cin >> rad;
cout << "Please enter the weight of your sphere" << endl;
cin >> weight;
volume = sphere_volume(rad);
buoyancy = buoy_force(volume,weight);
cout << "The force of your sphere is "<<force<<endl;
if (force <= water)
cout << "Your sphere will float in the water"<<endl;
else
cout <<"Your sphere will sink :( "<<endl;
return 0;
}
double sphere_volume (double radius)
{
double vol;
vol = ((4/3) * (M_PI) * (pow(radius,3)));
return vol;
}
double buoy_force (double vol,double weight)
{
double force;
force = vol * weight;
return force;
}
You never initialize force.
buoyancy = buoy_force(volume,weight);
cout << "The force of your sphere is "<<force<<endl;
Change the assignment to force = buoy_force(volume, weight).
You assigned the big answer to "buoyancy" and then printed out "force".
Add
force=buoyancy;
just before printing force. This is because force is uninitialized and you are trying to print it.