AceCommon  1.4.5
Arduino library for low-level common functions and features with no external dependencies
Functions
arithmetic.h File Reference
#include <stdint.h>
Include dependency graph for arithmetic.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

template<typename T >
void ace_common::incrementMod (T &d, T m)
 Increment 'd' mod 'm', avoiding '' operator which is expensive for 8-bit processors. More...
 
template<typename T >
void ace_common::incrementModOffset (T &d, T m, T offset)
 Increment 'd' mod 'm', with an offset, avoiding '' operator which is expensive for 8-bit processors. More...
 
uint8_t ace_common::decToBcdDivOnly (uint8_t val)
 A version of decToBcd() that uses only a single division operation. More...
 
uint8_t ace_common::decToBcdDivMod (uint8_t val)
 A version of decToBcd() that uses a division and a modulus operation. More...
 
uint8_t ace_common::decToBcd (uint8_t val)
 Convert normal decimal numbers to binary coded decimal. More...
 
uint8_t ace_common::bcdToDec (uint8_t val)
 Convert binary coded decimal to normal decimal numbers. More...
 
unsigned long ace_common::udiv1000 (unsigned long n)
 Approximate division by 1000 without using integer division to avoid inefficient integer division operations on 8-bit processors. More...
 

Detailed Description

Common functions involving arithmetics such as incrementing, addition, subtraction, division, and conversion to and from BCD (binary coded decimal).

Definition in file arithmetic.h.

Function Documentation

◆ bcdToDec()

uint8_t ace_common::bcdToDec ( uint8_t  val)
inline

Convert binary coded decimal to normal decimal numbers.

If the input val is a valid decimal number (0x00 to 0x99, using only decimal digits), the result is unspecified but probably not what you want.

Definition at line 110 of file arithmetic.h.

◆ decToBcd()

uint8_t ace_common::decToBcd ( uint8_t  val)
inline

Convert normal decimal numbers to binary coded decimal.

Uses either decToBcdDivOnly() or decToBcdDivMod() depending on which was determined to be faster on a particular platform.

If the input val is greater than 99, the result is unspecified, but is probably not what you want.

Definition at line 96 of file arithmetic.h.

◆ decToBcdDivMod()

uint8_t ace_common::decToBcdDivMod ( uint8_t  val)
inline

A version of decToBcd() that uses a division and a modulus operation.

Some compilers (e.g. AVR) seem to recognize this pattern of division-and-modulus operations, and generate code that is actually faster for this than decToBcdDivOnly(). AutoBenchmark says this version takes 4.996 micros, versus 5.128 micros for decToBcdDivOnly() on a AVR. That appears to be the difference of 2 clock cycles for a 16MHz clock.

Definition at line 83 of file arithmetic.h.

◆ decToBcdDivOnly()

uint8_t ace_common::decToBcdDivOnly ( uint8_t  val)
inline

A version of decToBcd() that uses only a single division operation.

For most 32-bit processors, this version is twice as fast as decToBcdDivMod().

Definition at line 68 of file arithmetic.h.

◆ incrementMod()

template<typename T >
void ace_common::incrementMod ( T &  d,
m 
)

Increment 'd' mod 'm', avoiding '' operator which is expensive for 8-bit processors.

For example, cycling through 0 to 9 can be done with incrementMod(count, 10).

Definition at line 46 of file arithmetic.h.

◆ incrementModOffset()

template<typename T >
void ace_common::incrementModOffset ( T &  d,
m,
offset 
)

Increment 'd' mod 'm', with an offset, avoiding '' operator which is expensive for 8-bit processors.

For example, incrementing the months of the year from 1 to 12 can be done with incrementMod(month, 12, 1).

Definition at line 57 of file arithmetic.h.

◆ udiv1000()

unsigned long ace_common::udiv1000 ( unsigned long  n)
inline

Approximate division by 1000 without using integer division to avoid inefficient integer division operations on 8-bit processors.

This can be useful for converting millis to seconds, or micros to millis, for example.

The algorithm is based on the binomial expansion of 1/(1-x):

1/1000 = 1/(1024 - 24)
= (1/2^10) * (1 / (1 - 3/2^7))
= (1/2^10) * (1 + 3/2^7 + 9/2^14 + 27/2^21 + ...)
= (1/2^10 + 3/2^17 + 9/2^24 + 27/2^31 + ...)

The truncation of this series means that this function returns approximations which are always slightly smaller than the fully accurate answer. See the unit tests for concrete examples. This approximation was good enough for me in the situations where exact accuracy was not required.

More accurate algorithms exist (see for example http://www.hackersdelight.org/divcMore.pdf).

Definition at line 136 of file arithmetic.h.