Optimized double-precision floating point functions. More...
Macros | |
| #define | PICO_DOUBLE_HAS_INT32_TO_DOUBLE_CONVERSIONS 1 |
| Set if int2double and uint2double are available. | |
| #define | PICO_DOUBLE_HAS_INT64_TO_DOUBLE_CONVERSIONS 1 |
| Set if int642double and uint642double are available. | |
| #define | PICO_DOUBLE_HAS_DOUBLE_TO_INT32_Z_CONVERSIONS 1 |
| Set if double2int_z and double2uint_z are available (rounding towards zero) | |
| #define | PICO_DOUBLE_HAS_DOUBLE_TO_INT64_Z_CONVERSIONS 1 |
| Set if double2int64_z and double2uint64_z are available (rounding towards zero) | |
| #define | PICO_DOUBLE_HAS_FIX32_TO_DOUBLE_CONVERSIONS 1 |
| Set if fix2double and ufix2double are available. | |
| #define | PICO_DOUBLE_HAS_FIX64_TO_DOUBLE_CONVERSIONS 1 |
| Set if fix642double and ufix642double are available. | |
| #define | PICO_DOUBLE_HAS_DOUBLE_TO_FIX32_Z_CONVERSIONS 1 |
| Set if double2fix_z and double2ufix_z are available (rounding towards zero) | |
| #define | PICO_DOUBLE_HAS_DOUBLE_TO_FIX64_Z_CONVERSIONS 1 |
| Set if double2fix64_z and double2ufix64_z are available (rounding towards zero) | |
| #define | PICO_DOUBLE_HAS_DOUBLE_TO_INT32_M_CONVERSIONS 1 |
| Set if double2int and double2uint are available (rounding towards -Infinity) | |
| #define | PICO_DOUBLE_HAS_DOUBLE_TO_INT64_M_CONVERSIONS 1 |
| Set if double2int64 and double2uint64 are available (rounding towards -Infinity) | |
| #define | PICO_DOUBLE_HAS_DOUBLE_TO_FIX32_M_CONVERSIONS 1 |
| Set if double2fix and double2ufix are available (rounding towards -Infinity) | |
| #define | PICO_DOUBLE_HAS_DOUBLE_TO_FIX64_M_CONVERSIONS 1 |
| Set if double2fix64 and double2ufix64 are available (rounding towards -Infinity) | |
| #define | PICO_DOUBLE_HAS_DDIV_FAST 1 |
| Set if ddiv_fast is available. | |
| #define | PICO_DOUBLE_HAS_SQRT_FAST 1 |
| Set if sqrt_fast is available. | |
| #define | PICO_DOUBLE_HAS_FMA_FAST 1 |
| Set if fma_fast is available. | |
| #define | PICO_DOUBLE_HAS_POWINT 1 |
| Set if powint is available. | |
Functions | |
| double | int2double (int32_t i) |
| Convert a signed 32-bit integer to the nearest double. | |
| double | uint2double (uint32_t u) |
| Convert an unsigned 32-bit integer to the nearest double. | |
| double | int642double (int64_t i) |
| Convert a signed 64-bit integer to the nearest double. | |
| double | uint642double (uint64_t u) |
| Convert an unsigned 64-bit integer to the nearest double. | |
| int32_t | double2int_z (double d) |
Convert a double to a signed 32-bit integer, rounding towards zero. On Arm this conversion is saturating (to INT32_MAX/INT32_MIN) for out of range input except when using pico_double compiler | |
| uint32_t | double2uint_z (double d) |
Convert a double to an unsigned 32-bit integer, rounding towards zero On Arm this conversion is saturating (to UINT32_MAX/UINT32_MIN) for out of range input except when using pico_double compiler | |
| int64_t | double2int64_z (double d) |
Convert a double to a signed 64-bit integer, rounding towards zero. On Arm this conversion is saturating (to INT64_MAX/INT64_MIN) for out of range input except when using pico_double compiler | |
| uint64_t | double2uint64_z (double d) |
Convert a double to an unsigned 64-bit integer, rounding towards zero. On Arm this conversion is saturating (to UINT64_MAX/UINT64_MIN) for out of range input except when using pico_double compiler | |
| double | fix2double (int32_t m, int e) |
| Convert a signed 32-bit fixed-point integer with the given number of fractional bits to the nearest double Out of range inputs will convert to +/- Infinity. | |
| double | ufix2double (uint32_t m, int e) |
| Convert an unsigned 32-bit fixed-point integer with the given number of fractional bits to the nearest double Out of range inputs will convert to +Infinity. | |
| double | fix642double (int64_t m, int e) |
| Convert a signed 64-bit fixed-point integer with the given number of fractional bits to the nearest double Out of range inputs will convert to +/- Infinity. | |
| double | ufix642double (uint64_t m, int e) |
| Convert an unsigned 64-bit fixed-point integer with the given number of fractional bits to the nearest double Out of range inputs will convert to +Infinity. | |
| int32_t | double2fix_z (double d, int e) |
Convert a double to a signed 32-bit fixed-point integer with the given number of fractional bits, rounding towards zero. On Arm this conversion is saturating (to INT32_MAX/INT32_MIN) for out of range input except when using pico_double compiler | |
| uint32_t | double2ufix_z (double d, int e) |
| Convert a double to an unsigned 32-bit fixed-point integer with the given number of fractional bits, rounding towards zero. This conversion is saturating (to UINT32_MAX/UINT32_MIN) for out of range input. | |
| int64_t | double2fix64_z (double d, int e) |
Convert a double to a signed 64-bit fixed-point integer with the given number of fractional bits, rounding towards zero. On Arm this conversion is saturating (to INT64_MAX/INT64_MIN) for out of range input except when using pico_double compiler | |
| uint64_t | double2ufix64_z (double d, int e) |
| Convert a double to an unsigned 64-bit fixed-point integer with the given number of fractional bits, rounding towards zero. This conversion is saturating (to UINT64_MAX/UINT64_MIN) for out of range input. | |
| int32_t | double2int (double d) |
| Convert a double to a signed 32-bit integer, rounding towards -Infinity. This conversion is saturating (to INT32_MAX/INT32_MIN) for out of range input. | |
| uint32_t | double2uint (double d) |
| Convert a double to an unsigned 32-bit integer, rounding towards -Infinity. This conversion is saturating (to UINT32_MAX/UINT32_MIN) for out of range input. | |
| int64_t | double2int64 (double d) |
| Convert a double to a signed 64-bit integer, rounding towards -Infinity. This conversion is saturating (to INT64_MAX/INT64_MIN) for out of range input. | |
| uint64_t | double2uint64 (double d) |
| Convert a double to an usigned 64-bit integer, rounding towards -Infinity. This conversion is saturating (to UINT64_MAX/UINT64_MIN) for out of range input. | |
| int32_t | double2fix (double d, int e) |
| Convert a double to a signed 32-bit fixed-point integer with the given number of fractional bits, rounding towards -Infinity. This conversion is saturating (to INT32_MAX/INT32_MIN) for out of range input. | |
| uint32_t | double2ufix (double d, int e) |
| Convert a double to an unsigned 32-bit fixed-point integer with the given number of fractional bits, rounding towards -Infinity. This conversion is saturating (to UINT32_MAX/UINT32_MIN) for out of range input. | |
| int64_t | double2fix64 (double d, int e) |
| Convert a double to a signed 64-bit fixed-point integer with the given number of fractional bits, rounding towards -Infinity. This conversion is saturating (to INT64_MAX/INT64_MIN) for out of range input. | |
| uint64_t | double2ufix64 (double d, int e) |
| Convert a double to an unsigned 64-bit fixed-point integer with the given number of fractional bits, rounding towards -Infinity. This conversion is saturating (to UINT64_MAX/UINT64_MIN) for out of range input. | |
| double | exp10 (double x) |
| Evaluate 10.0 to the power of the given value. | |
| void | sincos (double x, double *sinx, double *cosx) |
| Return both the sine and cosine of an angle efficiently. | |
| double | powint (double x, int32_t y) |
| Raise a floating point number to an integer power. | |
| double | ddiv_fast (double n, double d) |
| Perform a fast floating point divide with reduced accuracy. | |
| double | sqrt_fast (double d) |
| Perform a fast floating point square-root with reduced accuracy. | |
| double | fma_fast (double x, double y, double z) |
| Perform a fast (non-fused) multiply-add (x * y + z) with reduced accuracy. | |
| double | mla (double x, double y, double z) |
| Perform a fast multiply-add (x * y + z) with reduced accuracy (not fused multiply-add). This is another name for fma_fast. | |
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:
none - all floating point operations cause a panic - no double-precision floating point code is includedcompiler - no custom functions are provided; all double-precision floating point is handled by the C compiler/librarypico - 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 compiler by either setting the CMake global variable PICO_DEFAULT_DOUBLE_IMPL=compiler, or by using the CMake function pico_set_double_implementation(<TARGET> compiler). 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 extensions:
sincos
On Arm, the following additional optimized functions are also provided when using pico_double pico, all of which saturate to the nearest representable value for too large input when converting from floating point types:
(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
Scientific functions:
powint