I am trying to convert latitude and longitude locations from degrees, minutes, seconds to a decimal degree number. However, when I try to do this in C++ it rounds the numbers off and doesn't give the decimal form. I think this is because of the double and int mixed operations but I can't seem to find the problem. I have included my code below. Any help would be greatly appreciated.
#include <iomanip>
#include <cmath>
#include <iostream>
#include <string>
using namespace std;
int main()
{
int user_degrees_latitude, user_minutes_latitude, user_seconds_latitude, user_degrees_longitude, user_minutes_longitude, user_seconds_longitude;
double total_minutes_latitude, total_degrees_latitude, total_minutes_longitude, total_degrees_longitude;
const double sixtieth = (1/60);
cout<< "Input latitude in degrees, minutes, seconds:";
cin >> user_degrees_latitude >> user_minutes_latitude >> user_seconds_latitude;
cout << "Input longitude in degrees, minutes, seconds:";
cin >> user_degrees_longitude >> user_minutes_longitude >> user_seconds_longitude;
total_minutes_latitude = (user_minutes_latitude + (((sixtieth)*user_seconds_latitude));
total_degrees_latitude = (abs(user_degrees_latitude) + ((sixtieth)*total_minutes_latitude));
total_minutes_longitude = (user_minutes_longitude + ((sixtieth)*user_seconds_longitude));
total_degrees_longitude = (abs(user_degrees_longitude) + ((sixtieth)*total_minutes_longitude));
cout << user_degrees_latitude << " deg " << user_minutes_latitude << "\' " << user_seconds_latitude << "\" latitude, " << user_degrees_longitude << " deg " << user_minutes_longitude << "\' " << user_seconds_longitude << "\"";
cout << " is (" << total_degrees_latitude << "," << total_degrees_longitude << ")"<<endl;
return 0;
}
1/60 is integer division, which rounds toward zero. That means your sixtieth variable is 0. You may be doing integer division in other places, too. If you want your division to be floating-point, make sure at least one argument is floating-point.
I haven't looked through all the code, but this is wrong:
const double sixtieth = (1/60);
1/60 is 0, always. This is not a mixed operation, it is integer only. You should write:
const double sixtieth = (1.0/60);
Could also do the job:
const double sixtieth = (double)1/60;
Or preferred in C++
const double sixtieth = static_cast<double>(1)/60;
const double sixtieth = 1.0/60; Is preferred here though as your are working with rvalues.
You would need double or static_cast in case of lvalues:
int numerator = 1;
int denominator = 60;
const double sixtieth = (double) numerator/denominator;
const double sixtieth = static_cast<double>(numerator)/denominator;
Related
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
int(main){
std::vector<int> vObj;
float n = 0.59392;
int nCopy = n;
int temNum = 0;;
while (fmod(nCopy, 1) != 0) {
temNum = (nCopy * 10); cout << endl << nCopy << endl;
nCopy *= 10;
vObj.push_back(temNum);
cout << "\n\n Cycle\n\n";
cout << "Temp Num: " << temNum << "\n\nN: " << nCopy << endl;
}
return 0;
}
For example, I input 0.59392 but eventually when the code reaches the bottom, where it should be going
5939.2 and then go to
59392 and stop but for some reason
it keeps going.
yeah , so you have 3 major problems in your code , first of all : it's int main() not int(main) . second : the variable named **nCopy ** is not supposed to be a integer data type , third one : you have to know what the actual representation of the float number , but first this is my solution for your problem , it's not the best one , but it works for this case :
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
int main() {
std::vector<int> vObj;
double n = 0.59392;
double nCopy = n;
int temNum = 0;;
while (fmod(nCopy, 1) != 0) {
temNum = (nCopy * 10); cout << endl << nCopy << endl;
nCopy *= 10;
vObj.push_back(temNum);
cout << "\n\n Cycle\n\n";
cout << "Temp Num: " << temNum << "\n\nN: " << nCopy << endl;
}
return 0;
}
so the explanation is as follow , the double data types gives higher precision than float , that's why I used double instead of float , but it will lack accuracy when the number becomes big .
second of : you have to how is float or double is represented , as the value 0.59392 is actually stored in the memory as value 0.593900024890899658203125 when using float according to IEEE 754 standard , so there are other types of decimals to solve this problem where the difference between them is as follow
Decimal representation gives lower accuracy but higher range with big numbers and high accuracy when talking about small numbers, most 2 used standards are binary integer decimal (BID) and densely packed decimal (DPD)
float and doubles gives higher accuracy than Decimal when talking about big numbers but lower range ,they follow IEEE 754 standard
Fixed-Point types have the lowest range but they are the most accurate one and they are the fastest ones
but unfortunately , C++ only supports float and double types of numbers , but I believe there is external libraries out there to define a decimal data type.
This question already has answers here:
What happens when I print an uninitialized variable in C++? [duplicate]
(4 answers)
Closed 1 year ago.
Background: So I basically googled projects for beginners for C++ and one recommendation was currency converter. So I decided to do this, at first I tried to do it by creating a class, objects etc but I got lost with constructors and header files etc but that's a story for another day. I am very new to programming and this is my first "project".
So I decided to go the simple route and did this:
#include <iostream>
int main(){
double euro;
//creating all the variables and conversions
double eur2dol = euro * 1.13;
double eur2pound = euro * 0.84;
double eur2rup = euro * 84.49;
double eur2yuan = euro * 7.2322769;
double eur2btc = euro * 0.0000237;
double eur2eth = euro * 0.00029956;
// creating an array with the name of the currency i am converting to
std::string curname[6] = { " Dollars\n", " Pounds\n", " Rupees\n", " Yuan\n", " Bitcoin\n", " Etherium\n"};
// creating an array with the conversions i want to do
double currencies[6] = { eur2dol, eur2pound, eur2rup, eur2yuan, eur2btc, eur2eth };
//accepting input from the user
std::cout << "Amount in euros: " << std::endl;
std::cin >> euro;
// for loop to loop through every item in the currencies array and the corresponding name of the currency from the curname array
for(int i = 0; i < 5; i++){
std::cout << euro << " Euro is " << currencies[i] << curname[i];
};
return 0;
}
Now, I know there is no point in doing this other than practicing because the values constantly change but I am getting the same result no matter the value I type in and in scientific form.
How can I fix it so i get the correct result and what is the problem?
A typical case of uninitialized variable. Here you are operating on euro variable before asking(cin) value for it, The correct implementation would be something like:
#include <iostream>
int main()
{
double euro = 0; //always put some values beforehand
//accepting input from the user
std::cout << "Amount in euros: " << std::endl;
std::cin >> euro;
//creating all the variables and conversions
double eur2dol = euro * 1.13;
double eur2pound = euro * 0.84;
double eur2rup = euro * 84.49;
double eur2yuan = euro * 7.2322769;
double eur2btc = euro * 0.0000237;
double eur2eth = euro * 0.00029956;
// creating an array with the name of the currency i am converting to
std::string curname[6] = { " Dollars\n", " Pounds\n", " Rupees\n", " Yuan\n", " Bitcoin\n", " Etherium\n"};
// creating an array with the conversions i want to do
double currencies[6] = { eur2dol, eur2pound, eur2rup, eur2yuan, eur2btc, eur2eth };
// for loop to loop through every item in the currencies array and the corresponding name of the currency from the curname array
for(int i = 0; i < 5; i++){
std::cout << euro << " Euro is " << currencies[i] << curname[i];
};
return 0;
}
Note: Uninitiazed variable is a bad practice. If you initialized the variable like double euro = 0; earlier, it will alteast not return arbitrary values even for the wrong code.
You can format your floating-point values with std::fixed and std::setprecision.
Apart from that:
Make sure you don't use euro before reading it.
Try and declare the variables as close to the place where you first use them as possible.
currencies array would probably better be called conversion_rates or something like that.
[Demo]
#include <iomanip> // setprecision
#include <ios> // fixed
#include <iostream>
int main() {
// creating all the variables and conversions
double eur2dol = 1.13;
double eur2pound = 0.84;
double eur2rup = 84.49;
double eur2yuan = 7.2322769;
double eur2btc = 0.0000237;
double eur2eth = 0.00029956;
// creating an array with the name of the currency i am converting to
std::string currency_name[6] = { "Dollar", "Pound", "Rupee", "Yuan", "Bitcoin", "Etherium" };
// creating an array with the conversions i want to do
double conversion_rates[6] = { eur2dol, eur2pound, eur2rup, eur2yuan, eur2btc, eur2eth };
// accepting input from the user
std::cout << "Amount in euros: " << std::endl;
double euro{};
std::cin >> euro;
// for loop to loop through every item in the currencies array and
// the corresponding name of the currency from the curname array
for (int i = 0; i < 6; i++) {
std::cout << std::fixed << std::setprecision(2) << euro << " Euro is "
<< std::setprecision(5) << euro * conversion_rates[i] << " " << currency_name[i] << "\n";
};
return 0;
}
You could as well slightly improve your solution and get started with concepts such as structs and STL containers just by:
defining a Currency struct, where you hold the the currency name and rate conversion from euros,
using a constant vector of currencies,
walking the vector with a range for loop.
[Demo]
#include <iomanip> // setprecision
#include <ios> // fixed
#include <iostream> // cout
#include <string>
#include <vector>
struct Currency
{
std::string name{};
double from_euro_rate{};
};
int main() {
const std::vector<Currency> currencies{
{"Dollar", 1.13},
{"Pound", 0.84},
{"Rupee", 84.49},
{"Yuan", 7.2322769},
{"Bitcoin", 0.0000237},
{"Etherium", 0.00029956}
};
// accepting input from the user
std::cout << "Amount in euros: ";
double euro{};
std::cin >> euro;
std::cout << euro << "\n\n";
// for loop to loop through every item in the currencies array and
// the corresponding name of the currency from the curname array
for (auto& currency : currencies) {
std::cout << std::fixed << std::setprecision(2) << euro << " Euro is "
<< std::setprecision(5) << euro * currency.from_euro_rate << " " << currency.name << "\n";
};
}
I converted a string to a double using ::atof, it converts OK but it rounds up the decimal and I don't want it to.
string n;
double p;
cout << "String? :" << endl;
cin >> n
p = ::atof(n.c_str());
cout << p << endl;
I usually type in numbers like 123,456.78, 12,345.87, 123,456,789.12. When I type in a smaller number like 1,234.83 or bigger the programs starts messing with the decimals.
It would be of huge help if anybody helps. Thanks!
You need to set the precision used when sending data to the output stream using setprecision as shown below.
Of course the problem with this code is that atof() isn't your best option. However, to answer your question the use of atof() doesn't matter.
#include <iomanip>
#include <iostream>
#include <string>
int main()
{
double x;
std::string n;
std::cout << "String? :" << std::endl;
std::cin >> n;
x = ::atof(n.c_str());
std::cout << std::setprecision(10) << x << std::endl;
}
To convert and catch conversion errors you could use the following:
try
{
x = std::stod(n);
}
catch(std::invalid_argument)
{
// can't convert
}
I have found a simple floating point error and I was wondering if there is a way around it. I'm compiling in Haiku OS. I'm in Haiku r1 Alpha 4
#include <iostream>
#include <cmath>
float P(float PV, float r, int t){
return(r * PV/1-pow((1+r),-t));
}
int main(void){
float PV = 100000;
float r = .005;
int t = 350;
std::cout << "A loan valued at $" << PV << " at a rate of %" << r << " with a payment period of " << t << "months would be $" << P(PV,r,t) << ", per-payment.\n";
return 0;
}
When I run it P(PV,r,t) comes out as 499.834 it should be 500. Though if I set r = 0.06 P is correct and comes out as P = 6000.
Maybe it's a compiler error. I'm using gcc version 2.95.3-haiku-121101.
The code:
return(r * PV/1-pow((1+r),-t));
should be:
return(r * PV/(1-pow((1+r),-t)));
and the expected result is about 605.718, not 500.
I have been given double x = 23.456; and two integer d and c.
I have to break it so that d gets the value 23 and c gets the value 456.
I thought of the following:-
int d;
d=(int)x;
but I cannot think of what to do with c as it is an integer and if i write
c=(x-d)*1000;
then it might be applicable for this case only and not for any other case.
Is there any way to get the number of digits after the decimal and then multiply it with equal number of zeros.
Please help!!!
You could repeatedly multiply it by 10, until there is nothing after decimal point.
double c = x - d;
while(c - floor(c) > 0.0)
{c *= 10;}
you may also need to #include <math.h> for floor function, which rounds down a number. e.g. floor(4.9) returns 4.0
Floating point calculations are little bit tricky in C++ (same is true for Java and other languages). You should avoid their direct comparison and do some other stuff to get predictable result when using them, consider:
double d1=1.1;
double d2= d1 / 10.0;
if(d2==0.11)cout << "equals" << endl;
else cout << "not equals" << endl; //result is "not equals"
d1=1.99;
float f1=0.01f;
double d3=d1+f1;
if(d3==2.0)cout << "equals" << endl;
else cout << "not equals" << endl; //result is "not equals"
d1=1.99;
d2=0.01;
d3=d1+d2-2.0;
if(d3==0.0)cout << "equals" << endl;
else cout << "not equals" << endl; //result is "not equals"
As for practical solution of the problem I can suggest 2 variants:
Var 1 is to use a function that allows to specify number of digits:
#include <iostream>
#include <cmath>
using namespace std;
void split_double(const double value, int& i_part, int& r_part,
const int max_digits_after_dp, int min_digits_after_dp){
auto powerOfTenL = [](int power){ int result = 1;
for(int i=0;i<power;++i)result *= 10;
return result;
};
//Get integral part
i_part = (int)value;
double temp = (value-i_part);
double pOfTen = powerOfTenL(max_digits_after_dp);
temp *= pOfTen;
//Get real part
r_part = round(temp);
//Remove zeroes at the right in real part
int num_of_d = max_digits_after_dp;
if(min_digits_after_dp>max_digits_after_dp)
min_digits_after_dp=max_digits_after_dp;
while (num_of_d>min_digits_after_dp) {
//If the number is divisible by 10, divide it by 10
if(0==(r_part%10)) { r_part /=10; num_of_d--;
}
else break; //Last digit is not 0
}
}
int main(int argc, char *argv[])
{
double value = 10.120019;
int ipart,rpart;
const int digitsMax = 6;
const int digitsMin = 3;
split_double(value,ipart,rpart,digitsMax,digitsMin);
cout<<"Double " <<value << " has integral part " <<ipart
<<" and real part "<<rpart<<endl;
return 0;
}
Second variant to solve the problem is to use C/C++ formatting functions like vsprintf and then split the resulting string.