473,396 Members | 1,797 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

The Cephes Mathematical Library

The cephes math library is a legend in the internet. It was
written by Stephen L. Moshier in 1984, but there was apparently
an even earlier version in assembler, before he rewrote that
in C. It is used in many systems, for instance in the python
language.

I started working with this library around 1997 or whereabouts.
I rewrote the core of it in assembler, fixed some (minor)
bugs, and added several functions like the Lambert's W
function and others. I rewrote all the functions needed for
replicating all math.h

This library is at the center of the qfloat data type in lcc-win
that was one of the first concrete applications of operator
overloading and convinced me that I was in the right track.

Basically, the library works around

#define _NQ_ 12
typedef struct qfloatstruct {
int sign;
int exponent;
unsigned int mantissa[_NQ_];
}qfloat;

For a 32 bit system, this structure can be seen as an array
of 14 32 bit integers, with array[0] the sign, array[1] the
exponent, and array[2..13] the mantissa.

Within the mantissa, the first array position is always zero
and is used to hold bits that overflow from the higher
positions during the calculations.

When doing the four operations, the software expands this
structure by adding a zero to the end, to hold overflows in the
other direction.

I maintained this structure within the assembler core, and
essentially the 32 bit version uses the above description as is.

When preparing the 64 bit version however, I decided to
optimize the data layout.

1) The extra zero will no longer be stored in the number
but only stored in the temporary forms when actually
doing the calculations. Numbers will be expanded before
any of the four operations, then packed afterwards.

2) The size of the numbers must be a multiple of 2 to better
use the cache lines. A size of 64 bytes is a sensible choice.

All this leads naturally to the following structure
#define MANTISSA_LENGTH 7
typedef struct tagQfloat {
int sign;
unsigned int exponent;
unsigned long long mantissa[MANTISSA_LENGTH];
} Qfloat;

This allows for a precision of 448 bits, with 132 decimal
digits.

Obviously it would be too expensive to pass a 64 byte
structure by value for each function call, so I decided
to use references everywhere. The trick I used is that
instead of declaring variables like this:
Qfloat a,b,c;
I declare them like this:
Qfloat a[1],b[1],c[1];

This has the highly beneficial side effect that when
you call some function like
qadd(a,b,c);
to add a+b and put the result in c, the numbers are
automatically passed by reference without having to use the
ugly
qadd(&a,&b,&c);
notation and maintaining the bulk of the library
code intact.

This 64 bit version has more or less the same speed as the 32 bit
version, even if it has around 25% more precision (132 digits
instead of 105). Obviously reducing the number of loops by
half (mantissa is not 14 but 7 elements wide) offset the
extra precision work.

This new library will be shipped with the 64 bit version of lcc-win.

The purpose of this message is to discuss the data structures and the
choices I did. Obviously this is a serious implementation
of floating point, not just an academic exercise where the numbers
are represented just by "unsigned char" or similar solutions.
--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Jun 27 '08 #1
5 4476
jacob navia wrote:
The cephes math library is a legend in the internet. It was
written by Stephen L. Moshier in 1984, but there was apparently
an even earlier version in assembler, before he rewrote that
in C. It is used in many systems, for instance in the python
language.
Sorry. After I posted that, I found following comment in
qflti.c
/*
* Revision history:
*
* SLM, 5 Jan 84 PDP-11 assembly language version
* SLM, 2 Mar 86 fixed bug in asctoq()
* SLM, 6 Dec 86 C language version
*
*/

SLM is Stephen L. Moshier

The URL for the version of Mr Moshier is:

http://www.netlib.org/cephes/index.html
--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Jun 27 '08 #2
jacob navia wrote:
[...]
The purpose of this message is to discuss the data structures and the
choices I did. Obviously this is a serious implementation
of floating point, not just an academic exercise where the numbers
are represented just by "unsigned char" or similar solutions.
Okay, I'll bite: Does this discussion have anything to do
with C, or is it about implementation strategies for a library
of assembly code?

There seemed to be three C-ish things in your message:

1) Some assumptions about how a compiler pads (or rather
doesn't pad) struct objects. I guess the assumptions
are correct for your compiler, but they also seem
gratuitous: The operations are described in terms of
arrays, so why not just use arrays?

2) A trick for avoiding an address-of operator in function
calls, by declaring the variables as one-element arrays.
The price paid is that simple assignment now needs extra
syntax: `x = y' becomes `x[0] = y[0]'. TANSTAAFL.

3) I thought there was a third thing, but now I can't find it.

So: You've done something of interest to lcc users and maybe
to people who need in high-precision floating-point, and you
should feel good about having done so. But I fail to understand
why the implementation details of a library of assembly code are
a fit topic for a forum devoted to a different language.

Follow-ups set to comp.compilers.lcc.

--
Er*********@sun.com
Jun 27 '08 #3
Eric Sosman wrote:
jacob navia wrote:
>[...]
The purpose of this message is to discuss the data structures and the
choices I did. Obviously this is a serious implementation
of floating point, not just an academic exercise where the numbers
are represented just by "unsigned char" or similar solutions.

Okay, I'll bite: Does this discussion have anything to do
with C, or is it about implementation strategies for a library
of assembly code?
The core of the library is written in C, with the four operations
(add, subtract and multiply, + shift in assembler). I do not
see why you think the library is in assembler.
There seemed to be three C-ish things in your message:

1) Some assumptions about how a compiler pads (or rather
doesn't pad) struct objects. I guess the assumptions
are correct for your compiler, but they also seem
gratuitous: The operations are described in terms of
arrays, so why not just use arrays?
The problem is that arrays must be homogeneous. The exponent and the
sign are 32 bit, the mantissa is 64 bit. If you find a C array that
will do that I would take it immediately of course.

Nowhere in the code a specific layout is assumed. Precisely this
is the object of using a structure. I do not see where do you see
anything that assumes a specific layout...

Obviously, if we have
struct qfloat{ int32_t sign;int32_t exponent;
long long mantissa[7]};
and the compiler aligns each 32 bit integer into a 64 bit slot
we will have a waste of memory locations but the library will work
Obviously the assembler routines would need to be modified to
fit the compiler layout but I see no problem with this.

2) A trick for avoiding an address-of operator in function
calls, by declaring the variables as one-element arrays.
The price paid is that simple assignment now needs extra
syntax: `x = y' becomes `x[0] = y[0]'. TANSTAAFL.
There isn't a single assignment
qfloat a,b;
a=b

in the whole library. Why?

Precisely because the library declared the numbers as arrays. For
unknown hysterical reasons arrays can't be assigned to.

NOW that I have rewritten this library to use structures, the assignment
as you say is possible in the source code. Within the library source
code the function
qmov(a,b); //Move a into b
is used.
3) I thought there was a third thing, but now I can't find it.

So: You've done something of interest to lcc users and maybe
to people who need in high-precision floating-point, and you
should feel good about having done so. But I fail to understand
why the implementation details of a library of assembly code are
a fit topic for a forum devoted to a different language.
The cephes library is written in C. I made that very clear in my
message but maybe not clear enough for you.

Besides the extra precision, the library offers many special functions
in an open implementation. The list of functions is very long, with
elliptical integrals, statistics, physics, and many other functions like
Riemann zeta, Bessel functions, gamma, etc.

All that is written in C, for 32 bit, 64 bit and 448 bit precision.
This is a well known library, and I thought that we could discuss it in
this group.

>
Follow-ups set to comp.compilers.lcc.

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Jun 27 '08 #4
"jacob navia" <ja***@nospam.comwrote in message
news:g3**********@aioe.org...
Eric Sosman wrote:
>jacob navia wrote:
>>[...]
The purpose of this message is to discuss the data structures and the
choices I did. Obviously this is a serious implementation
of floating point, not just an academic exercise where the numbers
are represented just by "unsigned char" or similar solutions.

Okay, I'll bite: Does this discussion have anything to do
with C, or is it about implementation strategies for a library
of assembly code?

The core of the library is written in C, with the four operations
(add, subtract and multiply, + shift in assembler). I do not
see why you think the library is in assembler.
> There seemed to be three C-ish things in your message:

1) Some assumptions about how a compiler pads (or rather
doesn't pad) struct objects. I guess the assumptions
are correct for your compiler, but they also seem
gratuitous: The operations are described in terms of
arrays, so why not just use arrays?

The problem is that arrays must be homogeneous. The exponent and the
sign are 32 bit, the mantissa is 64 bit. If you find a C array that
will do that I would take it immediately of course.

Nowhere in the code a specific layout is assumed. Precisely this
is the object of using a structure. I do not see where do you see
anything that assumes a specific layout...

Obviously, if we have
struct qfloat{ int32_t sign;int32_t exponent;
long long mantissa[7]};
and the compiler aligns each 32 bit integer into a 64 bit slot
we will have a waste of memory locations but the library will work
Obviously the assembler routines would need to be modified to
fit the compiler layout but I see no problem with this.

> 2) A trick for avoiding an address-of operator in function
calls, by declaring the variables as one-element arrays.
The price paid is that simple assignment now needs extra
syntax: `x = y' becomes `x[0] = y[0]'. TANSTAAFL.

There isn't a single assignment
qfloat a,b;
a=b

in the whole library. Why?

Precisely because the library declared the numbers as arrays. For
unknown hysterical reasons arrays can't be assigned to.

NOW that I have rewritten this library to use structures, the assignment
as you say is possible in the source code. Within the library source
code the function
qmov(a,b); //Move a into b
is used.
So are you suggesting to change to struct assignment instead? I guess that
there will be no practical difference in speed or clarity.
> 3) I thought there was a third thing, but now I can't find it.

So: You've done something of interest to lcc users and maybe
to people who need in high-precision floating-point, and you
should feel good about having done so. But I fail to understand
why the implementation details of a library of assembly code are
a fit topic for a forum devoted to a different language.

The cephes library is written in C. I made that very clear in my
message but maybe not clear enough for you.

Besides the extra precision, the library offers many special functions
in an open implementation. The list of functions is very long, with
elliptical integrals, statistics, physics, and many other functions like
Riemann zeta, Bessel functions, gamma, etc.

All that is written in C, for 32 bit, 64 bit and 448 bit precision.
This is a well known library, and I thought that we could discuss it in
this group.
It is an interesting project. I guess that it would be better discussed on
news:comp.programming or the lcc group or even news:sci.math.num-analysis,
but certain aspects would no doubt be topical here.

** Posted from http://www.teranews.com **
Jun 27 '08 #5
jacob navia wrote:
Eric Sosman wrote:
>jacob navia wrote:
>>[...]
The purpose of this message is to discuss the data structures and the
choices I did. Obviously this is a serious implementation
of floating point, not just an academic exercise where the numbers
are represented just by "unsigned char" or similar solutions.

Okay, I'll bite: Does this discussion have anything to do
with C, or is it about implementation strategies for a library
of assembly code?
The core of the library is written in C, with the four operations
(add, subtract and multiply, + shift in assembler). I do not
see why you think the library is in assembler.
Sorry; I was misled by "I rewrote the core of it in
assembler." Obviously, that means it's written in C.
> There seemed to be three C-ish things in your message:

1) Some assumptions about how a compiler pads (or rather
doesn't pad) struct objects. I guess the assumptions
are correct for your compiler, but they also seem
gratuitous: The operations are described in terms of
arrays, so why not just use arrays?
The problem is that arrays must be homogeneous. The exponent and the
sign are 32 bit, the mantissa is 64 bit. If you find a C array that
will do that I would take it immediately of course.

Nowhere in the code a specific layout is assumed. Precisely this
is the object of using a structure. I do not see where do you see
anything that assumes a specific layout...
You're probably right, since you've seen the code and
no one else has. I was relying on the description: "this
structure can be seen as an array of 14 32 bit integers, with
array[0] the sign, array[1] the exponent, and array[2..13]
the mantissa." Silly me.
> 2) A trick for avoiding an address-of operator in function
calls, by declaring the variables as one-element arrays.
The price paid is that simple assignment now needs extra
syntax: `x = y' becomes `x[0] = y[0]'. TANSTAAFL.
There isn't a single assignment
qfloat a,b;
a=b

in the whole library. Why?

Precisely because the library declared the numbers as arrays.
... thus assuming the "specific layout" earlier denied.
NOW that I have rewritten this library to use structures, the assignment
as you say is possible in the source code. Within the library source
code the function
qmov(a,b); //Move a into b
is used.
If simple assignment works, why call a function? Seriously,
Jacob, this baffles me. You introduce the trick of declaring
variables as `Qfloat a[1], b[1], c[1];' (your own example) so
you can write `qadd(a,b,c);' instead of `qadd(&a,&b,&c);' (again,
your example), which requires you to use `qmov(a,b);' instead of
`b = a;'. I'd have suggested `b[0] = a[0];' but if you prefer
qmov() it's all one to me.

Also, I protest this "dribbling out" of detail: Your original
message made no mention at all of qmov(), nor of anything like it.
You can hardly expect the rest of us to be privy to unrevealed
implementation details known to you alone.
The cephes library is written in C. I made that very clear in my
message but maybe not clear enough for you.
I guess the fellow who said he'd translated it into assembly
was wrong.
> Follow-ups set to comp.compilers.lcc.
Follow-ups once again set to comp.compilers.lcc.

--
Eric Sosman
es*****@ieee-dot-org.invalid
Jun 27 '08 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Arend Sluis | last post by:
I have been struggling to get the cephes module (Special Functions - basically binds to a set of C and Fortran routine), but I keep running into problems like Traceback (most recent call last):...
5
by: Carl | last post by:
Hi, I am studying C++ right now. I am interested in creating my own mathematical software. Do you have any suggestions on the libraries or std libraries that I can use to creat very simple graphics...
3
by: gelong | last post by:
Hi there, I have a problem in writing a mathematical function using C++ programming. How to write an input that can insert whole equation? Example is the input are x˛ + 3y - 4zł = 0. In maple, it...
6
by: Thomas Lumley | last post by:
What does the standard guarantee about the accuracy of eg the trigonometric functions? There is obviously an implementation-dependent upper bound on the accuracy, since the answer is stored in a...
0
by: Juan R. | last post by:
I have updated some basic requirements for a generic mathematical markup language for scientific requirements at the next link. ...
4
by: Xah Lee | last post by:
i've long time been interested in algorithmic mathematical art. That is, mathematical or algorithmic visual art works that are generated by computer such that the program's source code reflects the...
13
by: jacek.strzelczyk | last post by:
Hello, I'm looking for a C library that provides the notation of n- dimensional mathematical functions. Or is there any other way to decode that kind of functions in C language? Thanks in...
2
by: Madmartigan | last post by:
Hi Operating system is WinXP using SharpDevelop version 1.1.0 and build 2124. I'm new to C# and have a problem trying to get a user to enter 3 mathematical operators of choice, then 2 numbers...
2
by: mc | last post by:
I'm looking for a library which can do mathematical stuff like solving equations. Or calculation the nulls of a function and so on. Does anyone know one? Thanks in advance!
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.