commit 859a5f67c167d89987dcf83f628748a8fc111880
parent 20059b1233d0b4be1f9d45f6800e0a51f9af1fd0
Author: Fredrik <moi@knutsen.co>
Date: Mon, 29 Jun 2020 01:21:35 +0100
Merge pull request #1 from Shiimoe/master
Added (useless) gamma function for calculating positive real factorials
Diffstat:
2 files changed, 34 insertions(+), 8 deletions(-)
diff --git a/src/builtin.c b/src/builtin.c
@@ -105,6 +105,24 @@ fsize nice_sin(fsize alpha)
return sin(alpha);
}
+#define gamma_upper_bound 1000
+#define gamma_resolution 1000000
+#define gamma_h gamma_upper_bound/gamma_resolution //upper bound / resolution
+
+fsize gamma_integrad(float x, fsize num) {
+ return pow(x, num) * exp(-x);
+}
+
+fsize gammae(fsize num) {
+ fsize sum = 0;
+
+ for (int i = 1; i < gamma_resolution; i++) {
+ sum += gamma_integrad(i*gamma_h, num);
+ }
+
+ return 0.5 * gamma_h * (gamma_integrad(0, num) + gamma_integrad(gamma_upper_bound, num) + 2 * sum);
+}
+
MATH_WRAPPER(sin, nice_sin)
MATH_WRAPPER(sinh, sinhl)
MATH_WRAPPER(cos, cosl)
@@ -157,23 +175,28 @@ DataValue *builtin_neg(DataValue input)
DataValue *builtin_factorial(DataValue input)
{
NumberNode *num = type_check("!", LHS, T_NUMBER, &input);
+
+ NumberNode tmp = num_to_float(*num);
+ NumberNode *new_num = malloc(sizeof(NumberNode));
+ memcpy(new_num, &tmp, sizeof(NumberNode));
+
+ DataValue *result = wrap_data(T_NUMBER, new_num);
if (num == NULL)
return NULL;
fsize integral = 0;
fsize fractional = modfl(num->value.f, &integral);
- if ((num->type == FLOAT && (fractional != 0 || num->value.f < 0))
+ if ((num->type == FLOAT && (num->value.f < 0))
|| (num->type == INT && num->value.i < 0)) {
ERROR_TYPE = EXECUTION_ERROR;
strcpy(ERROR_MSG,
- "factorial (`!') is only defined for positve integers.");
- }
-
- NumberNode tmp = num_to_float(*num);
- NumberNode *new_num = malloc(sizeof(NumberNode));
- memcpy(new_num, &tmp, sizeof(NumberNode));
+ "factorial (`!') is only defined for positve real numbers.");
+ } else if ((num->type == FLOAT && (fractional != 0))) {
+ new_num->value.f = gammae(num->value.f);
+ result->value = new_num;
+ return result;
+ }
- DataValue *result = wrap_data(T_NUMBER, new_num);
if (new_num->value.f == 0) {
new_num->value.f = 1;
result->value = new_num;
@@ -188,6 +211,7 @@ DataValue *builtin_factorial(DataValue input)
return result;
}
+
#define BINARY_FUNCTION(NAME, OP) \
NumberNode *num_ ## NAME (NumberNode lhs, NumberNode rhs) \
{ \
diff --git a/src/builtin.h b/src/builtin.h
@@ -11,6 +11,8 @@ NumberNode num_to_float(NumberNode);
NumberNode num_to_int(NumberNode);
NumberNode *upcast_pair(NumberNode, NumberNode);
+fsize gamma_func(float, fsize);
+fsize gammae(fsize);
DataValue *builtin_sin(DataValue);
DataValue *builtin_sinh(DataValue);
DataValue *builtin_cos(DataValue);