Smarter MIN, MAX, ABS macros

Use macros that explicitly avoid double-evaluation and can be used for any datatype, replacing `min`, `max`, `abs`, `fabs`, `labs`, and `FABS`.

Co-Authored-By: ejtagle <ejtagle@hotmail.com>
This commit is contained in:
Scott Lahteine
2018-05-13 01:10:34 -05:00
parent 083ec9963e
commit 99ecdf59af
52 changed files with 206 additions and 247 deletions

View File

@ -785,79 +785,6 @@ typedef struct
//! @}
/*! \name Mathematics
*
* The same considerations as for clz and ctz apply here but GCC does not
* provide built-in functions to access the assembly instructions abs, min and
* max and it does not produce them by itself in most cases, so two sets of
* macros are defined here:
* - Abs, Min and Max to apply to constant expressions (values known at
* compile time);
* - abs, min and max to apply to non-constant expressions (values unknown at
* compile time), abs is found in stdlib.h.
*/
//! @{
/*! \brief Takes the absolute value of \a a.
*
* \param a Input value.
*
* \return Absolute value of \a a.
*
* \note More optimized if only used with values known at compile time.
*/
#define Abs(a) (((a) < 0 ) ? -(a) : (a))
/*! \brief Takes the minimal value of \a a and \a b.
*
* \param a Input value.
* \param b Input value.
*
* \return Minimal value of \a a and \a b.
*
* \note More optimized if only used with values known at compile time.
*/
#define Min(a, b) (((a) < (b)) ? (a) : (b))
/*! \brief Takes the maximal value of \a a and \a b.
*
* \param a Input value.
* \param b Input value.
*
* \return Maximal value of \a a and \a b.
*
* \note More optimized if only used with values known at compile time.
*/
#define Max(a, b) (((a) > (b)) ? (a) : (b))
// abs() is already defined by stdlib.h
/*! \brief Takes the minimal value of \a a and \a b.
*
* \param a Input value.
* \param b Input value.
*
* \return Minimal value of \a a and \a b.
*
* \note More optimized if only used with values unknown at compile time.
*/
#define min(a, b) Min(a, b)
/*! \brief Takes the maximal value of \a a and \a b.
*
* \param a Input value.
* \param b Input value.
*
* \return Maximal value of \a a and \a b.
*
* \note More optimized if only used with values unknown at compile time.
*/
#define max(a, b) Max(a, b)
//! @}
/*! \brief Calls the routine at address \a addr.
*
* It generates a long call opcode.

View File

@ -1904,7 +1904,7 @@ static void udd_ep_in_sent(udd_ep_id_t ep)
ptr_src = &ptr_job->buf[ptr_job->buf_cnt];
nb_remain = ptr_job->buf_size - ptr_job->buf_cnt;
// Fill a bank even if no data (ZLP)
nb_data = min(nb_remain, pkt_size);
nb_data = MIN(nb_remain, pkt_size);
// Modify job information
ptr_job->buf_cnt += nb_data;
ptr_job->buf_load = nb_data;

View File

@ -290,7 +290,7 @@ extern "C" {
//! Bounds given integer size to allowed range and rounds it up to the nearest
//! available greater size, then applies register format of UOTGHS controller
//! for endpoint size bit-field.
#define udd_format_endpoint_size(size) (32 - clz(((uint32_t)min(max(size, 8), 1024) << 1) - 1) - 1 - 3)
#define udd_format_endpoint_size(size) (32 - clz(((uint32_t)MIN(MAX(size, 8), 1024) << 1) - 1) - 1 - 3)
//! Configures the selected endpoint size
#define udd_configure_endpoint_size(ep, size) (Wr_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPSIZE_Msk, udd_format_endpoint_size(size)))
//! Gets the configured selected endpoint size

View File

@ -84,7 +84,7 @@ void swSpiBegin(const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin)
uint8_t swSpiInit(const uint8_t spiRate, const pin_t sck_pin, const pin_t mosi_pin) {
WRITE(mosi_pin, HIGH);
WRITE(sck_pin, LOW);
return (SystemCoreClock == 120000000 ? 44 : 38) / POW(2, 6 - min(spiRate, 6));
return (SystemCoreClock == 120000000 ? 44 : 38) / POW(2, 6 - MIN(spiRate, 6));
}
#endif // TARGET_LPC1768

View File

@ -50,9 +50,11 @@ typedef uint8_t byte;
#define PSTR(v) (v)
#define PGM_P const char *
// Used for libraries, preprocessor, and constants
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#ifndef isnan
#define isnan std::isnan
#endif
@ -60,11 +62,6 @@ typedef uint8_t byte;
#define isinf std::isinf
#endif
//not constexpr until c++14
//#define max(v1, v2) std::max((int)v1,(int)v2)
//#define min(v1, v2) std::min((int)v1,(int)v2)
//#define abs(v) std::abs(v)
#define sq(v) ((v) * (v))
#define square(v) sq(v)
#define constrain(value, arg_min, arg_max) ((value) < (arg_min) ? (arg_min) :((value) > (arg_max) ? (arg_max) : (value)))

View File

@ -121,7 +121,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
timer_set_count(STEP_TIMER_DEV, 0);
timer_set_prescaler(STEP_TIMER_DEV, (uint16)(STEPPER_TIMER_PRESCALE - 1));
timer_set_reload(STEP_TIMER_DEV, 0xFFFF);
timer_set_compare(STEP_TIMER_DEV, STEP_TIMER_CHAN, min(HAL_TIMER_TYPE_MAX, (HAL_STEPPER_TIMER_RATE / frequency)));
timer_set_compare(STEP_TIMER_DEV, STEP_TIMER_CHAN, MIN(HAL_TIMER_TYPE_MAX, (HAL_STEPPER_TIMER_RATE / frequency)));
timer_attach_interrupt(STEP_TIMER_DEV, STEP_TIMER_CHAN, stepTC_Handler);
nvic_irq_set_priority(irq_num, 1);
timer_generate_update(STEP_TIMER_DEV);
@ -132,7 +132,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
timer_set_count(TEMP_TIMER_DEV, 0);
timer_set_prescaler(TEMP_TIMER_DEV, (uint16)(TEMP_TIMER_PRESCALE - 1));
timer_set_reload(TEMP_TIMER_DEV, 0xFFFF);
timer_set_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, min(HAL_TIMER_TYPE_MAX, ((F_CPU / TEMP_TIMER_PRESCALE) / frequency)));
timer_set_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, MIN(HAL_TIMER_TYPE_MAX, ((F_CPU / TEMP_TIMER_PRESCALE) / frequency)));
timer_attach_interrupt(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, tempTC_Handler);
nvic_irq_set_priority(irq_num, 2);
timer_generate_update(TEMP_TIMER_DEV);

View File

@ -130,7 +130,7 @@ bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
*/
FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) {
//compare = min(compare, HAL_TIMER_TYPE_MAX);
//compare = MIN(compare, HAL_TIMER_TYPE_MAX);
switch (timer_num) {
case STEP_TIMER_NUM:
timer_set_compare(STEP_TIMER_DEV, STEP_TIMER_CHAN, compare);

View File

@ -237,7 +237,7 @@ unsigned int TMC26XStepper::getSpeed(void) { return this->speed; }
*/
char TMC26XStepper::step(int steps_to_move) {
if (this->steps_left == 0) {
this->steps_left = abs(steps_to_move); // how many steps to take
this->steps_left = ABS(steps_to_move); // how many steps to take
// determine direction based on whether steps_to_move is + or -:
if (steps_to_move > 0)
@ -257,7 +257,7 @@ char TMC26XStepper::move(void) {
// rem if (time >= this->next_step_time) {
if (abs(time - this->last_step_time) > this->step_delay) {
if (ABS(time - this->last_step_time) > this->step_delay) {
// increment or decrement the step number,
// depending on direction:
if (this->direction == 1)

View File

@ -99,7 +99,7 @@ int8_t Servo::attach(const int pin, const int min, const int max) {
if (pin > 0) servo_info[this->servoIndex].Pin.nbr = pin;
pinMode(servo_info[this->servoIndex].Pin.nbr, OUTPUT); // set servo pin to output
// todo min/max check: abs(min - MIN_PULSE_WIDTH) /4 < 128
// todo min/max check: ABS(min - MIN_PULSE_WIDTH) /4 < 128
this->min = (MIN_PULSE_WIDTH - min) / 4; //resolution of min/max is 4 uS
this->max = (MAX_PULSE_WIDTH - max) / 4;