Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I am trying to get a integration program running but I keep getting the nan when computing. i have no idea whats wrong with my code.
#include <iostream>
#include <cmath>
using namespace std;
int main(){
cout << "For integration up \n";
for (int z=0; z<=5; z++){
int i=1;
float nathan [6] = {pow(10,2), pow(10,3), pow(10,4), pow(10,5),pow(10,6), pow(10,7)};
int h= nathan[z];
int n=0;
double x= (h-i)/h;
double y= (h-i)/h;
double t= 0;
while(n <= h){
if(n == 0){
t += (x/3)*(1/y);
}else if(n==h){
t+= (x/3)*(1/y);
}else if(n%2 ==1){
t+= (4*x/3)*(1/y);
}else{t+= (2*x/3)*(1/y);
}
y= x+y;
n = n+1;
}
cout << "The integration of 1/x for N = "<< nathan[z] <<" is equal to " << t << endl;
}
}
can someone please help me out with this...
With
int i = 1;
int h = nathan[z];
The term
(h - i) / h
invokes integer division, and since both h - i and h are positive and h - i is smaller than h, this results in an integer zero.
After
double x= (h-i)/h;
double y= (h-i)/h;
then, both x and y are zero, and from there all terms in
if(n == 0){
t += (x / 3) * (1 / y);
} else if(n == h) {
t += (x / 3) * (1 / y);
} else if(n%2 == 1) {
t += (4 * x / 3) * (1 / y);
} else {
t += (2 * x / 3) * (1 / y);
}
result in zero times infinity, which is not a number (i.e., nan). Once you're down that sinkhole, you're never coming back.
Make h a double to avoid this.
Side note: Please, please, please learn to properly indent your code. Your eventual coworkers are going to skin you alive if you don't, and they'll be right.
it s because x and y are always 0 in your code because h is int. When you do (h-i)/h, the compiler assumes that (h-i) is int and h is also int so it also assumes that the result of the ratio is int. This ratio is between 0 and 1 so when you only represent it with an int, it is just 0. And only after that the compiler cast this value to a double, which then remains 0.
Try with :
double x= (h-i)/(double)h;
double y= (h-i)/(double)h;
Related
This question already has answers here:
Why does pow(n,2) return 24 when n=5, with my compiler and OS?
(4 answers)
Closed 2 years ago.
For the below code:
int digsum(ll num) { //function to calculate sum of digits
if (num < 0)
num = abs(num);
int ans = 0;
while (num != 0) {
ans = ans + num % 10;
num = num / 10;
}
return ans;
}
int main() {
ios_base::sync_with_stdio(0); cin.tie(0);
int a, b, c, cnt = 0;
long long x;
cin >> a >> b >> c;
for (int i = 0; i <= 72; i++) {
x = (b * (pow(i, a))) + c;
if (i == digsum(x) && x < mod) {
cout << x << " ";
}
}
return 0;
}
In the case a,b,c = 3,2,8 respectively and i=19;
pow(19,3) is supposed to calculate 19^3 but when I replace pow by (19x19x19), this specific case is getting satisfied, where as that wasn't the case with the pow function.
Can someone explain what the problem is?
My psychic powers suggest that your standard library's implementation of pow is not precise. I recall a discussion on SO a while back on this topic. Remember, pow returns a floating point value. I can't repro it, but it's entirely possibly your invocation of pow(19,3) returns 6858.999999999 or similar due to the way it's optimized.
Indeed, this this page says as much:
Due to rounding errors in floating point numbers, the results of pow() may not be precise (even if you pass it integers or whole numbers).
Also, this question and answer suggests the same thing.
I wouldn't have suspected it, but there you go.
Consider doing this as a workaround:
long long power = nearbyint(pow(i,a));
x = b * power + c;
Given two integers X and Y, whats the most efficient way of converting them into X.Y float value in C++?
E.g.
X = 3, Y = 1415 -> 3.1415
X = 2, Y = 12 -> 2.12
Here are some cocktail-napkin benchmark results, on my machine, for all solutions converting two ints to a float, as of the time of writing.
Caveat: I've now added a solution of my own, which seems to do well, and am therefore biased! Please double-check my results.
Test
Iterations
ns / iteration
#aliberro's conversion v2
79,113,375
13
#3Dave's conversion
84,091,005
12
#einpoklum's conversion
1,966,008,981
0
#Ripi2's conversion
47,374,058
21
#TarekDakhran's conversion
1,960,763,847
0
CPU: Quad Core Intel Core i5-7600K speed/min/max: 4000/800/4200 MHz
Devuan GNU/Linux 3
Kernel: 5.2.0-3-amd64 x86_64
GCC 9.2.1, with flags: -O3 -march=native -mtune=native
Benchmark code (Github Gist).
float sum = x + y / pow(10,floor(log10(y)+1));
log10 returns log (base 10) of its argument. For 1234, that'll be 3 point something.
Breaking this down:
log10(1234) = 3.091315159697223
floor(log10(1234)+1) = 4
pow(10,4) = 10000.0
3 + 1234 / 10000.0 = 3.1234.
But, as #einpoklum pointed out, log(0) is NaN, so you have to check for that.
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
float foo(int x, unsigned int y)
{
if (0==y)
return x;
float den = pow(10,-1 * floor(log10(y)+1));
return x + y * den;
}
int main()
{
vector<vector<int>> tests
{
{3,1234},
{1,1000},
{2,12},
{0,0},
{9,1}
};
for(auto& test: tests)
{
cout << "Test: " << test[0] << "," << test[1] << ": " << foo(test[0],test[1]) << endl;
}
return 0;
}
See runnable version at:
https://onlinegdb.com/rkaYiDcPI
With test output:
Test: 3,1234: 3.1234
Test: 1,1000: 1.1
Test: 2,12: 2.12
Test: 0,0: 0
Test: 9,1: 9.1
Edit
Small modification to remove division operation.
(reworked solution)
Initially, my thoughts were improving on the performance of power-of-10 and division-by-power-of-10 by writing specialized versions of these functions, for integers. Then there was #TarekDakhran's comment about doing the same for counting the number of digits. And then I realized: That's essentially doing the same thing twice... so let's just integrate everything. This will, specifically, allow us to completely avoid any divisions or inversions at runtime:
inline float convert(int x, int y) {
float fy (y);
if (y == 0) { return float(x); }
if (y >= 1e9) { return float(x + fy * 1e-10f); }
if (y >= 1e8) { return float(x + fy * 1e-9f); }
if (y >= 1e7) { return float(x + fy * 1e-8f); }
if (y >= 1e6) { return float(x + fy * 1e-7f); }
if (y >= 1e5) { return float(x + fy * 1e-6f); }
if (y >= 1e4) { return float(x + fy * 1e-5f); }
if (y >= 1e3) { return float(x + fy * 1e-4f); }
if (y >= 1e2) { return float(x + fy * 1e-3f); }
if (y >= 1e1) { return float(x + fy * 1e-2f); }
return float(x + fy * 1e-1f);
}
Additional notes:
This will work for y == 0; but - not for negative x or y values. Adapting it for negative value is pretty easy and not very expensive though.
Not sure if this is absolutely optimal. Perhaps a binary-search for the number of digits of y would work better?
A loop would make the code look nicer; but the compiler would need to unroll it. Would it unroll the loop and compute all those floats beforehand? I'm not sure.
I put some effort into optimizing my previous answer and ended up with this.
inline uint32_t digits_10(uint32_t x) {
return 1u
+ (x >= 10u)
+ (x >= 100u)
+ (x >= 1000u)
+ (x >= 10000u)
+ (x >= 100000u)
+ (x >= 1000000u)
+ (x >= 10000000u)
+ (x >= 100000000u)
+ (x >= 1000000000u)
;
}
inline uint64_t pow_10(uint32_t exp) {
uint64_t res = 1;
while(exp--) {
res *= 10u;
}
return res;
}
inline double fast_zip(uint32_t x, uint32_t y) {
return x + static_cast<double>(y) / pow_10(digits_10(y));
}
double IntsToDbl(int ipart, int decpart)
{
//The decimal part:
double dp = (double) decpart;
while (dp > 1)
{
dp /= 10;
}
//Joint boths parts
return ipart + dp;
}
Simple and very fast solution is converting both values x and y to string, then concatenate them, then casting the result into a floating number as following:
#include <string>
#include <iostream>
std::string x_string = std::to_string(x);
std::string y_string = std::to_string(y);
std::cout << x_string +"."+ y_string ; // the result, cast it to float if needed
(Answer based on the fact that OP has not indicated what they want to use the float for.)
The fastest (most efficient) way is to do it implicitly, but not actually do anything (after compiler optimizations).
That is, write a "pseudo-float" class, whose members are integers of x and y's types before and after the decimal point; and have operators for doing whatever it is you were going to do with the float: operator+, operator*, operator/, operator- and maybe even implementations of pow(), log2(), log10() and so on.
Unless what you were planning to do is literally save a 4-byte float somewhere for later use, it would almost certainly be faster if you had the next operand you need to work with then to really create a float from just x and y, already losing precision and wasting time.
Try this
#include <iostream>
#include <math.h>
using namespace std;
float int2Float(int integer,int decimal)
{
float sign = integer/abs(integer);
float tm = abs(integer), tm2 = abs(decimal);
int base = decimal == 0 ? -1 : log10(decimal);
tm2/=pow(10,base+1);
return (tm+tm2)*sign;
}
int main()
{
int x,y;
cin >>x >>y;
cout << int2Float(x,y);
return 0;
}
version 2, try this out
#include <iostream>
#include <cmath>
using namespace std;
float getPlaces(int x)
{
unsigned char p=0;
while(x!=0)
{
x/=10;
p++;
}
float pow10[] = {1.0f,10.0f,100.0f,1000.0f,10000.0f,100000.0f};//don't need more
return pow10[p];
}
float int2Float(int x,int y)
{
if(y == 0) return x;
float sign = x != 0 ? x/abs(x) : 1;
float tm = abs(x), tm2 = abs(y);
tm2/=getPlaces(y);
return (tm+tm2)*sign;
}
int main()
{
int x,y;
cin >>x >>y;
cout << int2Float(x,y);
return 0;
}
If you want something that is simple to read and follow, you could try something like this:
float convertToDecimal(int x)
{
float y = (float) x;
while( y > 1 ){
y = y / 10;
}
return y;
}
float convertToDecimal(int x, int y)
{
return (float) x + convertToDecimal(y);
}
This simply reduces one integer to the first floating point less than 1 and adds it to the other one.
This does become a problem if you ever want to use a number like 1.0012 to be represented as 2 integers. But that isn't part of the question. To solve it, I would use a third integer representation to be the negative power of 10 for multiplying the second number. IE 1.0012 would be 1, 12, 4. This would then be coded as follows:
float convertToDecimal(int num, int e)
{
return ((float) num) / pow(10, e);
}
float convertToDecimal(int x, int y, int e)
{
return = (float) x + convertToDecimal(y, e);
}
It a little more concise with this answer, but it doesn't help to answer your question. It might help show a problem with using only 2 integers if you stick with that data model.
I'm working on a code that calculates PI with n terms. However, my code only works correctly with some values of n.
This piece of code even numbers do not work and when I switch up the negative sign the odd numbers do not work.
double PI(int n, double y=2){
double sum = 0;
if (n==0){
return 3;
}else if (n % 2 != 0){
sum = (4/(y*(y+1)*(y+2)))+(PI (n - 1 ,y+2)) ;
}else{
sum= -(4/(y*(y+1)*(y+2)))+PI (n - 1,y+2) ;
}
return sum;
}
int main(int argc, const char * argv[]) {
double n = PI (2,2);
cout << n << endl;
}
For n = 2 I expected a result of 3.1333 but I got a value of 2.86667
This is the formula for calculating PI , y is the denominator and n is the number of terms
Firstly, I will assume that a complete runnable case of your code looks like
#include <iostream>
using namespace std;
double PI(int n, double y=2){
double sum = 0;
if (n==0){
return 3;
}else if (n % 2 != 0){
sum = (4/(y*(y+1)*(y+2)))+(PI (n - 1 ,y+2)) ;
}else{
sum= -(4/(y*(y+1)*(y+2)))+PI (n - 1,y+2) ;
}
return sum;
}
int main(int argc, const char * argv[]) {
double n = PI (2,2);
cout << n << endl;
}
I believe that you are attempting to compute pi through the formula
(pi - 3)/4 = \sum_{k = 1}^{\infty} (-1)^{k+1} / ((2k(2k+1)(2k+2)),
(where here and elsewhere I use LaTeX code to represent mathy things). This is a good formula that converges pretty quickly despite being so simple. If you were to use the first two terms of the sum, you would find that
(pi - 3)/4 \approx 1/(2*3*4) - 1/(4*5*6) ==> pi \approx 3.13333,
which you seem to indicate in your question.
To see what's wrong, you might trace through your first function call with PI(2, 2). This produces three terms.
n=2: 2 % 2 == 0, so the first term is -4/(2*3*4) + PI(1, 4). This is the wrong sign.
n=1: 1 % 2 == 1, so the second term is 4/(4*5*6), which is also the wrong sign.
n=0: n == 0, so the third term is 3, which is the correct sign.
So you have computed
3 - 4/(2*3*4) + 4/(4*5*6)
and we can see that there are many sign errors.
The underlying reason is because you are determining the sign based on n, but if you examine the formula the sign depends on y. Or in particular, it depends on whether y/2 is odd or even (in your formulation, where you are apparently only going to provide even y values to your sum).
You should change y and n appropriately. Or you might recognize that there is no reason to decouple them, and use something like the following code. In this code, n represents the number of terms to use and we compute y accordingly.
#include <iostream>
using namespace std;
double updatedPI(int n)
{
int y = 2*n;
if (n == 0) { return 3; }
else if (n % 2 == 1)
{
return 4. / (y*(y + 1)*(y + 2)) + updatedPI(n-1);
}
else
{
return -4. / (y*(y + 1)*(y + 2)) + updatedPI(n-1);
}
}
int main() {
double n = updatedPI(3);
cout << n << endl;
}
The only problem with your code is that y is calculated incorrectly. It has to be equal to 2 * n. Simply modifying your code that way gives correct results:
Live demo: https://wandbox.org/permlink/3pZNYZYbtHm7k1ND
That is, get rid of the y function parameter and set int y = 2 * n; in your function.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I was doing an algorithm where Im given x and y solution, and I need to find if possible, quadratic formula for that solutions.
What I actually mean is:
If Im given output:
f(1) = 1
f(2) = 5
f(3) = 13
f(4) = 25
So, the function should return 1,5,13,25
Function that gives that output is: 2x^2-2x+1, but how do I get that?
If your y-values are precise, you can solve system of linear equations
a*x1^2 + b*x1 + c = y1
a*x2^2 + b*x2 + c = y2
a*x3^2 + b*x3 + c = y3
substitute known values for three points and find unknowns coefficients a,b,c
If values are approximate, use least squares method (more precise - polynomial least squares) with all points
This is piece of code for least sqaure analysis. It is written for newmat matrix library. Because i don't use it right now so i am too lazy to rewrite it into armadillo library i am currently using. Just to avoid mistakes newmat starts with vector/matrix indexes from 1 instead of 0.
void polynomial_approx( const vector<double>& x, const vector<double>& fx, vector<double>& coeff, int pd)
{
// x - input values of independent variable
// fx - input values of dependent variable
// coeff - output vector with polynomial coeffiecients
// pd - polynomial degree
if ( x.size() < pd ){
cerr << "Not enough data for such high polynomial degree." << endl;
};
coeff.clear();
Matrix A(x.size(), pd + 1);
Matrix D(pd+1,pd+1);
ColumnVector y(fx.size());
ColumnVector dx;
// converting vector from c++ type to newmat vector
for (unsigned int i = 0; i < fx.size(); i++)
y(i+1) = fx[i];
// creating the design matrix
for (unsigned int i = 1; i <= x.size();i++ ){
for (unsigned int j = 1; j<= pd+1;j++ ){
A(i,j) = pow(x[i],j-1);
}
}
// compute the unknown coefficients
dx = (A.t() * A ).i() * A.t() * y;
for (unsigned int i = 1; i<= dx.Ncols(); i++)
coeff.push_back( dx(i) );
/* reconstruction of polynomial */
vector<double> recon (x.size(), 0.0 );
for ( unsigned int i = 0; i < x.size() ; i++){
for ( unsigned int j = 0; j< coeff.size(); j++){
recon[i] += coeff[j]*pow( x[i], (double) j );
}
}
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
For a gravity simulation, I need to find the angle between two objects so I can apply the force. However, I am losing precision and I don't know where. Here is the minimal code that can reproduce the issue.
#include<iostream>
using namespace std;
struct Vector2f
{
float x, y;
};
Vector2f operator-(Vector2f& left, Vector2f& right)
{
return Vector2f{ left.x - right.x, left.y - right.y };
}
double pi = 3.141592653589793238463;
double angle(Vector2f& one, Vector2f& two)
{
Vector2f normal(one - two);
if (!normal.x && !normal.y)
{
return 0.0f;
}
float theta = -(atan((double)(normal.y / normal.x)) - pi / 2);
if (normal.x < 0)
{
return (theta - pi / 2);
}
else
{
return (theta + pi / 2);
}
}
int main()
{
Vector2f one{ 0,0 };
for (int i = -100; i <= 100; i += 100)
{
for (int j = -100; j <= 100; j += 100)
{
Vector2f two{ i,j };
cout << i << ", " << j << endl;
cout << "sin:\t" << sin(angle(one, two)) * 180.0f / pi << endl;
cout << "cos:\t" << cos(angle(one, two)) * 180.0f / pi << endl;
cout << endl;
}
}
return 0;
}
For instance, where I should be getting 45 (comparing (0,0) with (100, -100) due to the grid), I am getting answers like 40.5142 and 57.2958. I understand if the precision lost were less than a degree, but this is ridiculous. I want all the output from this code to be multiples of 45, basically for those without trig knowledge. Changing the datatype of Vector2f to double does not affect the end result. Could you help me find the issue?
I am using VS 2015, but it happens similarly on VS 2013.
sin(angle(one, two)) * 180.0f / pi doesn't make sense.
it should be
sin(angle(one, two))
And you may print your angle
std::cout << angle(one, two)) * 180.0f / pi << " degree\n";
std::cout << angle(one, two)) << " radian\n";