#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "curly.h"
#include "functies.h"
#include "mt19937ar.h"
#include "worker.h"
real fact(real z) {
real r = 1.0;
while(z > 1.0 && !isinf(r)) {
r *= z;
z -= 1.0;
}
// if(z != 1.0) r *= correctiefactor;
return r;
}
real invfact(real z) {
real r = 1.0;
if(!finite(z))
return 0.0/0.0;
while(z > r + 0.99999) {
r += 1.0;
z /= r;
}
if(z > 1.0) r += (z - 1.0) / r;
return r;
}
real upow(real x, u64 e) {
if(!e)
return 1.0;
if(e&1)
return x * upow(x, e - 1);
else
return x = upow(x, e >> 1), x * x;
}
real spow(real x, s64 e) {
return e < 0 ? 1.0 / upow(x, -e) : upow(x, e);
}
u64 dice(int m, int n) {
u64 r = 0;
if(n < 0 || m < 0)
return ~0;
if(n == 0 || m == 0)
return 0;
if(n > 65536)
return 2*dice(m, n/2-1) + dice(m, 2+n%2);
do
r += mt_genrand32_bounded(0, m) + 1;
while(--n > 0);
return r;
}
real realdice(int m, int n) {
u64 r = dice(m, n);
return r == ~0 ? 0.0/0.0 : (real)r;
}
real gcd(real m, real n) {
if(m < 0.0)
m = -m;
if(n < 0.0)
n = -n;
return n > 0.0 ? gcd(n, fmod(m, n)) : m;
}
real lcm(real m, real n) {
if(m < 0.0)
m = -m;
if(n < 0.0)
n = -m;
return m * n / gcd(m, n);
}
bool isint(real x) {
if(!finite(x))
return false;
if(fabs(floor(x) - x) < 1e-14
|| fabs(ceil(x) - x) < 1.0e-14L)
return true;
return false;
}
bool isnoemer(real x, real n) {
if(fabs(floor(x * n) - x * n) < n * 1.0e-14L
|| fabs(ceil(x * n) - x * n) < n * 1.0e-14L)
return true;
return false;
}
/* Zoals geript uit util-linux (misc/ddate.c) van Druel the Chaotic. */
void makeday(int imonth, int iday, int iyear, struct disc_time *funkychickens) {
static const int cal[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int dayspast = 0;
/* basic range checks */
if (imonth < 1 || imonth > 12) {
funkychickens->season = -1;
return;
}
if (iday < 1 || iday > cal[imonth-1]) {
if (!(imonth == 2 && iday == 29 && iyear%4 == 0 &&
(iyear%100 != 0 || iyear%400 == 0))) {
funkychickens->season = -1;
return;
}
}
imonth--;
funkychickens->year = iyear + 1166;
while(imonth > 0)
dayspast += cal[--imonth];
funkychickens->day = dayspast+iday-1;
funkychickens->season = 0;
if((funkychickens->year % 4) == 2) {
if (funkychickens->day==59 && iday==29)
funkychickens->day = -1;
}
funkychickens->yday = funkychickens->day;
while(funkychickens->day >= 73) {
funkychickens->season++;
funkychickens->day -= 73;
}
return;
}
static bool grepvaluta(splitline_t *l) {
real *koers;
koers = splitbuf_userdata(l);
*koers = strtor(l->buf, NULL);
return true;
}
real wisselkoers(const char *valuta) {
splitbuf_t b, *q;
real koers;
q = qnew();
qprintf(q, "http://download.finance.yahoo.com/d/quotes.csv?s=EUR");
url_encode(q, valuta);
qprintf(q, "=X&f=l1");
splitbuf_finish(q);
splitbuf_init(&b);
b.keepempty = false;
b.keepdelim = false;
b.hook = grepvaluta;
b.userdata = &koers;
url_fetch(&b, splitline(q)->buf);
splitbuf_clean(&b);
return 1.0/koers;
}