What I mean is the following:
double d1 =555;
double d2=55.343
I want to be able to tell that d1 is an integer while d2 is not. Is there an easy way to do it in c/c++?
Use std::modf:
double intpart;
modf(value, &intpart) == 0.0
Don't convert to int! The number 1.0e+300 is an integer too you know.
Edit: As Pete Kirkham points out, passing 0 as the second argument is not guaranteed by the standard to work, requiring the use of a dummy variable and, unfortunately, making the code a lot less elegant.
Assuming a c99 and IEEE-754 compliant environment,
(trunc(x) == x)
is another solution, and will (on most platforms) have slightly better performance than modf because it needs only to produce the integer part. Both are completely acceptable.
Note that trunc produces a double-precision result, so you don't need to worry about out of range type conversions as you would with (int)x.
Edit: as #pavon points out in a comment, you may need to add another check, depending on whether or not you care about infinity, and what result you want to get if x is infinite.
Assuming you have the cmath <math.h> library, you can check the number against it's floor. If the number might be negative, make sure you get the absolute first.
bool double_is_int(double trouble) {
double absolute = abs( trouble );
return absolute == floor(absolute);
}
avakar was almost right - use modf, but the detail was off.
modf returns the fractional part, so the test should be that the result of modf is 0.0.
modf takes two arguments, the second of which should be a pointer of the same type as the first argument. Passing NULL or 0 causes a segmentation fault in the g++ runtime. The standard does not specify that passing 0 is safe; it might be that it happens to work on avakar's machine but don't do it.
You could also use fmod(a,b) which calculates the a modulo b passing 1.0. This also should give the fractional part.
#include<cmath>
#include<iostream>
int main ()
{
double d1 = 555;
double d2 = 55.343;
double int_part1;
double int_part2;
using namespace std;
cout << boolalpha;
cout << d1 << " " << modf ( d1, &int_part1 ) << endl;
cout << d1 << " " << ( modf ( d1, &int_part1 ) == 0.0 ) << endl;
cout << d2 << " " << modf ( d2, &int_part2 ) << endl;
cout << d1 << " " << ( modf ( d2, &int_part2 ) == 0.0 ) << endl;
cout << d2 << " " << modf ( d2, &int_part2 ) << endl;
cout << d1 << " " << ( modf ( d2, &int_part2 ) == 0.0 ) << endl;
cout << d1 << " " << fmod ( d1, 1.0 ) << endl;
cout << d1 << " " << ( fmod ( d1, 1.0 ) == 0 ) << endl;
cout << d2 << " " << fmod ( d2, 1.0 ) << endl;
cout << d2 << " " << ( fmod ( d2, 1.0 ) == 0 ) << endl;
cout.flush();
modf ( d1, 0 ); // segfault
}
int iHaveNoFraction(double d){
return d == trunc(d);
}
Now, it wouldn't be C if it didn't have about 40 years of language revisions...
In C, == returns int but in C++ it returns bool. At least on my Linux distro (Ubuntu) you need to either declare double trunc(double); or you could compile with -std=c99, or declare the level macro, all in order to get <math.h> to declare it.
How about
if (abs(d1 - (round(d1))) < 0.000000001) {
printf "Integer\n"; /* Can not use "==" since we are concerned about precision */
}
Fixed up to work using rounding to reflect bug Anna found
Alternate solutions:
if ((d1 - floor(d1) < 0.000000001) || (d1 - floor(d1) > 0.9999999999)) {
/* Better store floor value in a temp variable to speed up */
printf "Integer\n"; /* Can not use "==" since we are concerned about precision */
}
Theres also another one with taking floor, subtracting 0.5 and taking abs() of that and comparing to 0.499999999 but I figure it won't be a major performance improvement.
Just compare ceil and floor value of d
return floor(d)==ceil(d);
So, for d1=555, the above statement will return 555==555, i.e, true, so it's an integer.
And for d2=555.6, the above statement will return 555==556, i.e, false, so it's a double.
How about this?
if ((d1 - (int)d1) == 0)
// integer
#define _EPSILON_ 0.000001
bool close_to_int(double &d)
{
double integer,
fraction = modf(d, &integer);
if(fraction < _EPSILON_)
{
d = integer;
return true;
}
if((1.0 - fraction) < _EPSILON_)
{
d = integer + 1;
return true;
}
return false;
}
This looks at both side of the integer value and sets the value of d if it is within the limits of an integer value.
try:
bool isInteger(double d, double delta)
{
double absd = abs(d);
if( absd - floor(absd) > 0.5 )
return (ceil(absd) - absd) < delta;
return (d - floor(absd)) < delta;
}
#include <math.h>
#include <limits>
int main()
{
double x, y, n;
x = SOME_VAL;
y = modf( x, &n ); // splits a floating-point value into fractional and integer parts
if ( abs(y) < std::numeric_limits<double>::epsilon() )
{
// no floating part
}
}
In many calculations you know that your floating point results will have a small numerical error that can result from a number of multiplications.
So what you may really want to find is the question is this number within say 1e-5 of an integer value. In that case I think this works better:
bool isInteger( double value )
{
double flr = floor( value + 1e-5 );
double diff = value - flr;
return diff < 1e-5;
}
I faced a similar questions.
As I needed to round the double anyway, that's what I find working:
double d = 2.000000001;
int i = std::round(d);
std::fabs(d-i) < 10 * std::numeric_limits<double>::epsilon()
modf uses std::nearbyint(num) that why you should use nearbyint which return a double without decimal and may be faster.
#include <iostream>
#include <cmath>
int main() {
double number = 55.12;
if (!(number - std::nearbyint(number))) {
std::cout << "Is integer!";
} else {
std::cout << "Has decimal!";
}
return 0;
}
A sample code snipped that does it:
if ( ABS( ((int) d1) - (d1)) )< 0.000000001)
cout <<"Integer" << endl;
else
cout <<"Flaot" << endl;
EDIT: Changed it to reflect correct code.
Below you have the code for testing d1 and d2 keeping it very simple. The only thing you have to test is whether the variable value is equal to the same value converted to an int type. If this is not the case then it is not an integer.
#include<iostream>
using namespace std;
int main()
{
void checkType(double x);
double d1 = 555;
double d2 = 55.343;
checkType(d1);
checkType(d2);
system("Pause");
return 0;
}
void checkType(double x)
{
if(x != (int)x)
{
cout<< x << " is not an integer "<< endl;
}
else
{
cout << x << " is an integer " << endl;
}
};
Related
I have to take the coordinates of the vertices of a triangle from the user and tell if it is a right-angled triangle or not. I'm using Pythagoras Theorem to Find out i.e. h * h = b * b + p * p
But surprisingly this doesn't work for some specific right-angled triangles.
Here is one such Triangle:
Vertex A: (x, y) = (1, 3)
Vertex B: (x, y) = (1, 1)
Vertex C: (x, y) = (5, 1)
It calculates perfectly, which I figured out by printing the calculation, but still doesn't work.
Then I tried by using sqrt() function from the cmath library this way:
h = sqrt(b * b + p * p)
Logically it is the same, but it worked.
I want to understand, why the earlier method is not working?
Here is a simplified version of My Code:
#include <iostream>
#include <cmath>
using namespace std;
class Vertex {
double x, y;
public:
void take_input(char obj) {
cout << endl << " Taking Coordinates of Vertex " << obj << ": " << endl;
cout << " Enter the x component: ";
cin >> x;
cout << " Enter the y component: ";
cin >> y;
}
double distance(Vertex p) {
double dist = sqrt((x-p.x)*(x-p.x) + (y-p.y)*(y-p.y));
return dist;
}
};
class Triangle {
Vertex a, b, c;
public:
void take_inp(string obj) {
cout << endl << "Taking Vertices of the Triangle " << obj << ": " << endl;
cout << " Verteces should be in a counter clockwise order (as per convention)." << endl;
a.take_input('A');
b.take_input('B');
c.take_input('C');
}
void is_rt_ang() {
double h = a.distance(c)*a.distance(c);
double bp = a.distance(b)*a.distance(b) + b.distance(c)*b.distance(c);
/*
// Strangely this attempt works which is logically the same:
double h = a.distance(c);
double bp = sqrt(a.distance(b)*a.distance(b) + b.distance(c)*b.distance(c));
*/
if (h == bp) {
cout << "Angle is 90" << endl;
cout << h << " = " << bp << endl;
cout << "It is Right-Angled" << endl;
}
else {
cout << "Angle is not 90!" << endl;
cout << h << " != " << bp << endl;
cout << "It is Not a Right-Angled" << endl;
}
}
};
int main()
{
Triangle tri1, tri2;
tri1.take_inp("tri1");
tri1.is_rt_ang();
return 0;
}
The line
double dist = sqrt((x-p.x)*(x-p.x) + (y-p.y)*(y-p.y));
in the Vertex::distance method gives you an approximation of a square root which is rarely going to coincide with an exact answer. This is because most real numbers can't be represented in floating point arithmetic.
But in given code sample you can make do without sqrt. Replace Vertex::distance method with a method
double distance_square(Vertex p) {
double dist_square = (x-p.x)*(x-p.x) + (y-p.y)*(y-p.y);
return dist_square;
}
and call it like this in Triangle::is_rt_ang:
double h = a.distance_square(c);
double bp = a.distance_square(b) + b.distance_square(c);
This solution is still flawed because floating-point multiplication is also a subject to rounding errors. But if it is guaranteed that you are going to work only with integer coordinates, you can replace all doubles in your code with ints and for them there is no problem with multiplication (besides possibly going out of bounds for large numbers).
EDIT: Also a comment on printing
It calculates perfectly, which I figured out by printing the
calculation, but still doesn't work.
When you print doubles you need to set precision manually in order to avoid rounding. If in your code I replace a line
cout << h << " != " << bp << endl;
with
cout << std::setprecision(std::numeric_limits<double>::digits10) << std::fixed << h << " != " << bp << endl;
then for example triangle from the question I get the output
Angle is not 90!
20.000000000000004 != 20.000000000000000
It is Not a Right-Angled
For this to compile you will need to add #include <limits> and #include <iomanip>.
In your is_rt_ang function you're assuming that your hypotenuse is always going to be the edge AC, but it doesn't seem like you're doing anything to verify this.
double h = a.distance(c)*a.distance(c);
double bp = a.distance(b)*a.distance(b) + b.distance(c)*b.distance(c);
You could try getting the squares of all your distances first, (AC)^2, (AB)^2, and (BC)^2, then finding the candidate for hypotenuse by taking the max value out of the three, then do something like:
bool isRightTriangle = max == (min1 + min2)
You may also be running into some kind of round-off error with floating point numbers. It is common to use a an epsilon value when comparing floating point numbers because of the inherent round-off errors with them. If you don't need floating point values maybe use an integer, or if you do need floating point values try using an epsilon value in your equalities like:
abs(h - bp) <= epsilon
You should be able to find more information about floating point values, round-off errors, and machine epsilons on the web.
Here is a link to a SO Q/A that talks about floating point math that may be a good resource for you: Is floating point math broken?
I have been given double x = 23.456; and two integer d and c.
I have to break it so that d gets the value 23 and c gets the value 456.
I thought of the following:-
int d;
d=(int)x;
but I cannot think of what to do with c as it is an integer and if i write
c=(x-d)*1000;
then it might be applicable for this case only and not for any other case.
Is there any way to get the number of digits after the decimal and then multiply it with equal number of zeros.
Please help!!!
You could repeatedly multiply it by 10, until there is nothing after decimal point.
double c = x - d;
while(c - floor(c) > 0.0)
{c *= 10;}
you may also need to #include <math.h> for floor function, which rounds down a number. e.g. floor(4.9) returns 4.0
Floating point calculations are little bit tricky in C++ (same is true for Java and other languages). You should avoid their direct comparison and do some other stuff to get predictable result when using them, consider:
double d1=1.1;
double d2= d1 / 10.0;
if(d2==0.11)cout << "equals" << endl;
else cout << "not equals" << endl; //result is "not equals"
d1=1.99;
float f1=0.01f;
double d3=d1+f1;
if(d3==2.0)cout << "equals" << endl;
else cout << "not equals" << endl; //result is "not equals"
d1=1.99;
d2=0.01;
d3=d1+d2-2.0;
if(d3==0.0)cout << "equals" << endl;
else cout << "not equals" << endl; //result is "not equals"
As for practical solution of the problem I can suggest 2 variants:
Var 1 is to use a function that allows to specify number of digits:
#include <iostream>
#include <cmath>
using namespace std;
void split_double(const double value, int& i_part, int& r_part,
const int max_digits_after_dp, int min_digits_after_dp){
auto powerOfTenL = [](int power){ int result = 1;
for(int i=0;i<power;++i)result *= 10;
return result;
};
//Get integral part
i_part = (int)value;
double temp = (value-i_part);
double pOfTen = powerOfTenL(max_digits_after_dp);
temp *= pOfTen;
//Get real part
r_part = round(temp);
//Remove zeroes at the right in real part
int num_of_d = max_digits_after_dp;
if(min_digits_after_dp>max_digits_after_dp)
min_digits_after_dp=max_digits_after_dp;
while (num_of_d>min_digits_after_dp) {
//If the number is divisible by 10, divide it by 10
if(0==(r_part%10)) { r_part /=10; num_of_d--;
}
else break; //Last digit is not 0
}
}
int main(int argc, char *argv[])
{
double value = 10.120019;
int ipart,rpart;
const int digitsMax = 6;
const int digitsMin = 3;
split_double(value,ipart,rpart,digitsMax,digitsMin);
cout<<"Double " <<value << " has integral part " <<ipart
<<" and real part "<<rpart<<endl;
return 0;
}
Second variant to solve the problem is to use C/C++ formatting functions like vsprintf and then split the resulting string.
it's my first day messing around with C++. I'm trying to do just a really basic code looking for the roots in a quadratic equation. Here is my code so far:
#include <iostream>
#include <cmath>
int main () {
int a, b, c;
double root1, root2;
std::cout << "Enter the integers a, b, and c to fit in the quadratic equation: ax^2 + bx + c >> " << std::endl;
std::cout << "a = ";
std::cin >> a;
std::cout << "b = ";
std::cin >> b;
std::cout << "c = ";
std::cin >> c;
std::cout <<"\n";
std::cout << "Quadratic equation to solve is : " << a << "x^2 + " << b << "x + " << c <<std::endl;
root1 = (-b + sqrt(b*b - 4*a*c))/(2*a);
root2 = (-b - sqrt(b*b - 4*a*c))/(2*a);
if (root1 && root2 != nan) {
std::cout << "root 1 = " << root1 << std::endl;
std::cout << "root 2 = " << root2 << std::endl;
}
else
std::cout << "no root exists" << std::endl;
return 0;
}
I'm getting this error:
invalid operands to binary expression ('double' and 'double (*)(const char *)')
in the line:
if (root1 && root2 != nan)
I'm looking for a simple test to see if the roots exist and this obviously doesn't work. Thanks in advance for your help!
To check if something is a real number, use isnan:
if(!isnan(root1) && !isnan(root2))
Explanation:
isnan determines if the given floating point number arg is not-a-number (NaN). It returns true if arg is NaN, false otherwise.
The NaN values are used to identify undefined or non-representable values for floating-point elements, such as the square root of negative numbers or the result of 0/0. In C++, it is implemented with function overloads for each floating-point type, each returning a bool value.
double (*)(const char *) is a type which represents a pointer to a function that returns a double and takes a const char * argument. You'll find if you look at a reference for cmath that nan is the function in question.
Looks like you should be able to call it with an empty string to get a suitable value:
nan("")
However, you can't provide a double on one side of && and a bool on the other, so you'll need to have a suitable test for root1 as well.
And yes, that type syntax for nan is a bit crazy, that's how C does function pointer syntax, and the name of a function by itself represents a pointer to it, so that's what you get out of the compiler because C++ inherited C-style function pointers.
Use (C++11):
#include <cmath>
...
if (!isnan(root1) && !isnan(root2))
Use if (root1 != nan("") && root2 != nan(""))
The problem is in two places:
root1 is always true except when it is 0
nan is not declared, it should be nan("")
But I think it is better to use !isnan(root1) instead of just nan
I'm running the following code:
double Scos [61][61][61] = {0};
double kdotr;
int ik;
int howmany [34] = {0};
auto Fs_ = initializer_list<int>({0});
copy(Fs_.begin(), Fs_.end(), Fs);
for ( size_t z=0; z<5; ++z )
{
for ( size_t y=0; y<5; ++y )
{
for ( size_t x=0; x<10; ++x )
{
for ( int k1=0; k1<=60; ++k1 )
{
for ( int k2=0; k2<=60; ++k2 )
{
for ( int k3=0; k3<=60; ++k3 )
{
int i = x+y*10+z*50;
kdotr = (double)dQ*( (k1-30)*(x_[i][0]-x) + (k2-30)*(x_[i][1]-y) + (k3-30)*(x_[i][2]-z) );
if ( isnan(kdotr) )
cout << "kdotr " << k1 << " " << k2 << " " << k3 << endl;
Scos[k1][k2][k3] += (double)cos(kdotr);
if ( isnan(Scos[k1][k2][k3]) )
cout << "Scos " << k1 << " " << k2 << " " << k3 << endl;
}
}
}
}
}
}
for ( int k1=0; k1<=60; ++k1 )
{
for ( int k2=0; k2<=60; ++k2 )
{
for ( int k3=0; k3<=60; ++k3 )
{
double k = (double)dQ*sqrt( pow((k1-30),2) + pow((k2-30),2) + pow((k3-30),2) );
ik = round(k/0.1);
Fs[ik] += Scos[k1][k2][k3];
if ( isnan(Fs[ik]) )
cout << "Fs[ik] " << k1 << " " << k2 << " " << k3 << endl;
++howmany[ik];
}
}
}
At the beginning there are just some declarations and initializations (array Fs was already declared somewhere else, together with dQ and x_).
I put calls to isnan because the code strangely returns some NaNs. At first, I believed the problem was with kdotr going to infinity, which would have been argument of cos; however, the code never fails at Scos, but at some Fs[ik]. This does not make sense to me, since Fs comes from a simple sum (and it is initialized to 0).
Has ever happened to you to obtain NaN after a sum between finite terms in C++?
This sort of problem is ALWAYS caused by some input to a calculation either being "invalid" (leading to the FPU generating a NaN as the result) or using "NaN" as an input in itself.
In this case, having a quick scan through the operations you do, it seems like there are only operations that don't generate NaN based on (for example) negative inputs [like sqrt or log would do], so my thinking is that one or more of your inputs are reading uninitialized (or incorrectly initialized) data.
I would start by checking that all the components of:
x_[i][0]-x) + (k2-30)*(x_[i][1]-y) + (k3-30)*(x_[i][2]-z
are not NaN. In particular x_[i][0,1,2].
Since your code is not a complete piece of exectutable code, and some variable's initialization isn't even in the code-snippet, it will be impossible for anyone here to give you a precise answer to where in your code it is going wrong.
Ok, I make the code work without NaNs.
As some commenters pointed out, there could be problems with the initializations. In fact, instead of using directly Fs (which is a member of a greater class - this code itself is part of a method), I stored the sums of cosines in a temporary array Fs_, declared and initialized inside the method (e.g. like Scos): now there are no NaNs anymore.
I want to increment a double value from the smallest possible (negative) value it can take to the largest possible value it can take.
I've started off with this:
int main()
{
double min(numeric_limits<double>::min());
double i(min);
while(i < 0);
{
cout << i << endl;
i += min ;
}
}
Unfortunately, this doesn't produce the desired result - the while loop is skipped after one iteration.
Is there a better way to accomplish my goal?
I'm guessing at what you want from your code: You want to start with largest possible negative value and increment it toward positive infinity in the smallest possible steps until the value is no longer negative.
I think the function you want is nextafter().
int main() {
double value(-std::numeric_limits<double>::max());
while(value < 0) {
std::cout << value << '\n';
value = std::nextafter(value,std::numeric_limits<double>::infinity());
}
}
Firstly,
while(i < 0); // <--- remove this semicolon
{
cout << i << endl;
i += min ;
}
Then, std::numeric_limits<double>::min() is a positive value, so i < 0 will never be true. If you need the most negative value, you'll need
double min = -std::numeric_limits<double>::max();
but I don't know what your i += min line is supposed to do. Adding two most negative number will just yield −∞, and the loop will never finish. If you want to add a number, you'll need another variable, like
double most_negative = -std::numeric_limits<double>::max();
double most_positive = std::numeric_limits<double>::max();
double i = most_negative;
while (i < 0)
{
std::cout << i << std::endl;
i += most_positive;
}
Of course this will just print the most negative number (-1.8e+308), and then i becomes 0 and the loop will exit.
The following runs through all float-values 'in order'. The steps between successive values become smaller as u.mind increases.
No guarantee this is correct and it will take a long time to complete and this isn't portable and it will take even longer for doubles and... etc. etc.
#include <cassert>
#include <iostream>
#include <limits>
union umin {
float mind;
int mini;
} u;
int main()
{
u.mind = std::numeric_limits<float>::max();
std::cout << -u.mind << " " << u.mini << std::endl;
while ( u.mind > 0 ) {
float previous = u.mind;
u.mini -= 1;
std::cout << -u.mind << " " << u.mini << " " << previous - u.mind << std::endl;
assert( previous > u.mind );
}
}