The task is: I have number a=2.7182818284590452353602875.
It is 25 digits after comma. I need to write a program which will round this number to the specified precision.
The precision is constrained to be 0 < n < 100.
For example:
Input: 0
Output: 3
Input: 25
Output: 2.7182818284590452353602875
Input: 4
Output: 2.7183
and so on.
This is my code. It works fine, BUT I am going out of the unsigned long long range if n>17...
#include <iostream>
#include <iomanip>
#include <cmath>
#include <math.h>
using namespace std;
int main()
{
double a=2.7182818284590452353602875;
double b=a;
unsigned long long c=a;
int n;
int kiek=0;
cin>>n;
while (1!=0){
b=b*10;
c=b;
if (kiek==n) break;
kiek++;
cout<<c<<endl;
}
cout<<c<<endl;
if((c%10)>4) {c=c/10+1;}
else {c=c/10;}
double atgal=1;
for(int i=0;i<n;i++){
atgal*=10;
}
cout<<endl<<atgal<<endl;
b=c;
b=b/atgal;
cout<<fixed<<setprecision(n)<<b;
}
Any suggestions about how to improve it or make it work?
The basic problem is this: The maximum accuracy of a double is about 17 digits. Even if you write double a=2.7182818284590452353602875; the last digits are ignored.
If you really need up to 100 digits og accuracy, you have to use a special library, one of these (GMP) has been mentioned in the comments.
If you do not need higher accuracy and only the output format is important for you, use this:
std::cout << std::setprecision(n) << a;
This can be done with printf precision setting:
printf("%.*f", precision, value);
The output should be rounded (not just truncated) value according to the C++ and C standards (C:7.21.6.1.8: "The value is rounded to the appropriate number of digits.").
Same result can be achieved using iostreams:
std::cout << std::fixed << std::setprecision(precision) << value;
If you want to implement it yourself, you can do so without ever converting the value to an integer, e.g. using functions such as ceil(), floor(), or modf().
Note that you can print an integer value stored in a float or double by printing it with the precision set to 0.
You can start of with the following code (no rounding, just truncating) and modify it to your needs.
double integerPart = 0;
double fractionalPart = 0;
// print the integer part
fractionalPart = modf(value, &integerPart);
printf("%.0f", integerPart);
// print the decimal point
printf(".");
// print the fractional part digit by digit
for (int i = 0; i < precision; ++i) {
fractionalPart *= 10;
fractionalPart = modf(fractionalPart, &integerPart);
printf("%.0f", integerPart);
}
Found new solution by myself ^^"
#include <iostream>
using namespace std;
int main()
{
int sk[25]={7,1,8,2,8,1,8,2,8,4,5,9,0,4,5,2,3,5,3,6,0,2,8,7,5};
int n=0;
cin>>n;
if(n==0) cout<<3;
else if (n==25) {
cout<<2<<".";
for(int i=0;i<n;i++){
cout<<sk[i];
}
}
else{
if (sk[n]>4){
if(sk[n-1]==9){
sk[n-1]=0;
sk[n-2]++;
}
else sk[n-1]++;
}
cout<<2<<".";
for(int i=0;i<n;i++){
cout<<sk[i];
}
}
return 0;
}
Thanks everyone for your replies!!! ^^
Related
I am on week 3 of C++ & I am so lost. I need to write a program with function decimal - that will return the decimal part of any non negative decimal number sent to it as input. Needs to be clear that it needs to return a double - parameters set at double.
we haven't learned about function decimal yet nor type coercion and trying to teach myself isn't going well.
Check the following example. You can try something like this that is pretty simple.
double num = 23.345;
int intpart = (int)num;
double decpart = num - intpart;
printf("Num = %f, intpart = %d, decpart = %f\n", num, intpart, decpart);
You can use string conversions:
#include <algorithm>
#include <iostream>
#include <string>
int main() {
float input = 12.123456;
std::string ip = std::to_string(input);
ip.erase(ip.begin(), --std::find(ip.begin(), ip.end(), '.'));
ip.front() = '0';
std::cout << ip;
return 0;
}
Another way would be simply substracting the floor of the number from itself...
#include <iostream>
#include <cmath>
int main() {
float input = 12.12;
std::cout << (input - std::floor(input));
return 0;
}
I'm not quit sure that I'm fully understand your question.
Are you having an hard time implementing this function?
If so - think about subtracting the integral part of the number from it, and in that way you will remain with the decimal part only.
Something like: (pseudo code)
double a = 10.85
int b = int(a)
return a - b
Think about the math.
A decimal number is of form a.b where a is the integral part and b the fractional part.
Suppose your input is N (= 1.234) then to extract say frac = .234 you just need to do is
frac = N - floor(N); remember floor(N) is of 1.000.
I think this is of help implement the code.
An example:
#include <iostream>
#include <cmath>
int main() {
float input;
std::cin >> input;
std::cout << (input - std::floor(input));
return 0;
}
or
as a function
#include <cmath>
double decimal(const double &N){
return (N - std::floor(N));
}
I am taking a double number in a string because i want to extract its value after the decimal part
I found concatenation not working properly here whats wrong with str2+=str[n-i] ?
string str;
cin>>str;
int flag=0;
string str2="";
int n=str.length();
for(int i=0;i<n;i++){
if(str[n-i]=='.'){
flag=1;
break;
}
str2+=str[n-i];
cout<<str2;
}
reverse(str2.begin(),str2.end());
int m = stoi(str2);
I am not sure if I understood you properly, but here someone asked what you are asking.
I thought on doing this:
#include <iostream>
using namespace std;
int main()
{
double num1=2.323441;
double num2=num1-(int)num1;
cout<<num2;
return 0;
}
Printing result: 0.323441
But this does not give your expected result, that I think it is: 323441.
Then I guess there are 2 possible solutions:
The first, 'dirty' and easy one is that number you got, multiply it by 10*it's length: If there are 5 decimals, multiply it by 100000. This way, you'll get the 0.323441converted to 323441.
The Second, as the answer I linked says, use round and power of:
int fractional_part_as_int(double number, int number_of_decimal_places) {
double dummy;
double frac = modf(number,&dummy);
return round(frac*pow(10,number_of_decimal_places));
}
Use std::stod to convert the string to double
Then use std::modf to decompose the floating point value into integral and fractional parts.
Or after having obtained the double value, you can just do:
double d = fpValue - (long)fpValue;
I am trying to print a number up to say 5 decimal places.
I have:
#include <iostream>
#include <cstdio>
using namespace std;
int main() {
float a = 987.65;
float b = 1.23456789;
scanf("%f %f", &a, &b);
printf("%.5f %.5f", a, b);
return 0;
}
I get the result as 987.65000 and 1.23456
I want the result to be 987.65 and 1.23456, so basically I want up to 5 i.e <=5 decimal digits in my answer.
A slightly less technical way to do it would be using setprecision, as displayed below:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
float a = 987.65;
float b = 1.23456789;
cout << setprecision(5);
cout << a << " " << b << endl;
return 0;
}
Output:
987.65 1.2346
The fundamental problem is that a computer can't exactly represent most floating point numbers.
Also, you want a complex formatting rule: if ending digits are zero, print spaces.
The problem is that your number 987.65000 could be represented as 98.6500001 and so wouldn't work with your formatting rule.
I believe you will have to write your own formatting function to achieve the functionality you are looking for.
Here's a solution that does what you want:
#include <iostream>
#include <cstdio>
using namespace std;
unsigned int numPlaces = 5; //number of decimal places
unsigned int determinePlaces (float number) {
unsigned int myPlaces = 0;
while (number != (int)(number) && myPlaces<=numPlaces-1) {
number = number*10;
myPlaces++;
}
return myPlaces;
}
int main() {
float a = 987.65;
float b = 1.23456789;
printf("%.*f %.*f\n", determinePlaces(a), a, determinePlaces(b), b);
return 0;
}
Output:
987.65 1.23457
Basically, the code keeps on multiplying the goat by 10 until the cast to an integer (essentially taking the floor value) matches the float. If it doesn't when it reaches the fifth multiplication by 10, we satisfy ourselves with a printf of 5 decimal places. Otherwise, we print the amount that was necessary to make the match to the floor value.
i know to reverse the digits of a number(integer) in c but my questions is how can we reverse the digits of a real no
for e.g 1200.23 gets reversed as 32.0021
code for integers
#include <stdio.h>
/* Iterative function to reverse digits of num(integer)*/
int reversDigits(int num)
{
int rev_num = 0;
while(num > 0)
{
rev_num = rev_num*10 + num%10;
num = num/10;
}
return rev_num;
}
/*Driver program to test reversDigits*/
int main()
{
int num = 4562;
printf("Reverse of no. is %d", reversDigits(num));
getchar();
return 0;
}
Obviously your paramater needs to be floating point type.
You could convert double to string then reverse the string then convert back to double:
#include <string>
#include <sstream>
template<typename T>
std::string toString(T t)
{
std::stringstream ss;
ss << t;
rteurn ss.str();
}
double reversDigits(double num)
{
std::string s = std::to_string(num);
std::reverse(s.begin(), s.end());
double d;
std::stringstream ss(s);
ss >> d;
return d;
}
You could use the following code, where the iostream library is being used:
#include <iostream>
#include <math.h>
using namespace std;
int main() {
double pass = 0;
double n;
double result=0;
cout << "Please enter a number to reverse" << endl;
cin >> n;
while (trunc(n / pow(10.0, pass)) > 0) {
result = fmod((n / pow(10.0, pass)), 10.0);
cout << trunc(result);
pass = pass + 1;
}
cout << endl;
system("pause");
return 0;
}
This uses the methods (12345/10), which gives you 1234.5 which then truncates into 1234. The above code also use the modulo method ('%' is the operator for modulo). For example, if you do 12345 % 10, the program displays the remainder of 12345/10, which in this case, would be 5.
I used this method in a loop to get the desired output.
PLEASE NOTE THAT I MADE THIS PROGRAM FOR A CLASS, SO IF THIS IS NOT EXACTLY WHAT YOU ARE LOOKING FOR, KINDLY DISREGARD THIS POST.
Try this code-
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
float reversDigits(float num)
{
char buffer[20],ch,*ptr;
int i,j,len;
snprintf(buffer,20,"%.3lf",num);
len = strlen(buffer);
for(i=0,j=len-1;i<j;i++,j--)
{
ch=buffer[i];
buffer[i]=buffer[j];
buffer[j]=ch;
}
buffer[len] = '\0';
return atof(buffer);
}
int main()
{
float num = 45000.062;
printf("Reverse of no. is %.5lf\n", reversDigits(num));
return 0;
}
Am passing a number with 3 digits after ., so i am using %.3lf in snprintf, if you simply use %lf means, while converting it to string it will add zeros and some numbers. To avoid that am using, else you need to do a little bit of more work to remove it!
Note: while converting string to float else float to string, in decimal position it will add some extra number or zero. The programmer need to take care of it!
[UPDATE]
This is my code:
double tmp=0;
double A=4.87149e+07;
double B=10;
double C=5.29e-06;
...
double sum=0;
ofstream M2;
M2.open("C:/capture/M2.doc");
for (i=0;i<916;i++)
{
for (int j=0;j<916;j++)
{
tmp=A*B*C;
sum= sum+tmp;
M2 << sum << "\n";
}
}
'm having what is above:
When I print the sum, it gives me a NaN result.
When I omitted the C from the sum formula, it gives me a non Nan result. Thus, I believe that the compiler is pretending that it's about a +oo/-oo multiplication (A which is so big, and C which is so small), which is not the case!
I,m dealing with important data like that.
I want to print the result at the end in a TextEdit:
plainTextEdit->setPlainText(QString::number(sum));
As soon as I reach exactly half of the i count loop (458), and j (458), the values of the Sum become equal to -1.#IND
How to handle that?
Running the following:
#include <iostream>
#include <fstream>
#include <QDebug>
int main(int argc, char *argv[])
{
double tmp=0;
double A=4.87149e+07;
double B=10;
double C=5.29e-06;
double sum=0;
std::ofstream M2;
M2.open("M2.doc");
for (int i=0;i<916;i++)
{
for (int j=0;j<916;j++)
{
tmp=A*B*C;
sum= sum+tmp;
M2 << sum << "\n";
}
qDebug() << sum;
}
}
Yields:
(lines 1-10 of M2.doc)
2577.02
5154.04
7731.05
10308.1
12885.1
15462.1
18039.1
20616.1
23193.2
25770.2
...
(lines 209760-209770)
209764 is where i = 458 and j = 458
5.40555e+008
5.40558e+008
5.4056e+008
5.40563e+008
5.40566e+008
5.40568e+008
5.40571e+008
5.40573e+008
5.40576e+008
5.40579e+008
5.40581e+008
...
(lines 839047 to 839056 aka the end)
2.16224e+009
2.16224e+009
2.16224e+009
2.16225e+009
2.16225e+009
2.16225e+009
2.16225e+009
2.16226e+009
2.16226e+009
2.16226e+009
I opened the file in Notepad++ because MS Word struggles with such long files.
tmp is probably optimized by the compiler to act almost exactly like a constant: 2577.02, or if you use printf you can see some additional precision pretty easily: 2577.018210 . The qDebug() line yields similar answers to the terminal.
Google's calculator output
double can keep track of a huge range of values:
#include <limits>
//...
printf("%g\n", std::numeric_limits<double>::min());
printf("%g\n", std::numeric_limits<double>::max());
Prints out
2.22507e-308
1.79769e+308
With my setup.
I hope that helps.