why is abs() and fabs() defined in two different headers in C - Stack Overflow
c++ - Why use abs() or fabs() instead of conditional negation? - Stack Overflow
Simple C Question on abs() and fabs()
Difference between abs() and fabs(), and can i replace with each other in the program?? And abs() fn is kinda not working.....
Videos
math.h first appears in 7th Research Unix. It is hard to tell how it got there. For example, [1] claims that bits of C library were merged from "PWB/Unix" which included troff and C compiler pcc, but I cannot prove it.
Another interesting piece of information is library manual from V7 Unix: intro.3:
(3) These functions, together with those of section 2 and those marked (3S), constitute library libc, which is automatically loaded by the C compiler cc(1) and the Fortran compiler f77(1). The link editor ld(1) searches this library under the `-lc' option. Declarations for some of these functions may be obtained from include files indicated on the appropri- ate pages.<...>
(3M) These functions constitute the math library, libm. They are automati- cally loaded as needed by the Fortran compiler f77(1). The link editor searches this library under the `-lm' option. Declarations for these functions may be obtained from the include file <math.h>.
If you look into V7 commands makefiles, only few C programs are linked with -lm flag. So my conclusion is speculative:
libm.a(andmath.h) was primarily needed for FORTRAN programs mostly, so it was separated into library to reduce binary footprint (note that it was linked statically).- Not many machines had floating point support. For example, you would need to buy an optional FPP for PDP-11 [2], there is also libfpsim simulation library in Unix to mitigate that, so floating point can be hardly used in early C programs.
1. A History of UNIX before Berkeley: UNIX Evolution: 1975-1984
2. PDP-11 architecture
Most operators like + - / * are also math operators yet these are also readily available. When programming you use so much math, that developers have started to differentiate between math that is needed for everyday stuff and math that is more specialized that you only use some of the time. Abs is one of those functions that are just used to often. Like with pointer arithmetic when you just want to know the difference to calculate the size of a memory block. But you are not interested in knowing which is higher in memory and which is lower.
So to sum up: abs is used often because it calculates the difference of two integers. The difference between two pointers for instance is also an integer. And so it is in stdlib.h. fabs how ever is not something you will need much unless you are doing math specific stuff. Thus it is in math.h.
The "conditional abs" you propose is not equivalent to std::abs (or fabs) for floating point numbers, see e.g.
#include <iostream>
#include <cmath>
int main () {
double d = -0.0;
double a = d < 0 ? -d : d;
std::cout << d << ' ' << a << ' ' << std::abs(d);
}
output:
-0 -0 0
Given -0.0 and 0.0 represent the same real number '0', this difference may or may not matter, depending on how the result is used. However, the abs function as specified by IEEE754 mandates the signbit of the result to be 0, which would forbid the result -0.0. I personally think anything used to calculate some "absolute value" should match this behavior.
For integers, both variants will be equivalent both in runtime and behavior. (Live example)
But as std::abs (or the fitting C equivalents) are known to be correct and easier to read, you should just always prefer those.
The first thing that comes to mind is readability.
Compare these two lines of code:
int x = something, y = something, z = something;
// Compare
int absall = (x > 0 ? x : -x) + (y > 0 ? y : -y) + (z > 0 ? z : -z);
int absall = abs(x) + abs(y) + abs(z);