Skip to content

Instantly share code, notes, and snippets.

@OswaldHurlem
Created May 13, 2018 10:04
Show Gist options
  • Save OswaldHurlem/45862c270063f05442c326470c63de9e to your computer and use it in GitHub Desktop.
Save OswaldHurlem/45862c270063f05442c326470c63de9e to your computer and use it in GitHub Desktop.
#define IMPL_DIV_INT(_intT) \
inline _intT Div(_intT A, _intT B) { \
_intT q = A/B, r = A%B; \
if ((r > 0 && B < 0) || (r < 0 && B > 0)) { return q-1; } \
return q; \
}
#define IMPL_CEIL_DIV_INT(_intT) \
inline _intT CeilDiv(_intT A, _intT B) { \
_intT q = A/B, r = A%B; \
if ((r > 0 && B > 0) || (r < 0 && B < 0)) { return q+1; } \
return q; \
}
#define IMPL_REM_INT(_intT) \
inline _intT Rem(_intT A, _intT B) { \
_intT r = A%B; \
if ((r > 0 && B < 0) || (r < 0 && B > 0)) { return r+B; } \
return r; \
}
// TODO consider allowing negative value for B
#define IMPL_POW2_MLT(_intT) inline _intT Pow2Mlt( _intT A, _intT B) { return A << B; }
#define IMPL_POW2_DIV(_intT) inline _intT Pow2Div( _intT A, _intT B) { return A >> B; }
#define IMPL_POW2_REM(_intT) inline _intT Pow2Rem (_intT A, _intT B) { return A - Pow2Mlt(Pow2Div(A, B), B); }
#define IMPL_POW2_CDIV(_intT) \
inline _intT Pow2CDiv(_intT A, _intT B) { \
_intT fq = Pow2Div(A,B); \
if (A == Pow2Mlt(fq,B)) { return fq; } \
return fq + 1; \
}
IMPL_DIV_INT(int8_t)
IMPL_DIV_INT(int16_t)
IMPL_DIV_INT(int32_t)
IMPL_REM_INT(int8_t)
IMPL_REM_INT(int16_t)
IMPL_REM_INT(int32_t)
IMPL_CEIL_DIV_INT(int8_t)
IMPL_CEIL_DIV_INT(int16_t)
IMPL_CEIL_DIV_INT(int32_t)
IMPL_POW2_MLT(int8_t)
IMPL_POW2_MLT(int16_t)
IMPL_POW2_MLT(int32_t)
IMPL_POW2_DIV(int8_t)
IMPL_POW2_DIV(int16_t)
IMPL_POW2_DIV(int32_t)
IMPL_POW2_REM(int8_t)
IMPL_POW2_REM(int16_t)
IMPL_POW2_REM(int32_t)
IMPL_POW2_CDIV(int8_t)
IMPL_POW2_CDIV(int16_t)
IMPL_POW2_CDIV(int32_t)
#include "stdio.h"
#include "math.h"
void TestI8tMath()
{
int32_t Min = INT8_MIN;
int32_t Max = INT8_MAX + 1;
b32t FailedAny = 0;
for (int32_t iA = Min; iA < Max; iA++)
{
for (int32_t iB = Min; iB < Max; iB++)
{
int8_t A = (int8_t)iA;
int8_t B = (int8_t)iB;
int8_t Q = 0, R = 0, Cq = 0, SafeQ = 0, SafeR = 0, SafeCq = 0;
if (B != 0)
{
double DoubleQ = floor(1.0*A/(1.0*B));
SafeQ = (int8_t)DoubleQ;
Q = Div(A, B);
SafeR = (int8_t)(A - 1.0*B*DoubleQ);
R = Rem(A, B);
SafeCq = (int8_t)ceil(1.0*A/(1.0*B));
Cq = CeilDiv(A, B);
}
if (Q != SafeQ
|| R != SafeR
|| Cq != SafeCq)
{
printf("int8_t Test Fail: (%d, %d) -> q,r:(%d, %d), Q:(%d vs %d), R:(%d vs %d), Cq(%d vs %d)\n",
A, B, A/B, A%B, Q, SafeQ, R, SafeR, Cq, SafeCq);
FailedAny = 1;
}
}
}
int32_t MinP = 0;
int32_t MaxP = 9;
for (int32_t iA = Min; iA < Max; iA++)
{
for (int32_t iB = MinP; iB < MaxP; iB++)
{
int8_t A = (int8_t)iA;
int8_t B = (int8_t)iB;
int8_t Q = 0, R = 0, Cq = 0, SafeQ = 0, SafeR = 0, SafeCq = 0;
if (B != 0)
{
double DoubleQ = floor(1.0*A/pow(2, B));
SafeQ = (int8_t)DoubleQ;
Q = Pow2Div(A, B);
SafeR = (int8_t)(A - pow(2, B)*DoubleQ);
R = Pow2Rem(A, B);
SafeCq = (int8_t)ceil(1.0*A/pow(2, B));
Cq = Pow2CDiv(A, B);
}
if (Q != SafeQ
|| R != SafeR
|| Cq != SafeCq)
{
printf("int8_t Pow2 Fail: (%d, %d) -> M:(%d), Q:(%d vs %d), R:(%d vs %d), Cq(%d vs %d)\n",
A, B, Pow2Mlt((int8_t)1,B), Q, SafeQ, R, SafeR, Cq, SafeCq);
FailedAny = 1;
}
}
}
if (!FailedAny) { printf("All int8_t tests passed\n"); }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment