libm

This page is about designing libm for the musl libc.

Writing the math code from scratch is a huge work so already existing code is used.

Sources

The math code is mostly from freebsd which in turn is based on fdlibm.

sources:

Design issues

The math code is available but there are still many design questions.

Representation

Binary representation of floating point numbers matter because lots of bithacks are needed in the math code.

float and double bit manipulation can be handled in a portable way in c:

(and old non-standard representations are not supported)

The endianness may still vary, but that can be worked around by using a union with a single large enough unsigned int. (The only exception is probably arm/oabi fpa where the word order of a double is not consistent with the endianness [debian wiki on arm], but we probably won't support that)

long double bit manipulation is harder as there are various representations:

(and other non-standard formats are not supported)

ld64 is easy to handle: all long double functions are aliased to the corresponding double one (long double is treated equivalently to double)

ld80 is the most common (i386, x86_64), it means 64bit significand with explicit msb (inconsistent with other ieee formats), 15bit exp, 1 sign bit.

ld128 is rare (sparc64 with software emulation), it means 113bit significand with implicit msb, 15bit exp, 1 sign bit.

Endianness can vary (although on the supported i386 and x86_64 it is the same) and there is no large enough unsigned int to handle it. (In case of ld80 internal padding can vary as well, eg m68k and m88k cpus use different ld80 than the intel ones)

Ugly

The ugly parts of libm hacking.

Some notes are from: http://www.vinc17.org/research/extended.en.html

libm implementations

libm tests

multiprecision libs (useful for tests)

other links

(page history, home)