Created
May 13, 2018 10:04
-
-
Save OswaldHurlem/45862c270063f05442c326470c63de9e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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