@web-font-path: "roboto-debian.css";
Optimized double-precision floating point functions.
Optimized double-precision floating point functions.
An application can take control of the floating point routines used in the application over and above what is provided by the compiler, by depending on the pico_double library. A user might want to do this:
The pico_double library comes in three main flavors:
pico_double_none
- all floating point operations cause a panic - no double-precision floating point code is includedpico_double_compiler
- no custom functions are provided; all double-precision floating point is handled by the C compiler/librarypico_double_pico
- the smallest and fastest available for the platform, along with additional functionality (e.g. fixed point conversions) which are detailed belowThe user can control which version they want (e.g. pico_double_xxx by either setting the CMake global variable PICO_DEFAULT_DOUBLE_IMPL=xxx
, or by using the CMake function pico_set_double_implementation(<TARGET> xxx)
. Note that in the absence of either, pico_double_pico is used by default.
On RP2040, pico_double_pico
uses optimized hand coded implementations from the bootrom and the SDK for both basic double-precision floating point operations and floating point math library functions. These implementations are generally faster and smaller than those provided by the C compiler/library, though they don't support all the features of a fully compliant floating point implementation; they are however usually fine for the majority of cases
On Arm, (replacement) optimized implementations are provided for the following compiler built-ins and math library functions when using pico_double_pico
:
basic arithmetic:
__aeabi_dadd, __aeabi_ddiv, __aeabi_dmul, __aeabi_drsub, __aeabi_dsub
comparison:
__aeabi_cfcmpeq, __aeabi_cfrcmple, __aeabi_cfcmple, __aeabi_dcmpeq, __aeabi_dcmplt, __aeabi_dcmple, __aeabi_dcmpge, __aeabi_dcmpgt, __aeabi_dcmpun
(u)int32 <-> double:
__aeabi_i2d, __aeabi_ui2d, __aeabi_d2iz, __aeabi_d2uiz
(u)int64 <-> double:
__aeabi_l2d, __aeabi_ul2d, __aeabi_d2lz, __aeabi_d2ulz
double -> float:
__aeabi_d2d
basic trigonometric:
sqrt, cos, sin, tan, atan2, exp, log
trigonometric and scientific
ldexp, copysign, trunc, floor, ceil, round, asin, acos, atan, sinh, cosh, tanh, asinh, acosh, atanh, exp2, log2, exp10, log10, pow, hypot, cbrt, fmod, drem, remainder, remquo, expm1, log1p, fma
GNU exetnsions:
powint, sincos
On Arm, the following additional optimized functions are also provided when using pico_double_pico
:
(u)int -> double (round to nearest):
int2double, uint2double, int642double, uint642double
(u)double -> int (round towards zero):
double2int_z, double2uint_z, double2int64_z, double2uint64_z
(u)double -> int (round towards -infinity):
double2int, double2uint, double2int64, double2uint64
(u)fix -> double (round to nearest):
fix2double, ufix2double, fix642double, ufix642double
double -> (u)fix (round towards zero):
double2fix_z, double2ufix_z, double2fix64_z, double2ufix64_z
double -> (u)fix (round towards -infinity):
double2fix, double2ufix, double2fix64, double2ufix64
Even faster versions of divide and square-root functions that do not round correctly:
ddiv_fast, sqrt_fast (these do not round correctly)
Faster unfused multiply and accumulate:
mla (fast fma)