Loading...
Searching...
No Matches
double.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef _PICO_DOUBLE_H
8#define _PICO_DOUBLE_H
9
129
130#include "pico.h"
131
132// PICO_CONFIG: PICO_DOUBLE_IN_RAM, Force placement of SDK provided double-precision floating point code into RAM, type=bool, default=0, group=pico_double
133#ifndef PICO_DOUBLE_IN_RAM
134#define PICO_DOUBLE_IN_RAM 0
135#endif
136
137#if !(LIB_PICO_DOUBLE_COMPILER || defined(__riscv)) || PICO_DOCS
138// private define to simplify this header only - it is undefined at the end
139#define __PICO_DOUBLE_ARM_OPTIMIZED 1
140#endif
141
144
145// we always define these for C code, but they are inline
146// funcs except for __PICO_DOUBLE_ARM_OPTIMIZED so wouldn't
147// be callable for assembly
148#if __PICO_DOUBLE_ARM_OPTIMIZED || !defined(__ASSEMBLER__)
150#define PICO_DOUBLE_HAS_INT32_TO_DOUBLE_CONVERSIONS 1
152#define PICO_DOUBLE_HAS_INT64_TO_DOUBLE_CONVERSIONS 1
154#define PICO_DOUBLE_HAS_DOUBLE_TO_INT32_Z_CONVERSIONS 1
156#define PICO_DOUBLE_HAS_DOUBLE_TO_INT64_Z_CONVERSIONS 1
157#endif
158
159#if __PICO_DOUBLE_ARM_OPTIMIZED
161#define PICO_DOUBLE_HAS_FIX32_TO_DOUBLE_CONVERSIONS 1
163#define PICO_DOUBLE_HAS_FIX64_TO_DOUBLE_CONVERSIONS 1
165#define PICO_DOUBLE_HAS_DOUBLE_TO_FIX32_Z_CONVERSIONS 1
167#define PICO_DOUBLE_HAS_DOUBLE_TO_FIX64_Z_CONVERSIONS 1
168
170#define PICO_DOUBLE_HAS_DOUBLE_TO_INT32_M_CONVERSIONS 1
172#define PICO_DOUBLE_HAS_DOUBLE_TO_INT64_M_CONVERSIONS 1
173
175#define PICO_DOUBLE_HAS_DOUBLE_TO_FIX32_M_CONVERSIONS 1
177#define PICO_DOUBLE_HAS_DOUBLE_TO_FIX64_M_CONVERSIONS 1
178#endif
179
180#if (PICO_RP2350 && LIB_PICO_DOUBLE_PICO_DCP) || PICO_DOCS
182#define PICO_DOUBLE_HAS_DDIV_FAST 1
184#define PICO_DOUBLE_HAS_SQRT_FAST 1
186#define PICO_DOUBLE_HAS_FMA_FAST 1
187#endif
188
189#if __PICO_DOUBLE_ARM_OPTIMIZED || __builtin_powi || PICO_DOCS
191#define PICO_DOUBLE_HAS_POWINT 1
192#endif
194
195#ifndef __ASSEMBLER__
196#include <math.h>
197
198#ifdef __cplusplus
199extern "C" {
200#endif
201
204#if PICO_DOUBLE_HAS_INT32_TO_DOUBLE_CONVERSIONS
205#if !__PICO_DOUBLE_ARM_OPTIMIZED
206 // for non Arm-optimized we may as well provide the function and let the compiler handle it
207 static inline double int2double(int32_t i) { return (double)i; }
208 static inline double uint2double(uint32_t u) { return (double)u; }
209#else
211 double int2double(int32_t i);
213 double uint2double(uint32_t u);
214#endif
215#endif
216
217#if PICO_DOUBLE_HAS_INT64_TO_DOUBLE_CONVERSIONS
218#if !__PICO_DOUBLE_ARM_OPTIMIZED
219 // for non Arm-optimized we may as well provide the function and let the compiler handle it
220 static inline double int642double(int64_t i) { return (double)i; }
221 static inline double uint642double(uint64_t u) { return (double)u; }
222#else
224 double int642double(int64_t i);
226 double uint642double(uint64_t u);
227#endif
228#endif
229
230#if PICO_DOUBLE_HAS_DOUBLE_TO_INT32_Z_CONVERSIONS
231#if !__PICO_DOUBLE_ARM_OPTIMIZED
232 // for non Arm-optimized we may as well provide the function and let the compiler handle it
233 static inline int32_t double2int_z(double d) { return (int32_t)d; }
234 static inline uint32_t double2uint_z(double d) { return (uint32_t)d; }
235#else
238 int32_t double2int_z(double d);
241 uint32_t double2uint_z(double d);
242#endif
243#endif
244
245#if PICO_DOUBLE_HAS_DOUBLE_TO_INT64_Z_CONVERSIONS
246#if !__PICO_DOUBLE_ARM_OPTIMIZED
247 // for non Arm-optimized we may as well provide the function and let the compiler handle it
248 static inline int64_t double2int64_z(double d) { return (int64_t)d; }
249 static inline uint64_t double2uint64_z(double d) { return (uint64_t)d; }
250#else
253 int64_t double2int64_z(double d);
256 uint64_t double2uint64_z(double d);
257#endif
258#endif
259
260#if PICO_DOUBLE_HAS_FIX32_TO_DOUBLE_CONVERSIONS
263double fix2double(int32_t m, int e);
266double ufix2double(uint32_t m, int e);
267#endif
268
269#if PICO_DOUBLE_HAS_FIX64_TO_DOUBLE_CONVERSIONS
272double fix642double(int64_t m, int e);
275double ufix642double(uint64_t m, int e);
276#endif
277
278#if PICO_DOUBLE_HAS_DOUBLE_TO_FIX32_Z_CONVERSIONS
281int32_t double2fix_z(double d, int e);
284uint32_t double2ufix_z(double d, int e);
285#endif
286
287#if PICO_DOUBLE_HAS_DOUBLE_TO_FIX64_Z_CONVERSIONS
290int64_t double2fix64_z(double d, int e);
293uint64_t double2ufix64_z(double d, int e);
294#endif
295
296// These methods round towards -Infinity - which IS NOT the C way for negative numbers;
297// as such the naming is not ideal, however is kept for backwards compatibility
298#if PICO_DOUBLE_HAS_DOUBLE_TO_INT32_M_CONVERSIONS
301int32_t double2int(double d);
304uint32_t double2uint(double d);
305#endif
306
307#if PICO_DOUBLE_HAS_DOUBLE_TO_INT64_M_CONVERSIONS
310int64_t double2int64(double d);
313uint64_t double2uint64(double d);
314#endif
315
316#if PICO_DOUBLE_HAS_DOUBLE_TO_FIX32_M_CONVERSIONS
319int32_t double2fix(double d, int e);
322uint32_t double2ufix(double d, int e);
323#endif
324
325#if PICO_DOUBLE_HAS_DOUBLE_TO_FIX64_M_CONVERSIONS
328int64_t double2fix64(double d, int e);
331uint64_t double2ufix64(double d, int e);
332#endif
333
334 // exp10 doesn't always appear in math.h but is present on all our platforms even for LIB_PICO_DOUBLE_COMPILER
335 // so we declare it here always
336
338 double exp10(double x);
339
340 // sincos doesn't always appear in math.h but is present on all our platforms even for LIB_PICO_DOUBLE_COMPILER
341 // so we declare it here always
342#if __PICO_DOUBLE_ARM_OPTIMIZED && PICO_C_COMPILER_IS_CLANG
343 // clang unhelpfully splits sincos into explict calls to sin & cos
344 extern void WRAPPER_FUNC(sincos)(double x, double *sinx, double *cosx);
345 #define sincos(x, sinx, cosx) WRAPPER_FUNC(sincos)(x, sinx, cosx)
346#else
348 void sincos(double x, double *sinx, double *cosx);
349#endif
350
351#if PICO_DOUBLE_HAS_POWINT
352#if !__PICO_DOUBLE_ARM_OPTIMIZED && __has_builtin(__builtin_powi)
353 static __force_inline double powint(double d, int32_t p) {
354 return __builtin_powi(d, p);
355 }
356#else
358 double powint(double x, int32_t y);
359#endif
360#endif
361
362#if PICO_DOUBLE_HAS_DDIV_FAST
364double ddiv_fast(double n, double d);
365#endif
366
367#if PICO_DOUBLE_HAS_SQRT_FAST
369double sqrt_fast(double d);
370#endif
371
372#if PICO_DOUBLE_HAS_FMA_FAST
374double fma_fast(double x, double y, double z);
376double mla(double x, double y, double z); // another name for fma_fast
377#endif
379
380#undef __PICO_DOUBLE_ARM_OPTIMIZED
381
382#ifdef __cplusplus
383}
384#endif
385
386#endif
387
388#endif
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,...
double uint2double(uint32_t u)
Convert an unsigned 32-bit integer to the nearest double.
int64_t double2int64(double d)
Convert a double to a signed 64-bit integer, rounding towards -Infinity. This conversion is saturatin...
double uint642double(uint64_t u)
Convert an unsigned 64-bit integer to the nearest double.
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,...
int32_t double2int(double d)
Convert a double to a signed 32-bit integer, rounding towards -Infinity. This conversion is saturatin...
uint64_t double2uint64(double d)
Convert a double to an usigned 64-bit integer, rounding towards -Infinity. This conversion is saturat...
uint64_t double2uint64_z(double d)
Convert a double to an unsigned 64-bit integer, rounding towards zero. On Arm this conversion is satu...
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,...
double sqrt_fast(double d)
Perform a fast floating point square-root with reduced accuracy.
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,...
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,...
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,...
double mla(double x, double y, double z)
Perform a fast multiply-add (x * y + z) with reduced accuracy (not fused multiply-add)....
double fma_fast(double x, double y, double z)
Perform a fast (non-fused) multiply-add (x * y + z) with reduced accuracy.
double ufix642double(uint64_t m, int e)
Convert an unsigned 64-bit fixed-point integer with the given number of fractional bits to the neares...
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 d...
int32_t double2int_z(double d)
Convert a double to a signed 32-bit integer, rounding towards zero. On Arm this conversion is saturat...
double int2double(int32_t i)
Convert a signed 32-bit integer to the nearest double.
double int642double(int64_t i)
Convert a signed 64-bit integer to the nearest double.
void sincos(double x, double *sinx, double *cosx)
Return both the sine and cosine of an angle efficiently.
double ddiv_fast(double n, double d)
Perform a fast floating point divide with reduced accuracy.
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,...
uint32_t double2uint(double d)
Convert a double to an unsigned 32-bit integer, rounding towards -Infinity. This conversion is satura...
uint32_t double2uint_z(double d)
Convert a double to an unsigned 32-bit integer, rounding towards zero On Arm this conversion is satur...
int64_t double2int64_z(double d)
Convert a double to a signed 64-bit integer, rounding towards zero. On Arm this conversion is saturat...
double powint(double x, int32_t y)
Raise a floating point number to an integer power.
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 d...
double exp10(double x)
Evaluate 10.0 to the power of the given value.
Definition double_math.c:341
double ufix2double(uint32_t m, int e)
Convert an unsigned 32-bit fixed-point integer with the given number of fractional bits to the neares...
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,...
#define __force_inline
Attribute to force inlining of a function regardless of optimization level.
Definition compiler.h:128