Sunday, 15 February 2015

C++ Type casting from double to const int does not work properly -



C++ Type casting from double to const int does not work properly -

i have variable of type const int, parameters it's dependent upon of type double. when seek cast downwards 'double' 'const int', doesn't work properly. example, when n should 991, entered 990. i've tried several methods , 1 has worked, i'm not sure if method going work time. here methods have tried:

first method:

const int n = (ls-1)/dx + 1;

second method:

const int n = static_cast<const int>((ls-1)/dx) + 1;

third method:

double z = (ls-1)/dx + 1; const int n = z;

fourth method (only working method):

double z = (ls-1)/dx; const int n = z + 1;

please note dx value such remainder of (ls-1)/dx 0 (i.e. it's integer value). can anyway explain why other methods aren't working may understand type casting better?

edit: requested, i'm uploading entire code show how working:

#include <iostream> #include <math.h> #include <stdio.h> #include <fstream> #include <cmath> #include <algorithm> #define pi 3.14159265 using namespace std; //define fluid properties double rho_l = 998; //liquid density double rho_lg = 828.9; //liquid-gas density ratio double mu_l = 0.000798; //liquid viscosity double mu_lg = 40.24; //liquid-gas viscosity ratio double sigma = 0.0712; //surface tension double nu_g = (mu_l/mu_lg)/(rho_l/rho_lg); //define injector properties double uinj = 56.7; //injection velocity double dinj = 0.0998; //injector diameter double theta = 15.0*pi/180.0; //spray cone angle double l = 500.0*dinj; //atomization length double ls = l/dinj; //normalized atomization length //define solver parameters double k = 5294; //viscous dissipation coefficient double eps = pow(10,-5); //residual error double dx = 0.0001; //step size double ui = 10; //initial guess //const int z = static_cast<const int>((ls-1)/dx + 1) + 1; const int n = (ls-1)/dx + 1;//z; double deriv (double u, double x, double delta, double m) { double dudx; dudx = -(1.0/delta)*(1.0/u)*(u - sqrt(1.0 - u)/sqrt(m*x*x))*(u - sqrt(1.0 - u)/sqrt(m*x*x)); homecoming (dudx); } int main() { //declare variables int max_step; double err; int step; double den; double smd; double m; double ug; double re; double cd; double delta; double k1; double k2; double k3; double k4; //allocate memory heap double *u = new double [n]; double *x = new double [n]; //initialize vectors , variables den = 0.5*rho_l - (4.0/3.0)*k*(mu_l)/(uinj*dinj*dinj)*l; m = 4.0/rho_lg*tan(theta)*tan(theta); (int = 0; < n; i++) { x[i] = 1.0 + dx*i; } u[0] = 1.0; max_step = 1; err = 1; step = 0; while(abs(err) > eps && step < max_step) { //calculate ug ug = sqrt(1.0 - (ui/uinj))/sqrt(m*ls*ls)*uinj; //calculate smd smd = 6.0*sigma/(den*(uinj*uinj - ui*ui)); //calculate re # , drag coefficient re = abs(ui-ug)*smd/nu_g; if(re <= 0.01) { cd = (0.1875) + (24.0/re); } else if(re > 0.01 && re <= 260.0) { cd = (24.0/re)*(1.0 + 0.1315*pow(re,(0.32 - 0.05*log10(re)))); } else { cd = (24.0/re)*(1.0 + 0.1935*pow(re,0.6305)); } //determine new u delta = (4.0/3.0)*(1.0/cd)*(rho_lg)*(smd/dinj); //rk4 (int = 0; < n-1; i++) { k1 = deriv(u[i],x[i],delta,m); k2 = deriv(u[i]+0.5*dx*k1,x[i]+0.5*dx,delta,m); k3 = deriv(u[i]+0.5*dx*k2,x[i]+0.5*dx,delta,m); k4 = deriv(u[i]+dx*k3,x[i+1],delta,m); u[i+1] = u[i] + dx/6.0*(k1 + 2.0*k2 + 2.0*k3 + k4); //if(i >= 0 && <= 3) //cout << << " " << k1 << " " << k2 << " " << k3 << " " << k4 << " " << u[i] << endl; } err = abs(u[n-1]*uinj - ui)/ui; ui = u[n-1]*uinj; step = step + 1; } smd = 6.0*sigma/(den*(uinj*uinj - ui*ui)); cout << "u = " << ui << endl; cout << "smd = " << smd << endl; cout << "den = " << den << endl; cout << "ug = " << ug << endl; cout << "m = " << m << endl; cout << "delta = " << delta << endl; cout << "re = " << re << endl; cout << "cd = " << cd << endl; cout << "u* = " << u[n-1] << endl; cout << "error = " << err << endl; cout << "step = " << step << endl; //output info text file ofstream outputdata("result-500-15.txt"); (int = 0; < n; i++) { outputdata << x[i] << " " << u[i] << '\n'; } outputdata.close(); delete [] u; delete [] x; homecoming 0; }

your guess correct: 0.1 doesn't have finite look in binary. rather complex issue , has many corner cases not solved in general adding 0.01 mentioned in comment. (it highly depends on values expect etc.)

your question suggests quotient supposed integer. in case, right approach maintain right results not utilize doubles begin (for ls, dx, z). either utilize fractional type (nothing built-in in c++, utilize own or library), arbitrary-precision decimal type (again, utilize library gmp - sensible if know numbers have terminating decimal expression), or, easiest: if both ls , dx guaranteed have @ n digits after decimal point, multiply both 10^n , utilize integral types.

okay, code different expected. in case, in opinion, right thing prepare number of steps n , calculate dx rather other way round:

const int n = 10000; double dx = (ls-1.0)/(double)(n-1);

if want start value dx , take n such calculated value dx, inquire user when programme starts:

#include <cmath> double dxestim; cout << "dx should close to: "; cin >> dxestim; cout << "candidate values n: " << endl; int n1 = (int) floor((ls-1)/dx + 1.0); int n2 = (int) ceil((ls-1)/dx + 1.0); cout << n1 << " gives dx = " << (ls-1.0)/(double)(n1-1) << endl; cout << n2 << " gives dx = " << (ls-1.0)/(double)(n2-1) << endl; cout << "please take n: "; cin >> n; ...

c++ types casting static-cast

No comments:

Post a Comment