Browse Source

Improved math_xrt and math_round

Marco Bambini 6 years ago
parent
commit
b46aeabc0d
1 changed files with 35 additions and 25 deletions
  1. 35 25
      src/optionals/gravity_math.c

+ 35 - 25
src/optionals/gravity_math.c

@@ -224,28 +224,27 @@ static bool math_xrt (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uin
     if (VALUE_ISA_NULL(value) || VALUE_ISA_NULL(base)) {
     if (VALUE_ISA_NULL(value) || VALUE_ISA_NULL(base)) {
         RETURN_VALUE(VALUE_FROM_INT(0), rindex);
         RETURN_VALUE(VALUE_FROM_INT(0), rindex);
     }
     }
-    
-    gravity_float_t n1;
-    gravity_float_t n2;
-    
-    if (VALUE_ISA_INT(value)) {
-        n1 = (gravity_float_t)value.n;
-    } else if (VALUE_ISA_FLOAT(value)) {
-        n1 = value.f;
-    } else goto report_error;
-    
-    if (VALUE_ISA_INT(base)) {
-        n2 = (gravity_float_t)base.n;
-    } else if (VALUE_ISA_FLOAT(base)) {
-        n2 = base.f;
-    } else goto report_error;
-    
-    if (n2 == 0.0) goto report_error;
-    
-    gravity_float_t computed_value = (gravity_float_t)POW(n1, 1.0/n2);
-    RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
-    
-report_error:
+
+    if (VALUE_ISA_INT(value) && VALUE_ISA_INT(base)) {
+        gravity_float_t computed_value = (gravity_float_t)pow((gravity_float_t)value.n, 1.0/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)pow((gravity_float_t)value.n, 1.0/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)pow((gravity_float_t)value.f, 1.0/base.n);
+        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)pow((gravity_float_t)value.f, 1.0/base.f);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+
     // should be NaN
     // should be NaN
     RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
     RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
 }
 }
@@ -631,14 +630,20 @@ static bool math_round (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, u
     }
     }
 
 
     if (VALUE_ISA_FLOAT(value)) {
     if (VALUE_ISA_FLOAT(value)) {
-        // check for extra parameter
+        // check for extra parameters
         gravity_int_t ndigits = 0;
         gravity_int_t ndigits = 0;
-        if (nargs == 3 && VALUE_ISA_INT(GET_VALUE(2))) {
+        bool toString = false;
+        
+        if (nargs >= 3 && VALUE_ISA_INT(GET_VALUE(2))) {
             gravity_value_t extra = GET_VALUE(2);
             gravity_value_t extra = GET_VALUE(2);
             if (VALUE_AS_INT(extra) > 0) ndigits = VALUE_AS_INT(extra);
             if (VALUE_AS_INT(extra) > 0) ndigits = VALUE_AS_INT(extra);
             if (ndigits > FLOAT_MAX_DECIMALS) ndigits = FLOAT_MAX_DECIMALS;
             if (ndigits > FLOAT_MAX_DECIMALS) ndigits = FLOAT_MAX_DECIMALS;
         }
         }
         
         
+        if (nargs >= 4 && VALUE_ISA_BOOL(GET_VALUE(3))) {
+            toString = VALUE_AS_BOOL(GET_VALUE(3));
+        }
+        
         if (ndigits) {
         if (ndigits) {
             double d = pow(10.0, (double)ndigits);
             double d = pow(10.0, (double)ndigits);
             gravity_float_t f = (gravity_float_t)(ROUND((gravity_float_t)value.f * (gravity_float_t)d)) / (gravity_float_t)d;
             gravity_float_t f = (gravity_float_t)(ROUND((gravity_float_t)value.f * (gravity_float_t)d)) / (gravity_float_t)d;
@@ -663,7 +668,12 @@ static bool math_round (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, u
                 ++p;
                 ++p;
             }
             }
             
             
-            // re-convert string to float
+            if (toString) {
+                // force string value
+                RETURN_VALUE(VALUE_FROM_CSTRING(vm, buffer), rindex);
+            }
+            
+            // default case is to re-convert string to float value
             RETURN_VALUE(VALUE_FROM_FLOAT(strtod(buffer, NULL)), rindex);
             RETURN_VALUE(VALUE_FROM_FLOAT(strtod(buffer, NULL)), rindex);
         }
         }