Printing correct number of decimal points using %f c++ - c++

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.

Related

Using function decimal to return only decimal of input as double C++

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));
}

Rounding the number to the specified precision

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!!! ^^

C++ doesn't show numbers with big decimals

I wrote a program of which the result made me wonder.
I have a double number with 3 decimals, but I need to change it to 2 decimals.
First I multiplied it with 100, then I changed it to an int, then I divided it by 100, but I don't know why
the result is wrong
input: 9.857
output is: 9.8499999999999996
Here is my code:
#include <iostream>
#include <cstdio>
using namespace std;
int main(){
double sum = 9.857, temp = 0;
temp = int(sum * 100);
temp = int(temp);
sum = temp / 100;
printf("%.16f\n", sum);
}
input: 9.857
output is: 9.850000000000000
Second code:
#include <iostream>
#include <cstdio>
using namespace std;
int main(){
double sum = 9.857, temp = 0;
temp = int(sum * 100);
temp = int(temp);
sum = temp / 100;
printf("%.15f\n", sum);
}
Why are the answers of these two code snippets different?
In addition to floating point arithmetic, you are also using the unsafe printf-family of functions despite including <iostream>. The proper way to limit the precision of your output value in C++ is to set the ostream's precision value:
Example
#include <iostream>
int main()
{
double sum = 9.857, temp = 0;
std::cout.precision(4);
std::cout << "Value = " << sum << std::endl;
std::cout.precision(3);
std::cout << "Value = " << sum << std::endl;
std::cout.precision(2);
std::cout << "Value = " << sum << std::endl;
return 0;
}
If you wanted to do it in C, it would look like this:
Example
#include <stdio.h>
int main()
{
double sum = 9.857, temp = 0;
printf("Value = %.3f\n", sum);
printf("Value = %.2f\n", sum);
return 0;
}
If you are looking for exact values, floating point types are not the right type to use due to how they are stored (they will not be exact). This means that attempting to show 15-digits beyond the decimal is not likely to give you the same result as your input for many cases.

Error in displaying a double value in a PlainText widget

[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.

c++ convert a fractional part of a number into integer

I needed to convert a fractional part of a number into integer without a comma,
for example I have 3.35 I want to get just 35 part without zero or a comma,
Because I used the modf() function to extract the the fractional part but it gives me a 0.35
if there is any way to do that or to filter the '0.' part I will be very grateful if you show me how with the smaller code possible,
A bit more efficient than converting to a string and back again:
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));
}
#include <iostream>
#include <cmath>
double round(double r) {
return (r > 0.0) ? std::floor(r + 0.5) : std::ceil(r - 0.5);
}
double floor_to_zero(double f) {
return (f > 0.0) ? std::floor(f) : std::ceil(f);
}
double sign(double s) {
return (s < 0.0) ? -1.0 : 1.0;
}
int frac(double f, int prec) {
return round((f - floor_to_zero(f)) * prec) * sign(f);
}
int main() {
double a = 1.2345;
double b = -34.567;
std::cout << frac(a, 100) << " " << frac(b, 100) << std::endl; // 23 57
}
another solution
int precision= 100;
double number = 3.35;
int f = floor(xx);
double temp = ( f - number ) * -1;
int fractional_part = temp * precision;
IF you need it as a string, a quite easy C style solution would be (should work for variable number of decimal places):
double yourNumber = 0.35f;
char buffer[32];
snprintf(buffer, 32, "%g", yourNumber);
strtok(buffer, "."); // Here we would get the part before . , should still check
char* fraction = strtok(NULL, ".");
int fractionAsInt = atoi(fraction);
This example lacks error handling in case of a bad string and is not feasible if you just need a fixed number of decimal places, since the arithmetic approaches work better there.
Something like this should work:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
static int get_frac(double value, unsigned short precision)
{
return (int)((value - (long)value) * pow(10, precision));
}
static int get_frac_no_trailing_zeros(double value, unsigned short precision)
{
int v = get_frac(value, precision);
while (v % 10 == 0)
v /= 10;
return v;
}
int main(int argc, char *argv[])
{
double v;
v = 123.4564;
printf("%.4f = %d\n", v, get_frac(v, 2));
printf("%.4f = %d\n", v, get_frac(v, 4));
printf("%.4f = %d\n", v, get_frac(v, 6));
printf("%.4f = %d\n", v, get_frac_no_trailing_zeros(v, 6));
return EXIT_SUCCESS;
}
You may also want to either avoid calling pow by having a user supply a number in a power of 10 in a first place, or use a lookup table.
Using some stl magic, here is the sample code:
typedef std::pair<int, int> SplitFloat;
SplitFloat Split(float value, int precision)
{
// Get integer part.
float left = std::floor(value);
// Get decimal part.
float right = (value - left) * float(std::pow(10, precision));
return SplitFloat(left, right);
}
It can be improved, but is pretty straightforward.
I just did something close to what you are trying to do, though I'm still pretty new. None the less, maybe this will help someone in the future as I landed here looking for results for my problem.
The first step is making sure that the variable that contains 3.35 is a double, but that's probably obvious.
Next, create a variable that is only an integer and set it's value equal to the value of the double. It will then only contain the whole number.
Then subtract the whole number (int) from the double. You will be left with the fraction/decimal value. From there, just multiply by 100.
Beyond the 100ths decimal value, you would have to do a little more configuring obviously, but it should be fairly simple to do with an if statement. If the decimal value is greater than .99, multiply 1000 instead etc..
Here's how I would do it.
#include <sstream>
#include <string>
int main()
{
double d = yourDesiredNumber; //this is your number
std::ostringstream out;
out << setprecision(yourDesiredPrecision) << std::fixed
<< std::showpoint << d;
std::istringstream in(out.str());
std::string wholePart; //you won't need this.
int fractionalPart;
std::getline(in, wholePart, '.');
in >> fractionalPart;
//now fractionalPart contains your desired value.
}
I'm pretty sure that instead of two different istringstream and ostringstream objects you could have gotten away with just one stringstream object, but I am not sure about the details (never used that class) so I didn't use it in the example.