Skip to content

Commit

Permalink
Implemented M_RatioReduce - using Euclid's Algorithm reduce the given…
Browse files Browse the repository at this point in the history
… numerator and denominator by their greatest common divisor.
  • Loading branch information
danij-deng committed Feb 18, 2011
1 parent 0a295be commit db1c489
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 2 deletions.
3 changes: 2 additions & 1 deletion doomsday/engine/api/doomsday.def
@@ -1,6 +1,6 @@
; Doomsday Engine API (Routines exported from Doomsday.exe).
;
; Highest ordinal is currently: --> 498 <--
; Highest ordinal is currently: --> 499 <--
; Other free ordinals: 30

NAME "DOOMSDAY"
Expand Down Expand Up @@ -538,6 +538,7 @@ EXPORTS
M_RunTrigger @341 NONAME
M_CeilPow2 @422 NONAME
M_NumDigits @143 NONAME
M_RatioReduce @499 NONAME

; Math.
; Binary angles.
Expand Down
3 changes: 2 additions & 1 deletion doomsday/engine/api/doomsday.h
Expand Up @@ -107,7 +107,7 @@ gameid_t DD_AddGame(const char* identityKey, const char* dataPath, const char* d
* @param rflags @see resourceFlags
* @param names One or more known potential names, seperated by semicolon e.g., "name1;name2".
* Names may include valid absolute, or relative file paths. These paths include
* valid symbolbolic escape tokens, predefined symbols into the virtual file system.
* valid symbolbolic escape tokens, predefined symbols into the virtual file system.
*/
void DD_AddGameResource(gameid_t game, resourceclass_t rclass, int rflags, const char* names, void* params);

Expand Down Expand Up @@ -531,6 +531,7 @@ void Con_SetString(const char* name, char* text);
int M_ScreenShot(const char* filename, int bits);
int M_CeilPow2(int num);
int M_NumDigits(int value);
int M_RatioReduce(int* numerator, int* denominator);

// MiscellaneousL: Time utilities.
boolean M_RunTrigger(trigger_t* trigger, timespan_t advanceTime);
Expand Down
10 changes: 10 additions & 0 deletions doomsday/engine/portable/include/m_misc.h
Expand Up @@ -135,6 +135,16 @@ int M_FloorPow2(int num);
int M_RoundPow2(int num);
int M_WeightPow2(int num, float weight);
float M_CycleIntoRange(float value, float length);

/**
* Using Euclid's Algorithm reduce the given numerator and denominator by
* their greatest common integer divisor.
* @param numerator Input and output numerator.
* @param denominator Input and output denominator.
* @return Greatest common divisor.
*/
int M_RatioReduce(int* numerator, int* denominator);

double M_SlopeToAngle(double dx, double dy);
double M_Length(double x, double y);
int M_NumDigits(int num);
Expand Down
34 changes: 34 additions & 0 deletions doomsday/engine/portable/src/m_misc.c
Expand Up @@ -341,6 +341,40 @@ void RNG_Reset(void)
rngIndex = 0, rngIndex2 = 0;
}

int M_RatioReduce(int* numerator, int* denominator)
{
assert(numerator && denominator);
{
int n, d, temp;

if(*numerator == *denominator)
return 1; // 1:1

n = abs(*numerator);
d = abs(*denominator);
// Ensure numerator is larger.
if(n < d)
{
temp = n;
n = d;
d = temp;
}

// Reduce to the common divisor.
while(d != 0)
{
temp = n;
n = d;
d = temp % d;
}

// Apply divisor.
*numerator /= n;
*denominator /= n;
return n;
}
}

/**
* Finds the power of 2 that is equal to or greater than the specified
* number.
Expand Down

0 comments on commit db1c489

Please sign in to comment.