Hi all,
Here's my problem. I'm making an app that draws functions. When I try to draw x*x (or anything else, really) I get a nice parabola in the middle and two ugly vertical lines on both sides. This happens because sometimes x*x is too big for a double. I do not want a larger variable type to store that result. I just want to know a way to tell when x*x will be too big for double so that I can stop drawing the function.
Thank you in advance
You can check x * x against the DOUBLE_MAX macro defined in <climits> (limits.h).
Surely when x * x > DOUBLE_MAX you will get overflow, though? So if DOUBLE_MAX was 8 and x was 3, then x * x would evaluate to 1, because x * x = 3 * 3 = 9, and 9 is 1 more than 8...
@chrisname
I can't find DOUBLE_MAX in climits.
There is, however, DBL_MAX in cfloat
That won't work though.
DBL_MAX+1 > DBL_MAX returns 0 for me.
The same happens with INT_MAX.
@Duoas
Yes, but I need a more general solution that would work for any function.
Something more like what chrisname wrote.
There is not any more "general" solution. You need to check your domain before using any function. When you code the function (such as x * x) you can easily prevent range errors by checking against the input domain first.
I think what he means is that if (x > sqrt(DOUBLE_MAX)
only works for when you're multiplying x by itself.
I can't find DOUBLE_MAX in climits.
There is, however, DBL_MAX in cfloat
That won't work though.
DBL_MAX+1 > DBL_MAX returns 0 for me.
The same happens with INT_MAX.
That'll be because of the overflow. When a variable overflows, it becomes either it's smallest value + the remainder* or 0. I don't know which. I think it's undefined. What you could do is check if the overflow flag is set; but of course you'd have to rewrite that for every processor you wanted to support. On the x86:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/* CHECKBIT: returns 1 or 0 if the bit at POS in I is set or not */
#define CHECKBIT(I, POS) (!!((I) & (1 << (POS))))
int main()
{
/* ... */
int flags = 0;
asm("mov %FLAGS, %eax\n":"=a"(flags)); /* gcc/gas syntax */
if (CHECKBIT(flags, 11)) {
/* Overflow flag is set */
} else {
/* No overflow */
}
}
but that's obviously a horrendous method. For one thing, it's not portable between toolchains (works only on GNU) and for another, it's not portable between processors, either. I think you'll have to go with Duoas' solution.
*unsignedint i = UINT_MAX + 1;
would make i == 1. I don't know if that works on all processors (if they don't have an overflow flag**, then it wouldn't) or if the result is undefined behaviour.
Yes, I know I could do this, but I don't think I will..
It would be nice if c++ had some way to check the flags though (throw an exception or something).
I think I'll just leave this project where it is. I'm having other problems with it, so it wouldn't have worked neatly anyway...