I know this question has been discussed a lot. I searched the web and come up with an algorithm myself. I'm wondering whether it can serve as a default implementation that works fine in general unit tests (not some serious/professional numeric tests).
bool equal_to(double x, double y) {
using limits = std::numeric_limits<double>;
auto mag_x = std::abs(x);
auto mag_y = std::abs(y);
if (mag_x < mag_y) {
std::swap(x, y);
std::swap(mag_x, mag_y);
}
auto eps = limits::epsilon() * mag_x;
auto lb = x - eps;
auto ub = x + eps;
return lb < y && y < ub;
}
Just found a flaw. The last statement should be
return (x == y) || (lb < y && y < ub);
in case equal_to(0, 0);
No, this isn't sufficient. Your eps is too low and should probably be multiplied with the number of steps used to produce x and y (although these errors often cancel, this isn't guaranteed).
Furthermore, your rounding effects may be amplified by catastrophic cancellation. If x is about 0.1 because it was calculated as 10.0 - 9.9 then you should have used limits::epsilon * (10+9.9). You're too optimistic by about a factor of 100.
Related
I'm using SFML library for a game application with moving objects. In the game, I have a ball object and I need to make sure that the ball's offset on the Y-axis each move is at least 0.1 (or -0.1)
Here's the code I'm using now:
if (offset.y < 0.0 && offset.y > -0.1) offset.y = -0.1;
if (offset.y > 0.0 && offset.y < 0.1) offset.y = 0.1;
Is there an easier/prettier way to accomplish that?
Edit:
As pointed out by the comments, code should include 0.0 case
if (offset.y < 0.0 && offset.y > -0.1) offset.y = -0.1;
if (offset.y >= 0.0 && offset.y < 0.1) offset.y = 0.1;
Just use std::abs() and std::copysign():
if (std::abs(offset.y) < .1)
offset.y = std::copysign(.1, offset.y);
Preserving the sign of zero any other way is difficult.
Though, consider whether you cannot use an integral model instead; .1 cannot be exactly represented as binary floating point.
What would be "easier or prettier" is highly opinion based, I'm afraid, but you could start by wrapping the logic into a function with a meaningful name (hopefully better than mine).
double at_least(double min_value, double x)
{
if (x < 0.0 && x > -min_value)
return -min_value;
if (x >= 0.0 && x < min_value)
return min_value;
return x;
}
Then, you could experiment some other alternatives:
#include <cmath>
#include <algorithm>
double at_least(double min_value, double x)
{
return std::copysign(std::max(min_value, std::abs(x)), x);
}
Or this one
double at_least(double min_value, double x)
{
if (x < 0.0 )
return std::min(-min_value, x);
else
return std::max(min_value, x);
}
After testing the correctness of each one, you could also profile them, if performances are important for your task. See e.g. those quick benchmarks:
http://quick-bench.com/AXt8U9vKg-75XXOFMyCK0g14RyQ
http://quick-bench.com/_nfoT0BKsAvh6QDzAWc-cX3_KYU
If you only need 1 digit after decimal point, you can use a scaled integer. To convert it to a floating point number you multiply it by 0.1. To convert a floating point number to the integer you multiply it by 10 and round to the nearest integer.
I think it's good enough . It looks clear .
You can play with e.g functions from cmath such as abs,signbit . Or wrapping it to new function- But I can't see any point in doing that
I writing a program to numerically find the roots of functions with irrational roots by various methods.
For methods such as linear interpolation, you need to find the approximate range in which a root lies, for this I wrote this code:
bool fxn1 = false;
bool fxn2 = false;
vector<float> root_list;
if(f_x(-100) < 0)
{
fxn2 = true;
}
for(float i = -99.99; i < 100.01; i += 0.01)
{
fxn1 = fxn2;
if(f_x(i) < 0)
{
fxn2 = true;
}
else
{
fxn2 = false;
}
if((fxn1 == false && fxn2 == true) || (fxn1 == true && fxn2 == false))
{
root_list.push_back(i-0.01);
root_list.push_back(i);
}
}
However, for non-continuous functions (i.e. functions with asymptotes), this code will also be triggered when the function swaps from positive to negative values either side of the asymptote.
Is there a way to get the program to tell the difference between a root and an asymptote?
Thanks in advance
If the function, f(x), is converging on a point inside [a,b] then the half-way point (a + b) / 2 should be closer to zero than a or b.
This observation leads to the following procedure:
Let mid = (a + b) / 2
If |f(mid)| < |f(a)| AND |f(mid)| < |f(b)| Then
Algorithm has converged to a root
Else
Algorithm has converged to an asymptote
End
In this pseudo code |.| denotes floating-point absolute value.
Finding numerically a root only make sense if the function has nice properties, and at least is continuous. What would you think about this one:
f: x -> f(x) defined by:
2 * i < x < 2 * i + 1 (i element of Z) : f(x) = x
2 - i + 1 < x < 2 * i (i element of Z) : f(x) = -x
x = i (i element of Z) : f(x) = 1
It is perfectly defined on R, is bounded on any bounded interval, has positive and negative values on any interval of size > 1, and is continuous on any non integer point, but it has no root.
It is simply because the rule that a root must exist on segment ]x, y[ if x < 0 < y or y < 0 < x only applies if the function is continuous on the interval.
And good luck if you want to numerically test for continuity of a function...
I occasionally get a stackoverflow exception in this method.
double norm_cdf(const double x) {
double k = 1.0/(1.0 + 0.2316419*x);
double k_sum = k*(0.319381530 + k*(-0.356563782 + k*(1.781477937 + k*(-1.821255978 + 1.330274429*k))));
if (x >= 0.0) {
return (1.0 - (1.0/(pow(2*M_PI,0.5)))*exp(-0.5*x*x) * k_sum);
} else {
return 1.0 - norm_cdf(-x);
}
}
Any suggestions on why i might be getting it ? Any steps I can take to rectify the error ?
Your problem is when x is Not a Number. NAN >= 0.0 is false, -NAN >= 0.0 is also false.
You could check against NAN specially, as others have suggested, but I would suggest simplifying things:
static double norm_cdf_positive(const double x) {
double k = 1.0/(1.0 + 0.2316419*x);
double k_sum = k*(0.319381530 + k*(-0.356563782 + k*(1.781477937 + k*(-1.821255978 + 1.330274429*k))));
return (1.0 - (1.0/(pow(2*M_PI,0.5)))*exp(-0.5*x*x) * k_sum);
}
double norm_cdf(const double x) {
if (x >= 0.0) {
return norm_cdf_positive(x);
} else {
return 1.0 - norm_cdf_positive(-x);
}
}
This has the advantage that compilers can make smarter assumptions about its behaviour. Note that I've marked the "internal" function static (which will limit its scope to the current compilation unit). You could also use unnamed namespaces. (edit: actually Timothy Shields has a simpler way of removing the recursion, which keeps everything in one function)
Likely this method is just the straw that breaks the camel's back. This function will only call itself at most once, so it's not the problem. (Edit: Or it's the NAN issue others point to, which will result in infinite recursion.)
You can easily make the function not recursive anyway, which might be a simpler option.
double norm_cdf(double x) {
bool negative = x < 0;
x = abs(x);
double k = 1.0/(1.0 + 0.2316419*x);
double k_sum = k*(0.319381530 + k*(-0.356563782 + k*(1.781477937 + k*(-1.821255978 + 1.330274429*k))));
double result = (1.0/(pow(2*M_PI,0.5)))*exp(-0.5*x*x) * k_sum;
if (!negative)
result = 1.0 - result;
return result;
}
When x is NaN, the recursion will never terminate. Add a check: Either std::isnan in C++11, or the lazy x != x, or document-and-blame-user. If you choose to handle NaN, propagating it might be a sensible choice.
Strange things happen when i try to find the cube root of a number.
The following code returns me undefined. In cmd : -1.#IND
cout<<pow(( double )(20.0*(-3.2) + 30.0),( double )1/3)
While this one works perfectly fine. In cmd : 4.93242414866094
cout<<pow(( double )(20.0*4.5 + 30.0),( double )1/3)
From mathematical way it must work since we can have the cube root from a negative number.
Pow is from Visual C++ 2010 math.h library. Any ideas?
pow(x, y) from <cmath> does NOT work if x is negative and y is non-integral.
This is a limitation of std::pow, as documented in the C standard and on cppreference:
Error handling
Errors are reported as specified in math_errhandling
If base is finite and negative and exp is finite and non-integer, a domain error occurs and a range error may occur.
If base is zero and exp is zero, a domain error may occur.
If base is zero and exp is negative, a domain error or a pole error may occur.
There are a couple ways around this limitation:
Cube-rooting is the same as taking something to the 1/3 power, so you could do std::pow(x, 1/3.).
In C++11, you can use std::cbrt. C++11 introduced both square-root and cube-root functions, but no generic n-th root function that overcomes the limitations of std::pow.
The power 1/3 is a special case. In general, non-integral powers of negative numbers are complex. It wouldn't be practical for pow to check for special cases like integer roots, and besides, 1/3 as a double is not exactly 1/3!
I don't know about the visual C++ pow, but my man page says under errors:
EDOM The argument x is negative and y is not an integral value. This would result in a complex number.
You'll have to use a more specialized cube root function if you want cube roots of negative numbers - or cut corners and take absolute value, then take cube root, then multiply the sign back on.
Note that depending on context, a negative number x to the 1/3 power is not necessarily the negative cube root you're expecting. It could just as easily be the first complex root, x^(1/3) * e^(pi*i/3). This is the convention mathematica uses; it's also reasonable to just say it's undefined.
While (-1)^3 = -1, you can't simply take a rational power of a negative number and expect a real response. This is because there are other solutions to this rational exponent that are imaginary in nature.
http://www.wolframalpha.com/input/?i=x^(1/3),+x+from+-5+to+0
Similarily, plot x^x. For x = -1/3, this should have a solution. However, this function is deemed undefined in R for x < 0.
Therefore, don't expect math.h to do magic that would make it inefficient, just change the signs yourself.
Guess you gotta take the negative out and put it in afterwards. You can have a wrapper do this for you if you really want to.
function yourPow(double x, double y)
{
if (x < 0)
return -1.0 * pow(-1.0*x, y);
else
return pow(x, y);
}
Don't cast to double by using (double), use a double numeric constant instead:
double thingToCubeRoot = -20.*3.2+30;
cout<< thingToCubeRoot/fabs(thingToCubeRoot) * pow( fabs(thingToCubeRoot), 1./3. );
Should do the trick!
Also: don't include <math.h> in C++ projects, but use <cmath> instead.
Alternatively, use pow from the <complex> header for the reasons stated by buddhabrot
pow( x, y ) is the same as (i.e. equivalent to) exp( y * log( x ) )
if log(x) is invalid then pow(x,y) is also.
Similarly you cannot perform 0 to the power of anything, although mathematically it should be 0.
C++11 has the cbrt function (see for example http://en.cppreference.com/w/cpp/numeric/math/cbrt) so you can write something like
#include <iostream>
#include <cmath>
int main(int argc, char* argv[])
{
const double arg = 20.0*(-3.2) + 30.0;
std::cout << cbrt(arg) << "\n";
std::cout << cbrt(-arg) << "\n";
return 0;
}
I do not have access to the C++ standard so I do not know how the negative argument is handled... a test on ideone http://ideone.com/bFlXYs seems to confirm that C++ (gcc-4.8.1) extends the cube root with this rule cbrt(x)=-cbrt(-x) when x<0; for this extension you can see http://mathworld.wolfram.com/CubeRoot.html
I was looking for cubit root and found this thread and it occurs to me that the following code might work:
#include <cmath>
using namespace std;
function double nth-root(double x, double n){
if (!(n%2) || x<0){
throw FAILEXCEPTION(); // even root from negative is fail
}
bool sign = (x >= 0);
x = exp(log(abs(x))/n);
return sign ? x : -x;
}
I think you should not confuse exponentiation with the nth-root of a number. See the good old Wikipedia
because the 1/3 will always return 0 as it will be considered as integer...
try with 1.0/3.0...
it is what i think but try and implement...
and do not forget to declare variables containing 1.0 and 3.0 as double...
Here's a little function I knocked up.
#define uniform() (rand()/(1.0 + RAND_MAX))
double CBRT(double Z)
{
double guess = Z;
double x, dx;
int loopbreaker;
retry:
x = guess * guess * guess;
loopbreaker = 0;
while (fabs(x - Z) > FLT_EPSILON)
{
dx = 3 * guess*guess;
loopbreaker++;
if (fabs(dx) < DBL_EPSILON || loopbreaker > 53)
{
guess += uniform() * 2 - 1.0;
goto retry;
}
guess -= (x - Z) / dx;
x = guess*guess*guess;
}
return guess;
}
It uses Newton-Raphson to find a cube root.
Sometime Newton -Raphson gets stuck, if the root is very close to 0 then the derivative can
get large and it can oscillate. So I've clamped and forced it to restart if that happens.
If you need more accuracy you can change the FLT_EPSILONs.
If you ever have no math library you can use this way to compute the cubic root:
cubic root
double curt(double x) {
if (x == 0) {
// would otherwise return something like 4.257959840008151e-109
return 0;
}
double b = 1; // use any value except 0
double last_b_1 = 0;
double last_b_2 = 0;
while (last_b_1 != b && last_b_2 != b) {
last_b_1 = b;
// use (2 * b + x / b / b) / 3 for small numbers, as suggested by willywonka_dailyblah
b = (b + x / b / b) / 2;
last_b_2 = b;
// use (2 * b + x / b / b) / 3 for small numbers, as suggested by willywonka_dailyblah
b = (b + x / b / b) / 2;
}
return b;
}
It is derives from the sqrt algorithm below. The idea is that b and x / b / b bigger and smaller from the cubic root of x. So, the average of both lies closer to the cubic root of x.
Square Root And Cubic Root (in Python)
def sqrt_2(a):
if a == 0:
return 0
b = 1
last_b = 0
while last_b != b:
last_b = b
b = (b + a / b) / 2
return b
def curt_2(a):
if a == 0:
return 0
b = a
last_b_1 = 0;
last_b_2 = 0;
while (last_b_1 != b and last_b_2 != b):
last_b_1 = b;
b = (b + a / b / b) / 2;
last_b_2 = b;
b = (b + a / b / b) / 2;
return b
In contrast to the square root, last_b_1 and last_b_2 are required in the cubic root because b flickers. You can modify these algorithms to compute the fourth root, fifth root and so on.
Thanks to my math teacher Herr Brenner in 11th grade who told me this algorithm for sqrt.
Performance
I tested it on an Arduino with 16mhz clock frequency:
0.3525ms for yourPow
0.3853ms for nth-root
2.3426ms for curt
Given integer values x and y, C and C++ both return as the quotient q = x/y the floor of the floating point equivalent. I'm interested in a method of returning the ceiling instead. For example, ceil(10/5)=2 and ceil(11/5)=3.
The obvious approach involves something like:
q = x / y;
if (q * y < x) ++q;
This requires an extra comparison and multiplication; and other methods I've seen (used in fact) involve casting as a float or double. Is there a more direct method that avoids the additional multiplication (or a second division) and branch, and that also avoids casting as a floating point number?
For positive numbers where you want to find the ceiling (q) of x when divided by y.
unsigned int x, y, q;
To round up ...
q = (x + y - 1) / y;
or (avoiding overflow in x+y)
q = 1 + ((x - 1) / y); // if x != 0
For positive numbers:
q = x/y + (x % y != 0);
Sparky's answer is one standard way to solve this problem, but as I also wrote in my comment, you run the risk of overflows. This can be solved by using a wider type, but what if you want to divide long longs?
Nathan Ernst's answer provides one solution, but it involves a function call, a variable declaration and a conditional, which makes it no shorter than the OPs code and probably even slower, because it is harder to optimize.
My solution is this:
q = (x % y) ? x / y + 1 : x / y;
It will be slightly faster than the OPs code, because the modulo and the division is performed using the same instruction on the processor, because the compiler can see that they are equivalent. At least gcc 4.4.1 performs this optimization with -O2 flag on x86.
In theory the compiler might inline the function call in Nathan Ernst's code and emit the same thing, but gcc didn't do that when I tested it. This might be because it would tie the compiled code to a single version of the standard library.
As a final note, none of this matters on a modern machine, except if you are in an extremely tight loop and all your data is in registers or the L1-cache. Otherwise all of these solutions will be equally fast, except for possibly Nathan Ernst's, which might be significantly slower if the function has to be fetched from main memory.
You could use the div function in cstdlib to get the quotient & remainder in a single call and then handle the ceiling separately, like in the below
#include <cstdlib>
#include <iostream>
int div_ceil(int numerator, int denominator)
{
std::div_t res = std::div(numerator, denominator);
return res.rem ? (res.quot + 1) : res.quot;
}
int main(int, const char**)
{
std::cout << "10 / 5 = " << div_ceil(10, 5) << std::endl;
std::cout << "11 / 5 = " << div_ceil(11, 5) << std::endl;
return 0;
}
There's a solution for both positive and negative x but only for positive y with just 1 division and without branches:
int div_ceil(int x, int y) {
return x / y + (x % y > 0);
}
Note, if x is positive then division is towards zero, and we should add 1 if reminder is not zero.
If x is negative then division is towards zero, that's what we need, and we will not add anything because x % y is not positive
How about this? (requires y non-negative, so don't use this in the rare case where y is a variable with no non-negativity guarantee)
q = (x > 0)? 1 + (x - 1)/y: (x / y);
I reduced y/y to one, eliminating the term x + y - 1 and with it any chance of overflow.
I avoid x - 1 wrapping around when x is an unsigned type and contains zero.
For signed x, negative and zero still combine into a single case.
Probably not a huge benefit on a modern general-purpose CPU, but this would be far faster in an embedded system than any of the other correct answers.
I would have rather commented but I don't have a high enough rep.
As far as I am aware, for positive arguments and a divisor which is a power of 2, this is the fastest way (tested in CUDA):
//example y=8
q = (x >> 3) + !!(x & 7);
For generic positive arguments only, I tend to do it like so:
q = x/y + !!(x % y);
This works for positive or negative numbers:
q = x / y + ((x % y != 0) ? !((x > 0) ^ (y > 0)) : 0);
If there is a remainder, checks to see if x and y are of the same sign and adds 1 accordingly.
simplified generic form,
int div_up(int n, int d) {
return n / d + (((n < 0) ^ (d > 0)) && (n % d));
} //i.e. +1 iff (not exact int && positive result)
For a more generic answer, C++ functions for integer division with well defined rounding strategy
For signed or unsigned integers.
q = x / y + !(((x < 0) != (y < 0)) || !(x % y));
For signed dividends and unsigned divisors.
q = x / y + !((x < 0) || !(x % y));
For unsigned dividends and signed divisors.
q = x / y + !((y < 0) || !(x % y));
For unsigned integers.
q = x / y + !!(x % y);
Zero divisor fails (as with a native operation). Cannot cause overflow.
Corresponding floored and modulo constexpr implementations here, along with templates to select the necessary overloads (as full optimization and to prevent mismatched sign comparison warnings):
https://github.com/libbitcoin/libbitcoin-system/wiki/Integer-Division-Unraveled
Compile with O3, The compiler performs optimization well.
q = x / y;
if (x % y) ++q;