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.
Related
I got a question from my fellow student friend about why +-/* don't need math.h library to work in C language.
<math.h> contains macro and function definitions for mathematical operations. Some of the functionality in <math.h> is required to be present according to the C Standard, but they still aren't intrinsically part of the grammar of the language, unlike the operators +, -, *, / and %.
Because they are in the standard of C and they are only one instruction in Assembly language. math.h is only the name of the library. That doesn't mean there are no math if you don't include it.
If you look at C Operators, notice they are all fairly simple operations that can be done on numbers and values without the need of a function call (sqrt()). These are part of the C standard and are a basic part of the language, present by default in every program.
The math.h Library contains far more complex mathematical operations, mostly in functions, not small assembly instructions. These do not need to be included in the language because not every program is going to need a square root or a cosine.
Basic operators are part of the grammar of the language. In a lib there are "higher functions" that are composed out of basic operators or other libs. So you can reduce everythink back to the basic constructs of a language ... certainly.
Arithmetic operators are built into the language grammar - they're not separate library calls like sqrt() or abs() or whatever. So, they don't need to have any sort of declaration in scope in order to function.
Primarily, the reason math.h is needed for some operations and not others is that the people who designed C decided to build some things into the core language and to keep some things in separate sets, including a set of things for math, a set of things for strings, a set of things for time, a set of things for input and output, and so on.
It would be possible to build the things in math.h into the core language. For example, sizeof is built into the language, so building sqrt into the language too would not require any change of grammar. Also, it would be theoretically possible to exclude some operations like * from the core language and require you to include math.h before using them. However, the language provides ways for declaring functions like sqrt but does not provide ways for declaring operators like *, so some changes to the grammar would have to be made to support this.
So, since it is possible the core language could include or exclude various things, then the reasons for various things being included or excluded are somewhat a matter of choice. Essentially, the basic arithmetic operations were considered fundamental and very useful, so they were made part of the core language, while other functions were not. There are various factors contributing to this.
One is a desire to avoid cluttering the language. If all of the functions declared in headers were part of the core language, then sqrt could be used only for the sqrt in math.h. A programmer could not use sqrt for their own variable name. This is fine for a few names, but, as the library grows, the chance there will be collisions between a name in a library and a name in regular source code grows.
Additionally, if there is existing source code and somebody has a bright idea for a new routine, adding the new routine name to the language might break existing code that is already using that name for a different purpose.
So, generally, we prefer to implement non-essential routines in separate sets, and then authors can choose to include the ones they want to use and learn, and they can leave out the ones they do not need and avoid problems.
Partitioning the libraries into sets like this also means that library routines not used by a program do not have to be linked into the final program executable, so the executable file can be smaller.
Additionally, it means C can be used in a variety of environments, such as a small machine that is not able to support the full math library. Somebody might want to run simple programs that just work with basic arithmetic on a small processor. If the core language of C is small, they can write such programs. If every C program had to include all of the routines on the libraries, it might not be possible to get C working on very small computers.
I'm working with OpenSSL on a Fedora system, and Fedora defines OPENSSL_NO_EC2M, so functions like EC_POINT_get_affine_coordinates_GF2m aren't available. I have code that was written to use these functions that I would like to compile and run on Fedora. Is EC_POINT_get_affine_coordinates_GFp a drop-in (possibly slower) replacement? In general, are functions with GFp in the name drop in replacements for identically named functions that have GF2m in the name?
If they aren't, what should I do to port code that uses them to OpenSSL installations that don't have them?
GFp functions are intended for curves that use a prime field, while GF2m functions are intended for binary curves (see https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography for more information). In other words the underlying curve type is different. Any well behaved code that is written to use those GF2m functions should only be calling them in a context where it makes sense to do so, i.e. where it knows that the curve type is a binary curve. Since an OpenSSL library that has been built with OPENSSL_NO_EC2M defined does not have any binary curves available in it, it should never be the case that those codepaths are ever hit.
It also turns out that the need for having those different functions in the API was somewhat spurious anyway. The library itself can figure out for itself what the underlying curve type is and do the right thing and the different implementations of most of the GFp/GF2m functions are identical anyway. For that reason many of these functions were recently scheduled for future deprecation (see https://github.com/openssl/openssl/commit/50db81633ec)
Whether you can port code that supports binary curves to a version of the library that doesn't will depend on whether the code you are porting relies on binary curves as an essential part of its operation. In many cases code will support both prime and binary curves. Therefore you can simply use a prime field curve instead and simply comment out the bits of the code that support binary curves. However if it can only be a binary curve then you are out of luck.
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 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.
I'm developing program for Cortex-M3. It doesn't have floating point coprocessor. Standard C library can emulate floating point operations, but I don't use it due to its size.
Is there any good and free c library, which can emulate floating point arithmetics, targeted on ARM processors?
Currently, when I use floating point operators I have such linkage errors:
undefined reference to `__adddf3'
undefined reference to `__subdf3'
undefined reference to `__divdf3'
undefined reference to `__extendsfdf2'
undefined reference to `__muldf3'
So probably such library should implement them.
Would you not be better off (performance and size wise) using fixed point? For simple arithmetic, this is trivial to implement either directly or with a function interface. If you could bare to use C++, using operator overloading could make the use of fixed almost seamless (at no runtime overhead compared to a C function interface).
If you have more complex requirements (trig, roots etc), a good fixed-point library is presented in this Dr. Dobb's Article.
If you want to perform your floating arithmetic using built in operators, then you'll need to provide the library routines that the compiler expects, so you'd end up with something that's likely to be as large as the library that came with the compiler.
You likely have the source code to the compiler's floating support routines, so if you want to look at them to see if you can improve them that's probably your best chance. If you don't think that'll work for whatever reason, you should talk to your compiler vendor about the requirements the compiler expects of the floating support routines and the best way to replace the vendor's library.
If you want to circumvent the compiler's requirements, you'll probably need to avoid using the built in operators and perform you arithmetic using explicit function calls. I have no experience with 3rd party floating point library routines, so unfortunately I can't point you to an possible good alternatives.
Those should be defined in the runtime support library for your compiler. Those names look like the floating-point functions from libgcc (the support library for gcc), which is pretty small. You should be able to pull in those functions by setting your link flags appropriately.
Perhaps newlib would be useful here? It can be a pain to set up the toolchain, but I've had success in reducing embedded flash usage versus gcc and its standard library.
Any static linker worth its salt is going to remove unused calls. This is particularly true for embedded compilers.
gcc has all of those functions, there is gcc build voodoo (multilib, thumb, thumb2, and soft float) you can use to have that automatically have it show up. I have years ago given up and just go grab the files from the gcc sources trim them to a clean source and just build them into my projects. Years ago looking at a commercial compiler or two then looking at newlib and gcc, at least at the time they were all using pretty much the same math library. I want to say it was from Sun.
Assuming your using gcc try compiling with the -static-libgcc flag and checking the final binary size. I don't know if the linker will optimize out the unused calls but I think it will.
All the below message represent some arithmetic operation
undefined reference to __adddf3'
undefined reference to__subdf3'
undefined reference to __divdf3'
undefined reference to__extendsfdf2'
undefined reference to `__muldf3'
So while linking compiler will give linking error if you are doing some arthamatic operation in two different data type. For example:
Float x;
float y;
y = x * 0.45;
So if you compile this code while linking it will give you below message
undefined reference to `__muldf3'
To resolve this specify the "0.45" explicitly to float
y = x * 0.45F;
Most of the time this type of linking error comes when you are using c++ compiler to compile c file.