Check for infinity while using -Wfloat-equal? - c

My pet project uses -nostdlib so I can't use any C libraries however I can include them for constants.
Below is my code. If I compile using gcc -Wfloat-equal -nostdlib -O2 -c a.c on gcc or clang it'll give me the error below. I was curious if there's a way to check without triggering this warning. I suspect I can't unless I call code I don't compile
warning: comparing floating-point with ‘==’ or ‘!=’ is unsafe [-Wfloat-equal]
#include <math.h>
int IsInfinity(double d) {
return d != (double)INFINITY && (float)d == INFINITY;
}

You can use return d < INFINITY && (float) d >= INFINITY;.
Another option is return isfinite(d) && isinf((float) d); if you want to classify negative values symmetrically. (These are macros defined in math.h.)

Code looks like it is trying to test if d is in the finite range and, as a float, is more than FLT_MAX.
// OP's
int IsInfinity(double d) {
return d != (double)INFINITY && (float)d == INFINITY;
}
if there's a way to check without triggering this warning.
Alternate:
Check via the max values:
int IsInfinity_alt(double d) {
if (d < 0) d = -d; // OP can not use fabs().
return ((float)d > FLT_MAX && d <= DBL_MAX);
}
Had code used the below, some double, just bigger than FLT_MAX function differently than above. It is possible that this behavior is preferred by OP.
return (d > FLT_MAX && d <= DBL_MAX);

Related

Overreaching gcc sanitizer

I have this little snippet here:
static int32_t s_pow(int32_t base, int32_t exponent)
{
int32_t result = 1;
while (exponent != 0) {
if ((exponent % 2) == 1) {
result *= base;
}
exponent /= 2;
base *= base; /* <- this line */
}
return result;
}
Small and neat and just the one I need.
But GCC 7.5.0 (and other newer versions that support the checks) complained:
gcc -I./ -Wall -Wsign-compare -Wextra -Wshadow -fsanitize=undefined\
-fno-sanitize-recover=all -fno-sanitize=float-divide-by-zero\
-Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wstrict-prototypes\
-Wpointer-arith -Wsystem-headers -O3 -funroll-loops -fomit-frame-pointer -flto -m64\
test.o -o test
test.c:25:12: runtime error: signed integer overflow: 65536 * 65536 cannot be represented in type 'int'
Yes, GCC, that is correct, 65536 * 65536 is a bit much for a 31 bit data type even in a 64 bit environment, admitted. But the input comes from a small table and is carefully chosen in such a way that the result result cannot exceed 2^20 and therefor none of the intermediate results can. I cannot change the sanitizing itself only my code. Yes, I checked all possible results.
Any ideas? Or is it my code?
As I see runtime error: signed integer overflow is happened in runtime. It means that you send an input leading to UB. You say that result cannot exceed 2^20. As I guess you mean that you have a case where you make base *= base action after you already got a result, and don't care about base anymore.
If I understand you right, you can just change code to something like this I guess?
It will give you a fix for s_pow(60000, 1) call for example, and won't affect performance, due optimization is quite easy for compiler here.
static int32_t s_pow(int32_t base, int32_t exponent) {
int32_t result = 1;
while (exponent != 0) {
if ((exponent % 2) == 1) {
result *= base;
}
exponent /= 2;
if (exponent == 0) {
break;
}
base *= base; /* <- this line */
}
return result;
}
Basically it is important to understand what you want here, if you want to remove annoying warning, here it is a way. If warning still appears, probably you send too big numbers.

Weird C program behaviour

I have the following C program:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
int main() {
const int opt_count = 2;
int oc = 30;
int c = 900;
printf("%d %f\n", c, pow(oc, opt_count));
assert(c == (int)(pow(oc, opt_count)));
}
I'm running MinGW on Windows 8.1. Gcc version 4.9.3. I compile my program with:
gcc program.c -o program.exe
When I run it I get this output:
$ program
900 900.000000
Assertion failed: c == (int)(pow(oc, opt_count)), file program.c, line 16
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
What is going on? I expect the assertion to pass because 900 == 30^2.
Thanks!
Edit
I'm not using any fractions or decimals. I'm only using integers.
This happens when the implementation of pow is via
pow(x,y) = exp(log(x)*y)
Other library implementations first reduce the exponent by integer powers, thus avoiding this small floating point error.
More involved implementations contain steps like
pow(x,y) {
if(y<0) return 1/pow(x, -y);
n = (int)round(y);
y = y-n;
px = x; powxn = 1;
while(n>0) {
if(n%2==1) powxn *= px;
n /=2; px *= px;
}
return powxn * exp(log(x)*y);
}
with the usual divide-n-conquer resp. halving-n-squaring approach for the integer power powxn.
You have a nice answer (and solution) from #LutzL, another solution is comparing the difference with an epsilon, e.g.: 0.00001, in this way you can use the standard function pow included in math.h
#define EPSILON 0.0001
#define EQ(a, b) (fabs(a - b) < EPSILON)
assert(EQ((double)c, pow(oc, opt_count)));

Branchless conditionals on integers — fast, but can they be made faster?

I've been experimenting with the following and have noticed that the branchless “if” defined here (now with &-!! replacing *!!) can speed up certain bottleneck code by as much as (almost) 2x on 64-bit Intel targets with clang:
// Produces x if f is true, else 0 if f is false.
#define BRANCHLESS_IF(f,x) ((x) & -((typeof(x))!!(f)))
// Produces x if f is true, else y if f is false.
#define BRANCHLESS_IF_ELSE(f,x,y) (((x) & -((typeof(x))!!(f))) | \
((y) & -((typeof(y)) !(f))))
Note that f should be a reasonably simple expression with no side-effects, so that the compiler is able to do its best optimizations.
Performance is highly dependent on CPU and compiler. The branchless ‘if’ performance is excellent with clang; I haven't found any cases yet where the branchless ‘if/else’ is faster, though.
My question is: are these safe and portable as written (meaning guaranteed to give correct results on all targets), and can they be made faster?
Example usage of branchless if/else
These compute 64-bit minimum and maximum.
inline uint64_t uint64_min(uint64_t a, uint64_t b)
{
return BRANCHLESS_IF_ELSE((a <= b), a, b);
}
inline uint64_t uint64_max(uint64_t a, uint64_t b)
{
return BRANCHLESS_IF_ELSE((a >= b), a, b);
}
Example usage of branchless if
This is 64-bit modular addition — it computes (a + b) % n. The branching version (not shown) suffers terribly from branch prediction failures, but the branchless version is very fast (at least with clang).
inline uint64_t uint64_add_mod(uint64_t a, uint64_t b, uint64_t n)
{
assert(n > 1); assert(a < n); assert(b < n);
uint64_t c = a + b - BRANCHLESS_IF((a >= n - b), n);
assert(c < n);
return c;
}
Update: Full concrete working example of branchless if
Below is a full working C11 program that demonstrates the speed difference between branching and a branchless versions of a simple if conditional, if you would like to try it on your system. The program computes modular exponentiation, that is (a ** b) % n, for extremely large values.
To compile, use the following on the command line:
-O3 (or whatever high optimization level you prefer)
-DNDEBUG (to disable assertions, for speed)
Either -DBRANCHLESS=0 or -DBRANCHLESS=1 to specify branching or branchless behavior, respectively
On my system, here's what happens:
$ cc -DBRANCHLESS=0 -DNDEBUG -O3 -o powmod powmod.c && ./powmod
BRANCHLESS = 0
CPU time: 21.83 seconds
foo = 10585369126512366091
$ cc -DBRANCHLESS=1 -DNDEBUG -O3 -o powmod powmod.c && ./powmod
BRANCHLESS = 1
CPU time: 11.76 seconds
foo = 10585369126512366091
$ cc --version
Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.1.0
Thread model: posix
So, the branchless version is almost twice as fast as the branching version on my system (3.4 GHz. Intel Core i7).
// SPEED TEST OF MODULAR MULTIPLICATION WITH BRANCHLESS CONDITIONALS
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <time.h>
#include <assert.h>
typedef uint64_t uint64;
//------------------------------------------------------------------------------
#if BRANCHLESS
// Actually branchless.
#define BRANCHLESS_IF(f,x) ((x) & -((typeof(x))!!(f)))
#define BRANCHLESS_IF_ELSE(f,x,y) (((x) & -((typeof(x))!!(f))) | \
((y) & -((typeof(y)) !(f))))
#else
// Not actually branchless, but used for comparison.
#define BRANCHLESS_IF(f,x) ((f)? (x) : 0)
#define BRANCHLESS_IF_ELSE(f,x,y) ((f)? (x) : (y))
#endif
//------------------------------------------------------------------------------
// 64-bit modular multiplication. Computes (a * b) % n without division.
static uint64 uint64_mul_mod(uint64 a, uint64 b, const uint64 n)
{
assert(n > 1); assert(a < n); assert(b < n);
if (a < b) { uint64 t = a; a = b; b = t; } // Ensure that b <= a.
uint64 c = 0;
for (; b != 0; b /= 2)
{
// This computes c = (c + a) % n if (b & 1).
c += BRANCHLESS_IF((b & 1), a - BRANCHLESS_IF((c >= n - a), n));
assert(c < n);
// This computes a = (a + a) % n.
a += a - BRANCHLESS_IF((a >= n - a), n);
assert(a < n);
}
assert(c < n);
return c;
}
//------------------------------------------------------------------------------
// 64-bit modular exponentiation. Computes (a ** b) % n using modular
// multiplication.
static
uint64 uint64_pow_mod(uint64 a, uint64 b, const uint64 n)
{
assert(n > 1); assert(a < n);
uint64 c = 1;
for (; b > 0; b /= 2)
{
if (b & 1)
c = uint64_mul_mod(c, a, n);
a = uint64_mul_mod(a, a, n);
}
assert(c < n);
return c;
}
//------------------------------------------------------------------------------
int main(const int argc, const char *const argv[const])
{
printf("BRANCHLESS = %d\n", BRANCHLESS);
clock_t clock_start = clock();
#define SHOW_RESULTS 0
uint64 foo = 0; // Used in forcing compiler not to throw away results.
uint64 n = 3, a = 1, b = 1;
const uint64 iterations = 1000000;
for (uint64 iteration = 0; iteration < iterations; iteration++)
{
uint64 c = uint64_pow_mod(a%n, b, n);
if (SHOW_RESULTS)
{
printf("(%"PRIu64" ** %"PRIu64") %% %"PRIu64" = %"PRIu64"\n",
a%n, b, n, c);
}
else
{
foo ^= c;
}
n = n * 3 + 1;
a = a * 5 + 3;
b = b * 7 + 5;
}
clock_t clock_end = clock();
double elapsed = (double)(clock_end - clock_start) / CLOCKS_PER_SEC;
printf("CPU time: %.2f seconds\n", elapsed);
printf("foo = %"PRIu64"\n", foo);
return 0;
}
Second update: Intel vs. ARM performance
Testing on 32-bit ARM targets (iPhone 3GS/4S, iPad 1/2/3/4, as compiled by Xcode 6.1 with clang) reveals that the branchless “if” here is actually about 2–3 times slower than ternary ?: for the modular exponentiation code in those cases. So it seems that these branchless macros are not a good idea if maximum speed is needed, although they might be useful in rare cases where constant speed is needed.
On 64-bit ARM targets (iPhone 6+, iPad 5), the branchless “if” runs the same speed as ternary ?: — again as compiled by Xcode 6.1 with clang.
For both Intel and ARM (as compiled by clang), the branchless “if/else” was about twice as slow as ternary ?: for computing min/max.
Sure this is portable, the ! operator is guaranteed to give either 0 or 1 as a result. This then is promoted to whatever type is needed by the other operand.
As others observed, your if-else version has the disadvantage to evaluate twice, but you already know that, and if there is no side effect you are fine.
What surprises me is that you say that this is faster. I would have thought that modern compilers perform that sort of optimization themselves.
Edit: So I tested this with two compilers (gcc and clang) and the two values for the configuration.
In fact, if you don't forget to set -DNDEBUG=1, the 0 version with ?: is much better for gcc and does what I would have it expected to do. It basically uses conditional moves to have the loop branchless. In that case clang doesn't find this sort of optimization and does some conditional jumps.
For the version with arithmetic, the performance for gcc worsens. In fact seeing what he does this is not surprising. It really uses imul instructions, and these are slow. clang gets off better here. The "arithmetic" actually has optimized the multiplication out and replaced them by conditional moves.
So to summarize, yes, this is portable, but if this brings performance improvement or worsening will depend on your compiler, its version, the compile flags that you are applying, the potential of your processor ...

C program to find roots error

I am writing a function in C with the below specifications:
float find_root(float a, float b, float c, float p, float q);
find_root takes the coefficients a,b,c of a quadratic equation and an interval (p, q). It will return the root of this equation in the given interval.
For example: find_root(1, -8, 15, 2, 4) should produce a root "close to" 3.0
I have written the below code, and I don't understand why it doesn't work:
#include<stdio.h>
#include<math.h>
main()
{
printf("Hello World");
}
float find_root(float a, float b, float c, float p, float q) {
float d,root1,root2;
d = b * b - 4 * a * c;
root1 = ( -b + sqrt(d)) / (2* a);
root2 = ( -b - sqrt(d)) / (2* a);
if (root1<=q || root1>=p)
{
return root1;
}
return root2;
}
Please let me know what the error is.
Your program doesn't work, because, you never called find_root() from your main().
find_root() is not suppossed to run all-by-itself. Your program statrs execution from main(). You need to call your sub-function from main() in order to make them execute.
Change your main to have a call to find_root(), something like below.
int main() //put proper signature
{
float anser = 0;
answer = find_root(1, -8, 15, 2, 4); //taken from the question
printf("The anser is %f\n", answer); //end with a \n, stdout is line buffered
return 0; //return some value, good practice
}
Then, compile the program like
gcc -o output yourfilename.c -lm
Apart from this, for the logical issue(s) in find_root() function, please follow the way suggested by Mr. #paxdiablo.
For that data, your two roots are 5 and 3. With p == 2 and q == 4:
if (root1<=q || root1>=p)
becomes:
if (5<=4 || 5>=2)
which is true, so you'll get 5.
The if condition you want is:
if ((p <= root1) && (root1 <= q))
as shown in the following program, that produces the correct 3:
#include<stdio.h>
#include<math.h>
float find_root (float a, float b, float c, float p, float q) {
float d,root1,root2;
d = b * b - 4 * a * c;
root1 = ( -b + sqrt(d)) / (2* a);
root2 = ( -b - sqrt(d)) / (2* a);
if ((p <= root1) && (root1 <= q))
return root1;
return root2;
}
int main (void) {
printf ("%f\n", find_root(1, -8, 15, 2, 4));
return 0;
}
That's the logic errors with your calculations of the roots.
Just keep in mind there are other issues with your code.
You need to ensure you actually call the function itself, your main as it stands does not.
It also wont produce a value within the p/q bounds, instead it will give you the first root if it's within those bounds, otherwise it'll give you the second root regardless of its value.
You may want to catch the situation where d is negative, since you don't want to take the square root of it:
a = 1000, b = 0, c = 1000: d <- -4,000,000
And, lastly, if your compiler is complaining about not being able to link sqrt (as per one of your comments), you'll probably find you can fix that by specifying the math library, something like:
gcc -o myprog myprog.c -lm
Your program starts at main by definition.
Your main function is not calling find_root but it should.
You need to compile with all warnings & debug info (gcc -Wall -Wextra -g) then use a debugger (gdb) to run your code step by step to understand the behavior of your program, so compile with
gcc -Wall -Wextra -g yoursource.c -lm -o yourbinary
or with
clang -Wall -Wextra -g yoursource.c -lm -o yourbinary
then learn how to use gdb (e.g. run gdb ./yourbinary ... and later ./yourbinary without a debugger)
Then you'll think and improve the source code and recompile it, and debug it again. And repeat that process till you are happy with your program.
BTW, you'll better end your printf format strings with \n or learn about fflush(3)
Don't forget to read the documentation of every function (like printf(3) ...) that you are calling.
You might want to give some arguments (thru your main(int argc, char**argv) ...) to your program. You could use atof(3) to convert them to a double
Read also about undefined behavior, which you should always avoid.
BTW, you can use any standard C compiler (and editor like emacs or gedit) for your homework, e.g. use gcc or clang on your Linux laptop (then use gdb ...). You don't need a specific seashell
Change this condition
if (root1<=q || root1>=p)
to
if (root1<=q && root1>=p)
otherwise if anyone of the conditions is satisfied, root1 will be returned and root2 will almost never be returned. Hope this fixes your problem.

Implementation of ceil function in C

I have two questions regarding ceil() function..
The ceil() function is implemented in C. If I use ceil(3/2), it works fine. But when I use ceil(count/2), if value of count is 3, then it gives compile time error.
/tmp/ccA4Yj7p.o(.text+0x364): In function FrontBackSplit': : undefined reference toceil' collect2: ld returned 1 exit status
How to use the ceil function in second case? Please suggest.
How can I implement my own ceil function in C. Please give some basic guidelines.
Thanks.
Try this out:
#define CEILING_POS(X) ((X-(int)(X)) > 0 ? (int)(X+1) : (int)(X))
#define CEILING_NEG(X) ((X-(int)(X)) < 0 ? (int)(X-1) : (int)(X))
#define CEILING(X) ( ((X) > 0) ? CEILING_POS(X) : CEILING_NEG(X) )
Check out the link for comments, proof and discussion:
http://www.linuxquestions.org/questions/programming-9/ceiling-function-c-programming-637404/
The ceil() function is implemented in the math library, libm.so. By default, the linker does not link against this library when invoked via the gcc frontend. To link against that library, pass -lm on the command line to gcc:
gcc main.c -lm
The prototype of the ceil function is:
double ceil(double)
My guess is that the type of your variable count is not of type double. To use ceil in C, you would write:
#include <math.h>
// ...
double count = 3.0;
double result = ceil(count/2.0);
In C++, you can use std::ceil from <cmath>; std::ceil is overloaded to support multiple types:
#include <cmath>
// ...
double count = 3.0;
double result = std::ceil(count/2.0);
double ceil (double x) {
if (x > LONG_MAX) return x; // big floats are all ints
return ((long)(x+(0.99999999999999997)));
}

Resources