Error in displaying a double value in a PlainText widget - c++

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

Related

Printing correct number of decimal points using %f 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.

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

Power function in a loop

I need help with writing power function. So, I need to write a porogramm, that will output a table from 1 to 10 in a power in a LOOP. NOT USING POW or EXP
Example of output:
0^0 == 1
1^1 == 1
2^2 == 4
3^3 == 27
4^4 == 256
(and so on, up to)
10^10 == 10000000000
NOT USING Cmath (NO POW or EXP)
for example:
e.g. power( 3.0, 5 ) will return 243 because 3*3*3*3*3 is 243
e.g. power( 173, 0 ) will return 1 because any number raised to the power of 0 is 1.
I did this Simple loop, But I have no idea how to insert power formula in it. I was also thinking about while loop
#include <iostream>
#include <string>
using namespace std;
int main(){
int number = 0, tot;
for (int table = 0; table < 10; table++)
{
tot = number * table;
cout << tot << endl;
number++;
}
}
This is a recursive function that can calculate a value raised to an integer power
double power(double base, unsigned int exp)
{
if (exp == 0)
{
return 1.0;
}
else
{
return base * power(base, exp - 1);
}
}
An iterative method to do this would be
double power(double base, unsigned int exp)
{
double product = 1.0;
for (unsigned int i = 0; i < exp; ++i)
{
product *= base;
}
return product;
}
You can test either method with something like
int main()
{
std::cout << power(5, 3);
}
Output
125
I think you already know the answer to your own question by now, but still; some hints:
Exponentiation is a repeated multiplication of the base, the repetition is defined by the exponent.
In C++, or any modern programming language, loops allow repetition of certain blocks of code: when the number of iterations is known beforehand, use the for-loop, otherwise, use the while-loop.
Combining both hints: you'll need to use a loop to repeat a multiplication; the amount of repetition (or iterations) is known beforehand, thus, a for-loop will be best.
int exponentiation(int base, int exponent) {
int result = 1;
for (int i = 0; i < exponent; ++i)
result = result * base;
return result;
}
Note: this will only suffice for integer exponentiation with positive exponents!
You can then call this function in a for-loop to let it compute the values you want:
#include <iostream>
int main(int argc, char** argv) {
for(int i = 0; i <= 10; ++i)
std::cout << exponentiation(i, i) << '\n';
}

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.

What's wrong? How can I change the "sum1" order?

I'm trying to compute the value of cos x using the Taylor series formula
infinity
---- 2k
\ k x
cos(x) = / (-1) * -------------
---- (2k)!
k=0
Shown graphically at http://ppt.cc/G,DC
Here is my program.
#include "stdafx.h"
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
double sum=0.0,sum1=0.0;
double x;
cin>>x;
for(int i=0 ; i<=10 ; i=i+1 )
{
for(int i=1 ; i<=20 ; i=i+1)
{
sum1=i*sum1+sum1;
}
sum=pow(-1,(double)i)*pow(x,(double)(2*i))/sum1+sum;
}
cout<<"Sum : "<<sum<<endl;
system("pause");
return 0;
}
The output is -1.#IND
Why?
How can I change the order of "sum1" to make it work right?
You're using i as the name of the controlling variables for two for-loops that are nested inside each other. That won't work the way you expect.
Next, sum1 is 0. No matter how many times you multiply zero by things and add zero to it, it's still zero. Then you divide by zero, which is why your final answer is NaN (not-a-number).
You need to fix the computation of factorial. Why don't you write a factorial function and test it by itself first?
You're redeclaring i inside your inner loop.
for(int i=0 ; i<=10 ; i=i+1 )
{
for(int i=1 ; i<=20 ; i=i+1)
It's been a while since I've done C, but I'm fairly sure that's an error.
Many things are a bit weird.
First : Please write ANSI C++ and try not to adopt the Microsoft Stuff, I don't really know but I guess those are for the pro's. Lets just stick to the basic stuff.
Here is what you should do :
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
double factorial(double fac)
{
if(fac == 0)
return 1;
return fac * factorial(fac - 1);
}
int main(int argc, char* argv[])
{
double sum=0.0;
double x;
cin >> x;
for ( int i = 0 ; i <= 10 ; i++ )
{
double divisor = factorial ( 2 * i );
if(divisor != 0.0)
{
sum += (double)( (pow( -1 , i ) * pow (x , 2*i )) / divisor );
}
}
cout<<"Sum : "<<sum<<endl;
//system("pause");
return 0;
}
You are not only calculating the Factorial in a weird way, but you also dont use the math operators correctly and you dont perform the math calculation as you would like to. Also the code you wrote is very weird that way because it does not make it clear (not even for you from what I understand). Look at what others commented too. They are right.
When you divide by 0, the result becomes infinity (which prints out as -1.#IND)
Muggen has given a good naive way of doing this, recomputing the whole factorial each time, and using the pow function to compute the alternating sign in the formula. But there are improvements that you can make to this code faster.
The Factorial function in one iteration of the loop can take advantage of the fact that you already multiplied most of the terms you need in the prior iterations of the loop.
The exponent (-1)^k is just a way to alternate between addition and subtraction -- you can replace that by having a variable that alternates its sign every iteration through the loop. (There are other ways to do this besides what I showed here, the point is that you don't need to call the pow() function to do it.)
The other power function x^(2k) can also be unrolled the same way.
I eliminated the first iteration of the loop, because I could calculate it in my head (it was 1.0, for any x), and set the initial value of sum to 1.0. This way factorial doesn't ever get multiplied by 0.
Try this instead
#include "stdafx.h"
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
double x;
cin>>x;
double sum=1.0, factorial=1.0, sign=-1.0, power=1.0;
for(int i=1 ; i<=10 ; i=i+1 )
{
factorial*= (2*i-1) * 2*i;
power *= x * x;
sum += sign * power/factorial;
sign = -sign;
}
cout<<"Sum : "<<sum<<endl;
system("pause");
return 0;
}
It does not appear that you are computing the factorial correctly. should be
sum1 = 1.0;
for(int k=1 ; k<=i*2 ; k=k+1)
{
sum1 *= k;
}
Notice that the factorial terminates a at your outer loop i, and not the fixed number 20, When i is 5, you don't want 20!, you want (2*5)!.