Loading...
Searching...
No Matches

Optimized single-precision floating point functions. More...

Macros

#define PICO_FLOAT_HAS_INT32_TO_FLOAT_CONVERSIONS   1
 Set if int2float and uint2float are available.
#define PICO_FLOAT_HAS_INT64_TO_FLOAT_CONVERSIONS   1
 Set if int642float and uint642float are available.
#define PICO_FLOAT_HAS_FLOAT_TO_INT32_Z_CONVERSIONS   1
 Set if float2int_z and float2uint_z are available (rounding towards zero).
#define PICO_FLOAT_HAS_FLOAT_TO_INT64_Z_CONVERSIONS   1
 Set if float2int64_z and float2uint64_z are available (rounding towards zero).
#define PICO_FLOAT_HAS_FIX32_TO_FLOAT_CONVERSIONS   1
 Set if fix2float and ufix2float are available.
#define PICO_FLOAT_HAS_FIX64_TO_FLOAT_CONVERSIONS   1
 Set if fix642float and ufix642float are available.
#define PICO_FLOAT_HAS_FLOAT_TO_FIX32_Z_CONVERSIONS   1
 Set if float2fix_z and float2ufix_z are available (rounding towards zero).
#define PICO_FLOAT_HAS_FLOAT_TO_FIX64_Z_CONVERSIONS   1
 Set if float2fix64_z and float2ufix64_z are available (rounding towards zero).
#define PICO_FLOAT_HAS_FLOAT_TO_INT32_M_CONVERSIONS   1
 Set if float2int and float2uint are available (rounding towards -Infinity).
#define PICO_FLOAT_HAS_FLOAT_TO_INT64_M_CONVERSIONS   1
 Set if float2int64 and float2uint64 are available (rounding towards -Infinity).
#define PICO_FLOAT_HAS_FLOAT_TO_FIX32_M_CONVERSIONS   1
 Set if float2fix and float2ufix are available (rounding towards -Infinity).
#define PICO_FLOAT_HAS_FLOAT_TO_FIX64_M_CONVERSIONS   1
 Set if float2fix64 and float2ufix64 are available (rounding towards -Infinity).
#define PICO_FLOAT_HAS_FDIV_FAST   1
 Set if fdiv_fast is available.
#define PICO_FLOAT_HAS_SQRTF_FAST   1
 Set if sqrtf_fast is available.
#define PICO_FLOAT_HAS_POWINTF   1
 Set if powintf is available.

Functions

float int2float (int32_t i)
 Convert a signed 32-bit integer to the nearest float.
float uint2float (uint32_t u)
 Convert an unsigned 32-bit integer to the nearest float.
float int642float (int64_t i)
 Convert a signed 64-bit integer to the nearest float.
float uint642float (uint64_t u)
 Convert an unsigned 64-bit integer to the nearest float.
int32_t float2int_z (float f)
 Convert a float 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_float compiler.
uint32_t float2uint_z (float f)
 Convert a float 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_float compiler.
int64_t float2int64_z (float f)
 Convert a float 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_float compiler.
uint64_t float2uint64_z (float f)
 Convert a float 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_float compiler.
float fix2float (int32_t m, int e)
 Convert a signed 32-bit fixed-point integer with the given number of fractional bits to the nearest float Out of range inputs will convert to +/- Infinity.
float ufix2float (uint32_t m, int e)
 Convert an unsigned 32-bit fixed-point integer with the given number of fractional bits to the nearest float Out of range inputs will convert to +Infinity.
float fix642float (int64_t m, int e)
 Convert a signed 64-bit fixed-point integer with the given number of fractional bits to the nearest float Out of range inputs will convert to +/- Infinity.
float ufix642float (uint64_t m, int e)
 Convert an unsigned 64-bit fixed-point integer with the given number of fractional bits to the nearest float Out of range inputs will convert to +Infinity.
int32_t float2fix_z (float f, int e)
 Convert a float 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_float compiler.
uint32_t float2ufix_z (float f, int e)
 Convert a float 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 float2fix64_z (float f, int e)
 Convert a float 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_float compiler.
uint64_t float2ufix64_z (float f, int e)
 Convert a float 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 float2int (float f)
 Convert a float 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 float2uint (float f)
 Convert a float 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 float2int64 (float f)
 Convert a float 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 float2uint64 (float f)
 Convert a float to an unsigned 64-bit integer, rounding towards -Infinity. This conversion is saturating (to UINT64_MAX/UINT64_MIN) for out of range input.
int32_t float2fix (float f, int e)
 Convert a float 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 float2ufix (float f, int e)
 Convert a float 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 float2fix64 (float f, int e)
 Convert a float 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 float2ufix64 (float f, int e)
 Convert a float 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.
float exp10f (float x)
 Evaluate 10.0f to the power of the given value.
void sincosf (float x, float *sinx, float *cosx)
 Return both the sine and cosine of an angle efficiently.
float powintf (float x, int32_t y)
 Raise a floating point number to an integer power.
float fdiv_fast (float n, float d)
 Perform a fast floating point divide with reduced accuracy.
float sqrtf_fast (float f)
 Perform a fast floating point square-root with reduced accuracy.

Detailed Description

Optimized single-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_float library. A user might want to do this

  1. To use optimized software implementations provided by the RP2-series device's bootrom or the SDK
  2. To use optimized combined software/hardware implementations utilizing custom RP2-series hardware for acceleration
  3. To control the amount of C compiler/library code bloat
  4. To make sure no floating point is called at all

The pico_float library comes in three main flavors:

  1. none - all floating point operations cause a panic - no single-precision floating point code is included
  2. compiler - no custom functions are provided; all single-precision floating point is handled by the C compiler/library
  3. pico - the smallest and fastest available for the platform, along with additional functionality (e.g. fixed-point conversions) which are detailed below

The user can control which version they want (e.g. pico_float compiler by either setting the CMake global variable PICO_DEFAULT_FLOAT_IMPL=xxx, or by using the CMake function pico_set_float_implementation(<TARGET> xxx). Note that in the absence of either, pico_float pico is used by default.

On Arm on RP2350, there are multiple options for pico_float pico:

  1. pico_float pico_vfp - this library leaves basic C single-precision floating point operations to the compiler which can use inlined VFP (Arm FPU) code. Custom optimized versions of trigonometric and scientific functions are provided. No DCP (RP2350 Double co-processor) instructions are used.
  2. pico_float pico_dcp - this library prevents the compiler injecting inlined VFP code, and also implements all single-precision floating point operations in optimized DCP or M33 code. This option is not quite as fast as pico_float pico_vfp, however it allows floating point operations without enabling the floating point co-processor on the CPU; this can be beneficial in certain circumstances, e.g. where leaving stack in tasks or interrupts for the floating point state is undesirable.

Note: pico_float pico is equivalent to pico_float pico_vfp on RP2350, as this is the most sensible default

On Arm, (replacement) optimized implementations are provided for the following compiler built-ins and math library functions when using _pico variants of pico_float:

  • basic arithmetic: (except pico_float pico_vfp)

    __aeabi_fadd, __aeabi_fdiv, __aeabi_fmul, __aeabi_frsub, __aeabi_fsub

  • comparison: (except pico_float pico_vfp)

    __aeabi_cfcmpeq, __aeabi_cfrcmple, __aeabi_cfcmple, __aeabi_fcmpeq, __aeabi_fcmplt, __aeabi_fcmple, __aeabi_fcmpge, __aeabi_fcmpgt, __aeabi_fcmpun

  • (u)int32 <-> float: (except pico_float pico_vfp)

    __aeabi_i2f, __aeabi_ui2f, __aeabi_f2iz, __aeabi_f2uiz

  • (u)int64 <-> float: (except pico_float pico_vfp)

    __aeabi_l2f, __aeabi_ul2f, __aeabi_f2lz, __aeabi_f2ulz

  • float -> double: (except pico_float pico_vfp)

    __aeabi_f2d

  • basic trigonometric:

    sqrtf, cosf, sinf, tanf, atan2f, expf, logf

  • trigonometric and scientific

    ldexpf, copysignf, truncf, floorf, ceilf, roundf, asinf, acosf, atanf, sinhf, coshf, tanhf, asinhf, acoshf, atanhf, exp2f, log2f, exp10f, log10f, powf, hypotf, cbrtf, fmodf, dremf, remainderf, remquof, expm1f, log1pf, fmaf

  • GNU extensions:

    sincosf

On Arm, the following additional optimized functions are also provided (when using _pico variants of pico_float), all of which saturate to the nearest representable value for too large input when converting from floating point types:

  • Conversions to/from integer types:
    • (u)int -> float (round to nearest):

      int2float, uint2float, int642float, uint642float

      note: on pico_float pico_vfp the 32-bit functions are also provided as C macros since they map to inline VFP code

    • (u)float -> int (round towards zero):

      float2int_z, float2uint_z, float2int64_z, float2uint64_z

      note: on pico_float pico_vfp the 32-bit functions are also provided as C macros since they map to inline VFP code

    • (u)float -> int (round towards -infinity):

      float2int, float2uint, float2int64, float2uint64

  • Conversions to/from fixed-point integers:
    • (u)fix -> float (round to nearest):

      fix2float, ufix2float, fix642float, ufix642float

    • float -> (u)fix (round towards zero):

      float2fix_z, float2ufix_z, float2fix64_z, float2ufix64_z

      note: on pico_float pico_vfp the 32-bit functions are also provided as C macros since they can map to inline VFP code when the number of fractional bits is a compile time constant between 1 and 32

    • float -> (u)fix (round towards -infinity):

      float2fix, float2ufix, float2fix64, float2ufix64

      note: on pico_float pico_vfp the 32-bit functions are also provided as C macros since they can map to inline VFP code when the number of fractional bits is a compile time constant between 1 and 32

  • Scientific functions:

    powintf

  • Even faster versions of divide and square-root functions that do not round correctly: (pico_float pico_dcp only)

    fdiv_fast, sqrtf_fast

On RISC-V, (replacement) optimized implementations are provided for the following compiler built-ins when using the pico_float pico library (note that there are no variants of this library like there are on Arm):

  • Basic arithmetic:

    __addsf3, __subsf3, __mulsf3