Add option to use libdivide in maths.h functions
This commit is contained in:
parent
36d285d883
commit
105534efb8
|
@ -1,6 +1,8 @@
|
||||||
#ifndef MATH_H
|
#ifndef MATH_H
|
||||||
#define MATH_H
|
#define MATH_H
|
||||||
|
|
||||||
|
#define USE_LIBDIVIDE
|
||||||
|
|
||||||
int fastMap1023toX(int, int);
|
int fastMap1023toX(int, int);
|
||||||
unsigned long percentage(byte, unsigned long);
|
unsigned long percentage(byte, unsigned long);
|
||||||
unsigned long halfPercentage(byte, unsigned long);
|
unsigned long halfPercentage(byte, unsigned long);
|
||||||
|
@ -16,4 +18,6 @@ unsigned long divu100(unsigned long);
|
||||||
//This is a new version that allows for out_min
|
//This is a new version that allows for out_min
|
||||||
#define fastMap10Bit(x, out_min, out_max) ( ( ((unsigned long)x * (out_max-out_min)) >> 10 ) + out_min)
|
#define fastMap10Bit(x, out_min, out_max) ( ( ((unsigned long)x * (out_max-out_min)) >> 10 ) + out_min)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -1,5 +1,14 @@
|
||||||
#include "maths.h"
|
#include "maths.h"
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
#include "src/libdivide/libdivide.h"
|
||||||
|
|
||||||
|
#ifdef USE_LIBDIVIDE
|
||||||
|
//Constants used for libdivide
|
||||||
|
struct libdivide::libdivide_u32_t libdiv_u32_10 = libdivide::libdivide_u32_gen(10);
|
||||||
|
struct libdivide::libdivide_u32_t libdiv_u32_100 = libdivide::libdivide_u32_gen(100);
|
||||||
|
struct libdivide::libdivide_s32_t libdiv_s32_100 = libdivide::libdivide_s32_gen(100);
|
||||||
|
struct libdivide::libdivide_u32_t libdiv_u32_200 = libdivide::libdivide_u32_gen(200);
|
||||||
|
#endif
|
||||||
|
|
||||||
//Replace the standard arduino map() function to use the div function instead
|
//Replace the standard arduino map() function to use the div function instead
|
||||||
int fastMap(unsigned long x, int in_min, int in_max, int out_min, int out_max)
|
int fastMap(unsigned long x, int in_min, int in_max, int out_min, int out_max)
|
||||||
|
@ -13,65 +22,56 @@ int fastMap(unsigned long x, int in_min, int in_max, int out_min, int out_max)
|
||||||
//return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
//return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
The following are all fast versions of specific divisions
|
|
||||||
Ref: www.hackersdelight.org/divcMore.pdf
|
|
||||||
*/
|
|
||||||
|
|
||||||
//Unsigned divide by 10
|
//Unsigned divide by 10
|
||||||
unsigned int divu10(unsigned int n)
|
unsigned int divu10(unsigned int n)
|
||||||
{
|
{
|
||||||
unsigned long q, r;
|
#ifdef USE_LIBDIVIDE
|
||||||
q = (n >> 1) + (n >> 2);
|
return libdivide::libdivide_u32_do(n, &libdiv_u32_10);
|
||||||
q = q + (q >> 4);
|
#else
|
||||||
q = q + (q >> 8);
|
return (n / 10);
|
||||||
q = q + (q >> 16);
|
#endif
|
||||||
q = q >> 3;
|
|
||||||
r = n - (q * 10);
|
|
||||||
return q + ((r + 6) >> 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Signed divide by 100
|
//Signed divide by 100
|
||||||
int divs100(long n)
|
int divs100(long n)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_LIBDIVIDE
|
||||||
|
return libdivide::libdivide_s32_do(n, &libdiv_s32_100);
|
||||||
|
#else
|
||||||
return (n / 100); // Amazingly, gcc is producing a better /divide by 100 function than this
|
return (n / 100); // Amazingly, gcc is producing a better /divide by 100 function than this
|
||||||
/*
|
#endif
|
||||||
long q, r;
|
|
||||||
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);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Unsigned divide by 100
|
//Unsigned divide by 100
|
||||||
unsigned long divu100(unsigned long n)
|
unsigned long divu100(unsigned long n)
|
||||||
{
|
{
|
||||||
//return (n / 100);
|
#ifdef USE_LIBDIVIDE
|
||||||
unsigned long q, r;
|
return libdivide::libdivide_u32_do(n, &libdiv_u32_100);
|
||||||
q = (n >> 1) + (n >> 3) + (n >> 6) - (n >> 10) +
|
#else
|
||||||
(n >> 12) + (n >> 13) - (n >> 16);
|
return (n / 100);
|
||||||
q = q + (q >> 20);
|
#endif
|
||||||
q = q >> 6;
|
|
||||||
r = n - (q * 100);
|
|
||||||
return q + ((r + 28) >> 7);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Return x percent of y
|
//Return x percent of y
|
||||||
//This is a relatively fast approximation of a percentage value.
|
//This is a relatively fast approximation of a percentage value.
|
||||||
unsigned long percentage(byte x, unsigned long y)
|
unsigned long percentage(byte x, unsigned long y)
|
||||||
{
|
{
|
||||||
return (y * x) / 100; //For some reason this is faster
|
#ifdef USE_LIBDIVIDE
|
||||||
//return divu100(y * x);
|
return libdivide::libdivide_u32_do((y * x), &libdiv_u32_100);
|
||||||
|
#else
|
||||||
|
return (y * x) / 100;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//Same as above, but 0.5% accuracy
|
//Same as above, but 0.5% accuracy
|
||||||
unsigned long halfPercentage(byte x, unsigned long y)
|
unsigned long halfPercentage(byte x, unsigned long y)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_LIBDIVIDE
|
||||||
|
return libdivide::libdivide_u32_do((y * x), &libdiv_u32_200);
|
||||||
|
#else
|
||||||
return (y * x) / 200;
|
return (y * x) / 200;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue