Find Pi to the Nth Digit - c++

I'm beginning to teach myself C++ until my class starts in the fall. I was wondering if you might be able to help me come up with a better way to ask the user for the number of digits they want for the number pi, and then display it. My problem is that using pi = atan(1)*4 isn't precise past around 10 decimal places. Is there a better built in number that has pi to at least 20 decimal places? Here is what I have so far, thanks!
#include <iostream>
#include <string>
#include <iomanip>
#include <ios>
#include <sstream>
using namespace std;
using std::setprecision;
using std::streamsize;
int main()
{
double pi = atan(1)*4;
int input = 0;
while(true)
{
cout << "Please enter how many digits of PI you would like to see (Max 20): ";
cin >> input;
if(input > 0 && input <= 20)
{
break;
}
else
{
cout << "That's not a valid number! Try again." << endl;
}
}
streamsize prec = cout.precision();
cout << setprecision(input);
cout << "Here you go: " << pi <<endl;
system("pause");
}

The easiest way to do this would probably just have a std::string containing the digits that you want ("3.14159265358979323846264338327950288419"), and then just print the first input digits beyond the decimal point.

I would say that this is less of a C++ problem, and more of a math problem. There are several infinite series that converge to the true value of Pi very quickly. Have you looked at the Wikipedia article on this topic?
As for being precise to nine or ten digits, you may run into rounding issues using double (especially with certain calculation methods). I would consider looking into an arbitrary-precision math library. I'm a big fan of MPFR, but I'm sure Boost has something analogous if that's more your thing (keep in mind that Boost is a C++ library, whereas MPFR is a C library [although you can, of course, use C code from C++]).
MPFR does have a C++ wrapper, but in general I don't enjoy using it as much as the C functions, since the last time I looked at it (admittedly, a while ago), it wasn't quite as feature-complete.
It's probably worth noting also that, since your goal is to learn C++, and not to learn how to efficiently approximate Pi, it might be preferrable to solve this problem by e.g. just retrieving the first n-digits from a hard-coded string instead, as Chris said.

A double will have 53 bits of precision. Each bit gives about 1/3 of a decimal digit (log(10)/log(2) to be precise), which means that we get approximately 53/3 digits out of a double. That should give 17 digits (including the 3 at the beginning). It's plausible that atan(1) isn't giving quite all the digits of pi/4 either (because atan as well as any other trigonometric function is an approximation).
If you want many more digits than about 12-14 digits, you will need to use a "big number" library, and there are a number of "clever" ways to calculate the decimals of PI.

Related

Count the length of a number

Hello I would like to count the number there is in a number I mean if I have this double 78.23 the functions would return 4 if I have 145.123 I would got 6. Is it possible to do this with C++ ?
Thank you !
Precision - in the sense that you are asking about it - is as much a property of the output stream, as of the value being output. Assuming you are outputting using an C++ ostream (ofstream, ostrstream, etc), look up properties ios_base::precision, ios_base::width, etc or stream manipulator like setprecision. If you are using C I/O (sprintf(), etc), the answer depends upon modifiers specified for the %f format.
So the method to get the value you seek would probably be to output the value using your chosen method (stream manipulators, format specifiers) to a string. Then compute the length of the string, subtract one for every trailing 0, the decimal point, etc.
Also, floating point variables with a base 2 mantissa (which includes most real-world floating point representations) cannot exactly represent any value that is not a sum of integral powers of 0.5 (the stored value is an approximation). Among other things, this means a floating point variable cannot exactly represent values like 0.1 and 0.01. Both of your sample values 78.23 and 145.123 cannot be represented exactly using floating point variables. Which is part of the reason why the answer to questions like yours depends on how the variable is output, as much as the value itself.
the easy way of doing this is to just enter the number as a string and use .length()
#include <iostream>
#include <string>
#include <conio.h>
using namespace std; int main() {
string number;
cout << "Enter a number: ";
cin >> number;
cout << "length is " << number.length();
_getch();
return 0;
if you need it strictly to be with integers and doubles then you'll have to create a mathematical algorithm.

How do I store numbers in C++ without the decimals being truncated?

I am writing a simple percentage calculator in C++. I am a beginner and I can't figure out how to store the decimals without them being removed. If I enter any input that results in a decimal, it changes to a 0 and messes up the rest of the calculation.
#include <iostream>
using namespace std;
int main ()
{
int a;
int b;
int c;
int result;
cout << "Enter your goal: ";
cin >> a ;
cout << "Enter the amount achieved: ";
cin >> b ;
c = b / a;
result = c * 100;
cout << result;
cin.get();
}
I know that the integer c is where the problem is, but I have know idea what I need to do to make this work. I don't know why I am having trouble with what should be a simple program.
Check out the basic numeric types:
int -> integer numbers
float -> single precision floating point numbers
double-> double precision floating point numbers
You need the float or double ones for that operations.
Check some useful documentation:
http://en.cppreference.com/w/cpp/language/types
https://en.wikipedia.org/wiki/C_data_types
This looks like a case of a solution working for the wrong reasons. Like #MikeCAT says in his answer, if you multiply by 100 first, it "works" (i.e. the result you get is not 0). While that might look like a solution, it isn't, especially since multiplication should be commutative, right? It doesn't make sense for the order of factors to change the answer. It shouldn't.
It works, right?
Well, yes, and no. The real problem (like others have said) in your question is that you're not using data types the right way. As I understand, you don't have much programming experience, which is cool. Welcome to programming! Computers are dumb, and when I say "dumb", I mean oh-my-god-you-are-the-stupidest-machine-ever dumb.
A number is not always just a number
As other answers have mentioned, there are two main ways of handling numbers in programming (computers are so dumb that they need to be told which one to use): integers and floating points. Integers (as you probably know) are for the numbers in the set {0, 1, -1, 2, -2, ...}. They cannot represent rational numbers. Floating point numbers (or floats), represent rational numbers, up to a certain degree of exactitude. The math behind floats is a bit complex (and I'm definitely not an expert), but basically, they allow you to represent a rational number up to a number of decimal points (since computer memory is limited, it is not possible to represent an infinite number of decimals). doubles like others have mentioned, pretty much just double the amount of decimal points you can specify. Since memory was much more limited before, it was common to use float, but you can use double know without much worrying about it - and it's going to give you better results for calculation. Note that there are some specific problems you can run into with doubles and floats rounding and overflowing and all sorts of crazy stuff (which you should read about if you're doing more serious calculation), but in general, they're fine for most rational calculations.
The difference between these two data types is in the way they are represented in memory, when translated to binary. Computers understand binary only, so everything needs to be translated so they can work with it. You don't need to know the details right now, but in essence, the data type you choose really makes a difference.
So what do I do?
Well, you have to know what sort of calculation you want to do, and what you want to use it for. Sometimes, the language in which you program automates this choice (or chooses the more powerful version) for you, but in C++, that is not the case. In C and C++, where your programming is closer to what computers understand than in other languages, you usually have to be much more specific (and careful) when programming. That's also why programming in C and C++ tends to be considered as more difficult than others: less things are automated for you.
In your case, you probably don't really want integers. When you use integers, it's impossible to use decimals. So, when you divide, for instance 2 / 3, the answer is 0 (with a remainder of 2) - and when you multiply by 100 remains 0. We all know it's not really 0, but the computer cannot represent 0.66 in an int. It just can't. So, it gives you the closest thing, which is 0. Now, if you do something like 100 * 2 / 3, then the answer would be 66.6..., which is represented as 66. The .6 is lost, but the answer is no longer 0. So, it appears to "work", but it doesn't, really. Even for percentages, there is a pretty big difference between 66% and 66.66%.
If you used doubles, however, the story would be different. In that case, 2 / 3 would be 0.6..., and when you multiply that by 100, then you get 66.6..., which is the right answer. That would be the exact same result as doing 100 * 2 / 3.
Putting it all together
So, your program should look like this:
#include <iostream>
using namespace std;
int main ()
{
double a;
double b;
double c;
double result;
cout << "Enter your goal: ";
cin >> a ;
cout << "Enter the amount achieved: ";
cin >> b ;
c = b / a;
result = c * 100;
cout << result;
cin.get();
}
This would work the right way, and you will have learned something cool in the process. Good luck!
You should use the "float" or "double" type to work with decimal point numbers.
A quick fix for your code is to change those int type variables to "float".
I also suggest you to read more about C++, like this post http://www.cplusplus.com/doc/tutorial/variables/
Try this (multiply 100 before dividing b by a):
#include <iostream>
using namespace std;
int main ()
{
int a;
int b;
int c;
int result;
cout << "Enter your goal: ";
cin >> a ;
cout << "Enter the amount achieved: ";
cin >> b ;
c = b / a;
result = b * 100 / a;
cout << result;
cin.get();
}
Easiest way, if you do not need a perfect rounded result, is to first multiply with 100 and then divide by a
result = (b*100)/a;
If you need a rounded value you can first multiply all bei 10 and then round it manually
result = (((b*10*100)/(a*10))+5)/10
this statement can be shortened but I keep it that way to make it easier to understand.
The easiest way of yourse is using double values instead of int. But I do not know if it is your intense
You probably want to use floating point arithmetic something like:
double c = static_cast<double>(b) / a;
But if you just want the percentage as an integer, multiply by 100 before you divide:
int c = 100 * b / a;

Is there a bug in numeric_limits or am I just confused?

I encountered some queer behavior, at least in my own mind, while debugging some code involved with determining if an addition operation would underflow a double. Here is an example program demonstrating what I found.
#include <iostream>
#include <limits>
using std::cout;
using std::endl;
using std::numeric_limits;
int main()
{
double lowest = numeric_limits<double>::lowest();
bool truth = (lowest + 10000) == lowest;
cout << truth << endl;
}
When I execute this code, I get true as a result. Is this a bug or am I just sleep deprived?
The smallest double is:
-1.7976931348623157e+308
Adding 10,000, or 1e4, to this would only have a noticeable effect if doubles had 300+ digits of precision, which they most definitely do not. Doubles can only hold 15-17 significant digits.
The difference in magnitude between these two numbers is so great that adding 10,000 does not produce a new number. In fact, the minimum double is such a huge number (so to speak) that you could add a googol to it—that's 1 followed by a hundred zeros—and it wouldn't change.

C++: Cosine is wrong, should be zero. 3Pi/2

I have a program and I'm trying to calculatecos(M_PI*3/2) and instead of getting 0, as I should, I get -1.83691e-016
What am I missing here? I am in radians as I need to be.
First, M_PI is not a very portable macro and is usually good to about 15 decimal places, depending on the compiler you use - my guess is you're using Microsoft's C++ compiler.
Second, if you want a more accurate (and portable) version, use the Boost Math library:
http://www.boost.org/doc/libs/1_55_0/libs/math/doc/html/math_toolkit/tutorial/non_templ.html
Third, as Kay has pointed out, pi in itself is an irrational number and therefore no amount of bits (or digits in base 10) would be enough to accurately represent it. Therefore, What you're actually calculating is not cos(3*pi/2) exactly, but "the cosine of 3/2 times the closest approximation of pi given the bits required", which will NOT be 3 *pi/2 and therefore won't be zero.
Finally, if you want custom precision for your mathematical constants, read this: http://www.boost.org/doc/libs/1_55_0/libs/math/doc/html/math_toolkit/tutorial/user_def.html
The number M_PI is only an approximation of π. The cosine that you get back is also an approximation, and it's a pretty good one - it has fifteen correct digits after the decimal point.
Given the discrete nature of double values, the standard margin of error against which to test for numerical equality is numeric_limits<double>::epsilon():
#include <iostream>
#include <limits>
#include <cmath>
using namespace std;
int main()
{
double x = cos(M_PI*3/2);
cout << "x = << " << x << endl;
cout << "numeric_limits<double>::epsilon() = "
<< numeric_limits<double>::epsilon() << endl;
cout << "Is x sufficiently close to 0? "
<< (abs(x) < numeric_limits<double>::epsilon() ? "yes" : "no") << endl;
return 0;
}
Output:
x = << -1.83697e-16
numeric_limits<double>::epsilon() = 2.22045e-16
Is x sufficiently close to 0? yes
As you can see, the absolute value of -1.83697e-16 is within the margin of error given by epsilon 2.22045e-16.
Pi is irrational, the computer cannot represent the number perfectly. The small error to the "correct" value of pi causes the error in the output. Being 1.83691 × 10-16 off is still pretty good.
If you want to learn more about the restrictions of actual system and the impact of little errors in the input, then refer to http://en.wikipedia.org/wiki/Numerical_stability.

Maximum Width of a Printed Double in C++

I was wondering, how long in number of characters would the longest a double printed using fprintf be? My guess is wrong.
Thanks in advance.
Twelve would be a bit of an underestimate. On my machine, the following results in a 317 character long string:
#include <limits>
#include <cstdio>
#include <cstring>
int main()
{
double d = -std::numeric_limits<double>::max();
char str[2048] = "";
std::sprintf(str, "%f", d);
std::size_t length = std::strlen(str);
}
Using %e results in a 14 character long string.
Who knows. The Standard doesn't say how many digits of precision a double provides other than saying it (3.9.1.8) "provides at least as much precision as float," so you don't really know how many characters you'll need to sprintf an arbitrary value. Even if you did know how many digits your implementation provided, there's still the question of exponential formatting, etc.
But there's a MUCH bigger question here. Why the heck would you care? I'm guessing it's because you're trying to write something like this:
double d = ...;
int MAGIC_NUMBER = ...;
char buffer[MAGIC_NUMBER];
sprintf(buffer, "%f", d);
This is a bad way to do this, precisely because you don't know how big MAGIC_NUMBER should be. You can pick something that should be big enough, like 14 or 128k, but then the number you picked is arbitrary, not based on anything but a guess that it will be big enough. Numbers like MAGIC_NUMBER are, not suprisingly, called Magic Numbers. Stay away from them. They will make you cry one day.
Instead, there's a lot of ways to do this string formatting without having to care about buffer sizes, digits of precision, etc, that let you just get on with the buisness of programming. Streams is one:
#include <sstream>
double d = ...;
stringstream ss;
ss << d;
string s = ss.str();
cout << s;
...Boost.Format is another:
#include <boost\format\format.hpp>
double d = ... ;
string s = (boost::format("%1%") % d).str();
cout << s;
Its defined in limits:
std::cout << std::numeric_limits<double>::digits << "\n";
std::cout << std::numeric_limits<double>::digits10 << "\n";
Definition:
digits: number of digits (in radix base) in the mantissa
Equivalent to FLT_MANT_DIG, DBL_MANT_DIG or LDBL_MANT_DIG.
digits10: Number of digits (in decimal base) that can be represented without change.
Equivalent to FLT_DIG, DBL_DIG or LDBL_DIG for floating types.
See: http://www.cplusplus.com/reference/std/limits/numeric_limits/
Of course when you print stuff to a stream you can use the stream manipulators to limit the size of the output.
you can decide it by yourself..
double a=1.1111111111111111111111111111111111111111111111111;
printf("%1.15lf\n", a);
return 0;
./a.out
1.111111111111111
you can print more than 12 characters..
If your machine uses IEEE754 doubles (which is fairly widespread now), then the binary precision is 53 bits; The decimal equivalent is approximately 15.95 (calculated via logarithmic conversion), so you can usually rely on 15 decimal digits of precision.
Consult Double precision floating-point format for a brief discussion.
For a much more in-depth study, the canonical paper is What Every Computer Scientist Should Know About Floating-Point Arithmetic. It gets cited here whenever binary floating point discussions pop up, and is worth a weekend of careful reading.