X-Git-Url: http://nsz.repo.hu/git/?p=www;a=blobdiff_plain;f=libm%2Findex.html;h=dce0a912895ac5fc5b931b7b1e7ae2685601a08a;hp=50ffa4e6345e5e69773862c653af09ec7fcea705;hb=5ad91f5c5f3d4369c232e5710e9c34474b38f307;hpb=426327db4c4ddcff003fc2ffbfb892d2c1f03720 diff --git a/libm/index.html b/libm/index.html index 50ffa4e..dce0a91 100644 --- a/libm/index.html +++ b/libm/index.html @@ -1,14 +1,12 @@ libm

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. +

This page is about libm for the +musl libc.

Sources

-

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

Writing math code from scratch is a huge work so already existing code is +used. Several math functions are taken from the +freebsd libm and a few from the +openbsd libm implementations. +Both of them are based on fdlibm. +The freebsd libm seems to be the most well maintained and most correct version +of fdlibm.

sources:

-

Design issues

-

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

General rules

Representation

Binary representation of floating point numbers matter -because lots of bithacks are needed in the math code. +because bit hacks are often needed in the math code. +(in particular bit hacks are used instead of relational operations for nan +and sign checks becuase relational operators raise invalid fp exception on nan +and they treat -0.0 and +0.0 equally and more often than not these are not desired)

-float and double bit manipulation can be handled -in a portable way in c: +float and double bit manipulation can be handled in a portable way in c using +union types:

-(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: +(assuming the bits in the object representation of 32bit and 64bit unsigned ints +map to the floating-point representation according to ieee-754, this is not +always the case, eg. old +arm floating-point accelerator +(FPA) used mixed endian double representation, but musl does not support the old +arm ABI) +

+long double bit manipulation is harder as there are various representations +and some of them don't map to any unsigned integer type:

(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) +In case of ld64 the bit manipulation is the same as with double +and all long double math functions can be just wrappers around the +corresponding double ones. +(using symbol aliasing on the linker level is non-conformant +since functions would not have unique address then)

-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. +ld80 is the most common long double on linux (i386 and x86_64 abi), +it means 64bit significand with explicit msb +(inconsistent with other ieee formats), 15bit exp, 1 sign bit. +The m68k (and m88k) architecture uses the same format, but different endianness: +

+where m is the significand and se is the sign and exponent.

-ld128 is rare (sparc64 with software emulation), it means -113bit significand with implicit msb, 15bit exp, 1 sign bit. +ld128 is rare (eg. 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) - +There are other non-conformant long double types: eg. the old SVR4 abi for ppc +uses 128 bit long doubles, but it's software emulated and traditionally +implemented using +two doubles +(also called ibm long double as this is what ibm aix used on ppc). +The ibm s390 supports the ieee 754-2008 compliant binary128 floating-point +format, but previous ibm machines (S/370, S/360) used slightly different +representation. +

+This variation shows the difficulty to consistently handle +long double: the solution is to use ifdefs based on float.h and +on the endianness and write different code for different architectures.

Ugly

The ugly parts of libm hacking.

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

Useful info about floating-point in gcc: +http://gcc.gnu.org/wiki/FloatingPointMath

libm implementations

@@ -392,6 +578,7 @@ various other closed ones: intel libm, hp libm for itanium,.. mpcheck
  • FPAccuracy
  • beebe's ieee tests +
  • elefunt
  • testlibm
  • fptest
  • tests in crlibm