Bläddra i källkod

Added Math.log10() and Math.logx()

log10 is a base 10 log, and logx is a variable base, where
"Math.logx(2,4)" is a base 2 log of 4
Steven Hall 8 år sedan
förälder
incheckning
c629253d04
2 ändrade filer med 79 tillägg och 0 borttagningar
  1. 59 0
      src/optionals/gravity_math.c
  2. 20 0
      test/unittest/math/log.gravity

+ 59 - 0
src/optionals/gravity_math.c

@@ -382,6 +382,63 @@ static bool math_log (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uin
     RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
 }
 
+// returns the base 10 logarithm of x
+static bool math_log10 (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, nargs)
+    gravity_value_t value = GET_VALUE(1);
+
+    if (VALUE_ISA_NULL(value)) {
+        RETURN_VALUE(VALUE_FROM_INT(0), rindex);
+    }
+
+    if (VALUE_ISA_INT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)LOG((gravity_float_t)value.n)/(gravity_float_t)LOG((gravity_float_t)10);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+
+    if (VALUE_ISA_FLOAT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)LOG((gravity_float_t)value.f)/(gravity_float_t)LOG((gravity_float_t)10);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+
+    // should be NaN
+    RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
+}
+
+// returns the logarithm (base x) of y
+static bool math_logx (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, nargs)
+    gravity_value_t base = GET_VALUE(1);
+    gravity_value_t value = GET_VALUE(2);
+
+    if (VALUE_ISA_NULL(value)) {
+        RETURN_VALUE(VALUE_FROM_INT(0), rindex);
+    }
+
+    if (VALUE_ISA_INT(value) && VALUE_ISA_INT(base)) {
+        gravity_float_t computed_value = (gravity_float_t)LOG((gravity_float_t)value.n)/(gravity_float_t)LOG((gravity_float_t)base.n);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+
+    if (VALUE_ISA_INT(value) && VALUE_ISA_FLOAT(base)) {
+        gravity_float_t computed_value = (gravity_float_t)LOG((gravity_float_t)value.n)/(gravity_float_t)LOG((gravity_float_t)base.f);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+
+    if (VALUE_ISA_FLOAT(value) && VALUE_ISA_INT(base)) {
+        gravity_float_t computed_value = (gravity_float_t)LOG((gravity_float_t)value.f)/(gravity_float_t)LOG((gravity_float_t)base.n);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+
+    if (VALUE_ISA_FLOAT(value) && VALUE_ISA_FLOAT(base)) {
+        gravity_float_t computed_value = (gravity_float_t)LOG((gravity_float_t)value.f)/(gravity_float_t)LOG((gravity_float_t)base.f);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+
+    // should be NaN
+    RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
+}
+
 // returns the number with the highest value
 static bool math_max (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
     gravity_float_t n = FLOAT_MIN;
@@ -623,6 +680,8 @@ static void create_optional_class (void) {
     gravity_class_bind(meta, "gcf", NEW_CLOSURE_VALUE(math_gcf));
     gravity_class_bind(meta, "lcm", NEW_CLOSURE_VALUE(math_lcm));
     gravity_class_bind(meta, "log", NEW_CLOSURE_VALUE(math_log));
+    gravity_class_bind(meta, "log10", NEW_CLOSURE_VALUE(math_log10));
+    gravity_class_bind(meta, "logx", NEW_CLOSURE_VALUE(math_logx));
     gravity_class_bind(meta, "max", NEW_CLOSURE_VALUE(math_max));
     gravity_class_bind(meta, "min", NEW_CLOSURE_VALUE(math_min));
     gravity_class_bind(meta, "pow", NEW_CLOSURE_VALUE(math_pow));

+ 20 - 0
test/unittest/math/log.gravity

@@ -0,0 +1,20 @@
+#unittest {
+	name: "Test Math.log(), Math.log10(), Math.logx()";
+	error: NONE;
+	result: true;
+};
+
+func main() {
+	var r1 = Math.log(1) == 0
+	var r2 = Math.log(Math.E) == 1
+	var r3 = Math.log(Math.E*Math.E) == 2
+
+	var r4 = Math.log10(1) == 0
+	var r5 = Math.log10(10) == 1
+	var r6 = Math.log10(100) == 2
+
+	var r7 = Math.logx(2, 2) == 1
+	var r8 = Math.logx(2, 4) == 2
+	var r9 = Math.logx(5, 25) == 2
+	return r1 and r2 and r3 and r4 and r5 and r6 and r7 and r8 and r9
+}