2015-02-14 05:11:43 -08:00
# ifndef MATH_H
# define MATH_H
2013-09-23 05:23:34 -07:00
2014-05-08 06:01:36 -07:00
//Replace the standard arduino map() function to use the div function instead
2015-02-24 18:13:35 -08:00
int fastMap ( unsigned long x , int in_min , int in_max , int out_min , int out_max )
2013-09-23 05:23:34 -07:00
{
2015-02-24 18:13:35 -08:00
return ldiv ( ( ( x - in_min ) * ( out_max - out_min ) ) , ( in_max - in_min ) ) . quot + out_min ;
//return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
//This is a dedicated function that specifically handles the case of mapping 0-1023 values into a 0 to X range
//This is a common case because it means converting from a standard 10-bit analog input to a byte or 10-bit analog into 0-511 (Eg the temperature readings)
int fastMap1023toX ( unsigned long x , int in_min , int in_max , int out_min , int out_max )
{
return ( x * out_max ) > > 10 ;
2013-09-23 05:23:34 -07:00
}
2015-01-28 00:31:09 -08:00
/*
The following are all fast versions of specific divisions
2015-01-30 04:51:01 -08:00
Ref : http : //www.hackersdelight.org/divcMore.pdf
2015-01-28 00:31:09 -08:00
*/
//Unsigned divide by 10
2015-02-03 16:52:01 -08:00
unsigned int divu10 ( unsigned int n ) {
2015-12-12 14:17:55 -08:00
unsigned long q , r ;
2015-01-28 00:31:09 -08:00
q = ( n > > 1 ) + ( n > > 2 ) ;
q = q + ( q > > 4 ) ;
q = q + ( q > > 8 ) ;
q = q + ( q > > 16 ) ;
q = q > > 3 ;
r = n - q * 10 ;
return q + ( ( r + 6 ) > > 4 ) ;
// return q + (r > 9);
}
//Signed divide by 10
2015-12-12 14:17:55 -08:00
int divs10 ( long n ) {
long q , r ;
2015-01-28 00:31:09 -08:00
n = n + ( n > > 31 & 9 ) ;
q = ( n > > 1 ) + ( n > > 2 ) ;
q = q + ( q > > 4 ) ;
q = q + ( q > > 8 ) ;
q = q + ( q > > 16 ) ;
q = q > > 3 ;
r = n - q * 10 ;
return q + ( ( r + 6 ) > > 4 ) ;
// return q + (r > 9);
}
2015-02-03 16:52:01 -08:00
//Signed divide by 100
2015-12-12 14:17:55 -08:00
int divs100 ( long n ) {
2016-05-28 05:06:48 -07:00
return ( n / 100 ) ; // Amazingly, gcc is producing a better /divide by 100 function than this
2015-12-12 14:17:55 -08:00
long q , r ;
2015-02-03 16:52:01 -08:00
n = n + ( n > > 31 & 99 ) ;
q = ( n > > 1 ) + ( n > > 3 ) + ( n > > 6 ) - ( n > > 10 ) +
( n > > 12 ) + ( n > > 13 ) - ( n > > 16 ) ;
q = q + ( q > > 20 ) ;
q = q > > 6 ;
r = n - q * 100 ;
return q + ( ( r + 28 ) > > 7 ) ;
// return q + (r > 99);
}
2015-02-14 05:11:43 -08:00
2015-06-11 20:18:36 -07:00
//Unsigned divide by 100
2015-08-23 01:04:53 -07:00
unsigned long divu100 ( unsigned long n ) {
2016-05-28 05:06:48 -07:00
//return (n / 100); // No difference with this on/off
2015-08-23 01:04:53 -07:00
unsigned long q , r ;
2015-06-11 20:18:36 -07:00
q = ( n > > 1 ) + ( n > > 3 ) + ( n > > 6 ) - ( n > > 10 ) +
( n > > 12 ) + ( n > > 13 ) - ( n > > 16 ) ;
q = q + ( q > > 20 ) ;
q = q > > 6 ;
r = n - q * 100 ;
return q + ( ( r + 28 ) > > 7 ) ;
// return q + (r > 99);
}
//Return x percent of y
//This is a relatively fast approximation of a percentage value.
2015-08-23 01:04:53 -07:00
unsigned long percentage ( byte x , unsigned long y )
2015-06-11 20:18:36 -07:00
{
2016-05-28 05:06:48 -07:00
return ( y * x ) / 100 ; //For some reason this is faster
//return divu100(y * x);
2015-06-11 20:18:36 -07:00
}
2016-06-16 21:13:10 -07:00
/*
* Calculates integer power values . Same as pow ( ) but with ints
*/
inline long powint ( int factor , unsigned int exponent )
{
long product = 1 ;
while ( exponent - - )
product * = factor ;
return product ;
}
2015-02-14 05:11:43 -08:00
# endif // MATH_H