Merge pull request #659 from ennorehling/develop

gcd and rounding error
This commit is contained in:
Enno Rehling 2017-02-18 16:08:08 +01:00 committed by GitHub
commit d5dcf14a56
3 changed files with 27 additions and 6 deletions

View File

@ -1036,6 +1036,8 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want)
static int required(int want, variant save)
{
int req = (int)(want * save.sa[0] / save.sa[1]);
int r = want * save.sa[0] % save.sa[1];
if (r>0) ++req;
return req;
}

View File

@ -405,6 +405,11 @@ static void test_make_item(CuTest *tc) {
CuAssertIntEquals(tc, 21, get_item(u, itype));
CuAssertIntEquals(tc, 284, u->region->resources->amount); /* 60% saving = 6 stones make 10 stones */
make_item(u, itype, 1);
split_allocations(u->region);
CuAssertIntEquals(tc, 22, get_item(u, itype));
CuAssertIntEquals(tc, 283, u->region->resources->amount); /* no free lunches */
rdata->modifiers[0].flags = RMF_REQUIREDBUILDING;
rdata->modifiers[0].race = NULL;
rdata->modifiers[0].btype = bt_get_or_create("mine");

View File

@ -905,6 +905,22 @@ static int parse_rules(xmlDocPtr doc)
return 0;
}
static int gcd(int num, int den) {
const int primes[] = { 3, 5, 7, 11, 0 };
int i=0, g = 1, p = 2;
while (p && p<=den && p<=num) {
if (num % p == 0 && den % p == 0) {
num /= p;
den /= p;
g *= p;
}
else {
p = primes[i++];
}
}
return g;
}
static int parse_resources(xmlDocPtr doc)
{
xmlXPathContextPtr xpath = xmlXPathNewContext(doc);
@ -1025,15 +1041,13 @@ static int parse_resources(xmlDocPtr doc)
rdata->modifiers[k].flags = RMF_SKILL;
}
else if (strcmp((const char *)propValue, "material") == 0) {
int num, den = 100;
int g, num, den = 100;
double fval = xml_fvalue(node, "value", 0);
// TODO: extract into a function for reading fractions?
num = (int)(fval * den + 0.5);
if (num % 10 == 0) {
// TODO: calculating a GCD would be better than this
num /= 10;
den /= 10;
}
g = gcd(num, den);
num /= g;
den /= g;
rdata->modifiers[k].value.sa[0] = (short)num;
rdata->modifiers[k].value.sa[1] = (short)den;
rdata->modifiers[k].flags = RMF_SAVEMATERIAL;