I read that the pow(double, double) function is defined in "math.h" but I can't find its declaration.
Does anybody know where this function declared? And where is it implemented in C?
Reference:
http://publications.gbdirect.co.uk/c_book/chapter9/maths_functions.html
Quite often, an include file such as <math.h> will include other header files that actually declare the functions you would expect to see in <math.h>. The idea is that the program gets what it expects when it includes <math.h>, even if the actual function definitions are in some other header file.
Finding the implementation of a standard library function such as pow() is quite another matter. You will have to dig up the source code to your C standard runtime library and find the implementation in there.
Where it's defined depends on your environment. The code is inside a compiled C standard library somewhere.
Its "definition" is in the source code for your c standard library distribution. One such distribution is eglibc. This is browsable online, or in a source distribution:
w_pow.c
math_private.h
Short answer: In the C standard library source code.
The actual implementation of pow may vary from compiler to compiler. Generally, math.h (or a vendor-specific file included by math.h) provides the prototype for pow (i.e., its declaration), but the implementation is buried in some library file such as libm.a. Depending on your compiler, the actual source code for pow or any other library function may not be available.
declared: in the include directory of your system/SDK (e.g.: /usr/include;/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.2.sdk/usr/include/architecture/arm/math.h)
defined (implemented):
as library (compiled, binary code): in the library directory of your system/SDK (e.g.: /usr/lib (in case of the math library it's libm.dylib)
as source (program code): this is the interesting part. I work on a Mac OS X 10.6.x right now. The sources for the functions declared in math.h (e.g.: extern double pow ( double, double ); ) are not shipped with the installation (at least I couldn't find it). You are likely to find those sources in your system/SDK's C library. In my case the math library (libm) is a separate project, some of its sources are provided by Apple: http://www.opensource.apple.com/tarballs/Libm/Libm-315.tar.gz
The extern keyword in the function declaration of pow means, that it's defined somewhere else. Math functions are low-level high-performance implementations mostly done in assembly code (*.s). The assembly routines (taking the arguments/giving the parameters via registers/stack) are linked with the rest of the C library. The linking/exporting of the function/routine names is platform specific and doesn't really matter if ones goal is not dive into assembly coding.
I hope this helped,
Raphael
If you are seeking how the calculation is implemented, you can find it here:
http://fossies.org/dox/gcc-4.5.3/e__pow_8c_source.html
The name of the function is __ieee754_pow
which is called by pow function.
I’s really defined in math.h. Have you tried including math.h and simply using pow? What do you mean by “can't find it”?
Here's a C implementation for fdlibm: http://www.netlib.org/fdlibm/e_pow.c
For what it's worth, when v8 dropped its cos/sine tables, it pulled from fdlibm's implementation to do so: https://code.google.com/p/v8/source/detail?r=22918
From the change commit comments: "Implement trigonometric functions using a fdlibm port."
Mozilla on the other hand calls the cstdlib math functions, which will have variable performance by build and system (ex: may or may not invoke the chip-level implementations of transcendental functions). While C# bytecode seems to make explicit references to chip-level functions when it can. However, "pow" is not one of those, iirc (doesn't seem to have an chip-level function) and is implemented elsewhere.
See also: https://bugzilla.mozilla.org/show_bug.cgi?id=967709
For a cos/sine discussion in the Mozilla community, comparison of Mozilla's implementation vs old v8 implementation.
See also: How is Math.Pow() implemented in .NET Framework?
Intrinsic functions are chip-level, actually implemented on the processor. (We don't necessarily need lookup tables any more.)
Its here and also here.
Also go on wikipedia
You will find pow there.
Related
The standard library function abs() is declared in stdlib.h, while fabs() is in math.h.
Why are they reside in different headers?
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 (and math.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.
I'm learning C for 2 months. I experimented with different IDEs and my experiments resulted in confusion. Because for e.g. in NETBEANS I can use abs function without stdlib.h library, but when I tried to do the same thing in Visual Studio 2012 it gave a an error. Or a very odd thing in NETBEANS I can use functions from math.h library without declaring the library. Why is this happening? Can someone help? NETBEANS USES cygwin compilers.
In C you don't need to include the headers in order to use the functions. Older compilers don't always warn about that though. Also, different compilers might provide those functions in different ways; on some, they're not functions but macros. With macros, you need to include the headers.
It's good practice to always include the headers that provide the functions you need, so that you get the function prototypes. That's the only way the compiler can check for errors (correct types of passed function arguments, for example.) If you call a function for which you have no prototype, you get an implicit declaration of that function. That means the compiler just takes a guess and hopes you're using the function correctly, but has no way to check. That's why this won't work with macros, since a macro can't have a function declaration (implicit or not.)
The reason Visual Studio gives an error is because it's a C++ compiler, not a C compiler. C++ is a bit different from C. One of the differences is that C++ does not allow implicit function declarations. If you don't declare the functions you use (by including their header file in this case), then that's considered an error. C++ is mostly compatible with C, but that happens to be one of the few differences.
Btw, they're not libraries. They're header files. There's a difference. You have several standard headers you can include, but you only have one library; the C library. On most systems, you also have a math library, which only contains math functions. The point though is that several header files can be (and usually are) part of the same library.
my experience with C has been the same. different compilers has different libraries and sometimes they don't stick to the standards.
some compiler vendors try to lock you in (XXXXX$XXX) :)
I need to track down how exactly is double sin(double x) implemented in eglibc-2.13. I downloaded the source code and the only part that made sense was __sin function, that was platform-specific. Is it the heart of what I have in /usr/lib/i386-linux-gnu/libm.a?
How to track down the macrodefinitions that lead from sin() to __sin()? What I really need is the exact code (filename and the line is enough) and a way in which the build process deduces which implementation to use. The architecture's i386.
The (e)glibc build process is black, black magic. You do not want to try to comprehend it. However, glibc adheres to a one-file-per-public-function coding style, so in general, if you have the source tree and you want to find the implementation(s) of some function, the easiest thing to do is
$ find * -name '*function*' -print
from the top level, replacing function with the name of the function, of course.
Talking specifically about sin: the generic implementations of the math functions are in the math directory: however, it appears that there is no generic definition of sin. So the next place to look is sysdeps. Everything that isn't generic is in sysdeps, and in particular, sysdeps/ieee754 is where all the math functions that have some dependence on the IEEE 754 floating point specification, but no other system dependencies, live. This directory is organized by type: sysdeps/ieee754/dbl-64 contains all the math functions for IEEE double. And here you will find sysdeps/ieee754/dbl-64/s_sin.c, which is the code you are looking for. (The e_, s_, k_, etc prefixes on all these files used to mean something but AFAIK no longer do.)
If there were an implementation of sin in assembly language for a particular processor, it would be in a file named sin.S (or possibly s_sin.S) somewhere else in sysdeps. It does not appear that there is one, though.
Not an answer, but just a bit of a background:
When you use sin() or cos() in your C code, it is almost certainly the compiler that provides the implementation, rather than your C library. As an example, look at the list of builtins GCC provides. The linked page also describes the cases where the built-ins are used rather than the versions the C library provides.
I'm new to C. I was traveling through math.h, looking for its mathematical algorithms, but encountered only this kind of lines:
_CRTIMP double __cdecl sin (double);
_CRTIMP double __cdecl cos (double);
...
Now, I couldn't find the algorithm itself. I know _CRTIMP is a kind of run-time library C uses, but I just can't figure out what the whole line means. Could you, please, explain?
Besides, I would like to know where these functions are defined at.
C headers typically contain only function prototype declarations, not definitions. Function prototypes specify what is called the "function signature": return value, arguments, and sometimes calling convention (when & where compilers support this). The function definitions are in a separate source file, that gets compiled separately from your own (including any headers your source file #include's). Definitions of library functions might be in C, they might also be in assembly, but that shouldn't matter to your code (only to your curiosity). But you probably don't compile those yourself anyway; instead, your development environment / operating system comes with a standard library (a binary object file) that contains many already-compiled functions. Your development environment simply links your code to that library.
C header files will only contain the declaration of functions, not their definitions.
You're looking for the source code of the functions declared in math.h, here's one implementation of sin: http://fxr.watson.org/fxr/source//arch/i386/math-emu/poly_sin.c?v=linux-2.4.22
The C header files that are included with your OS, compiler, or C runtime library are not really intended for human consumption. You can certainly read them, and you can learn quite a bit by trying to understand them, but they're primarily intended for use by the compiler. As you've seen in these examples, they tend to depend on a lot of compiler-specific features (a habit you should try to avoid in your own code).
They also tend to have a lot of #ifdefs, so the same headers can be used with different systems.
If you just want to know how to use the sin function, for example, you're better off reading your system's documentation. On my Ubuntu system, for example, man sin shows this (among other things):
SYNOPSIS
#include <math.h>
double sin(double x);
float sinf(float x);
long double sinl(long double x);
Link with -lm.
The _CRTIMP and __cdecl are probably important to the compiler, but as a programmer you can safely ignore them.
If you're looking for the source code that implements the sin function, that may or may not be available. It might be written in a language other than C; there have even been systems where it's implemented in hardware (though a small wrapper would still be required).
Another answer provides a link to one implementation, but that's probably not the one used on your system.
And you don't need to get too bogged down in how the sin function is implemented. It's certainly a good thing to know, but you don't need that information to write code that uses it. (I absolutely do not want to discourage curiosity.)
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why do you have to link the math library in C?
When I write a program that uses functions from the math.h library, why is it that I have to explicitly link to libm even though they are part of the C standard library?
For instance, when I want to use the sin() function I need to #include <math.h> but I also need to pass -lm to GCC. But for any other library from the standard library, I don't have to do that. Why the difference?
In the old days, linkers were slow and separating the mostly unused math code from the rest made the compilation process go faster. The difference is not so great today, so you can add the -lm option to your default compiler configuration.
Note that the header <math.h> (or any other header) does not contain code. It contains information about the code, specifically how to call functions. The code itself is in a library. I mean, your program does not use the "<math.h> library", it uses the math library and uses the prototypes declared in the <math.h> header.
It's the same reason you have to explicitly link to libpthread on most implementations. When something new and scary is added to the standard library, it usually first gets implemented as a separate add-on library that overrides some of the symbols in the old standard library implementation with versions that conform to the new requirements, while also adding lots of new interfaces. I wouldn't be surprised if some historical implementations had separate versions of printf in libm for floating point printing, with a "light" version in the main libc lacking floating point. This kind of implementation is actually mentioned and encouraged for tiny systems in the ISO C rationale document, if I remember correctly.
Of course in the long-term, separating the standard library out like this leads to a lot more problems than benefits. The worst part is probably the increased load time and memory usage for dynamic-linked programs.
Actually, the reason you normally don't need to link against libm for most math functions is that these are inlined by your compiler. Your program would fail to link on a platform where this is not the case.