Piotr Caban : jscript: Added Number.toExponential implementation.

Alexandre Julliard julliard at winehq.org
Thu Apr 19 13:27:53 CDT 2012


Module: wine
Branch: master
Commit: c1228eb45f5e390862b6521324bd8f2b62ff2c68
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=c1228eb45f5e390862b6521324bd8f2b62ff2c68

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Thu Apr 19 15:28:59 2012 +0200

jscript: Added Number.toExponential implementation.

---

 dlls/jscript/number.c     |  107 ++++++++++++++++++++++++++++++++++++++++++++-
 dlls/jscript/tests/api.js |   15 ++++++
 2 files changed, 120 insertions(+), 2 deletions(-)

diff --git a/dlls/jscript/number.c b/dlls/jscript/number.c
index 417e9ce..e1ff50c 100644
--- a/dlls/jscript/number.c
+++ b/dlls/jscript/number.c
@@ -150,6 +150,70 @@ static inline void number_to_fixed(double val, int prec, BSTR *out)
     *out = str;
 }
 
+static inline void number_to_exponential(double val, int prec, BSTR *out)
+{
+    WCHAR buf[NUMBER_DTOA_SIZE], *pbuf;
+    int dec_point, size, buf_size, exp_size = 1;
+    BOOL neg = FALSE;
+    BSTR str;
+
+    if(val < 0) {
+        neg = TRUE;
+        val = -val;
+    }
+
+    buf_size = prec+2;
+    if(buf_size<2 || buf_size>NUMBER_DTOA_SIZE)
+        buf_size = NUMBER_DTOA_SIZE;
+    dtoa(val, buf, buf_size, &dec_point);
+    buf_size--;
+    if(prec == -1)
+        for(; buf_size>1 && buf[buf_size-1]=='0'; buf_size--)
+            buf[buf_size-1] = 0;
+
+    size = 10;
+    while(dec_point>=size || dec_point<=-size) {
+        size *= 10;
+        exp_size++;
+    }
+
+    if(buf_size == 1)
+        size = buf_size+2+exp_size; /* 2 = strlen(e+) */
+    else if(prec == -1)
+        size = buf_size+3+exp_size; /* 3 = strlen(.e+) */
+    else
+        size = prec+4+exp_size; /* 4 = strlen(0.e+) */
+    if(neg)
+        size++;
+    str = SysAllocStringLen(NULL, size);
+
+    size = 0;
+    pbuf = buf;
+    if(neg)
+        str[size++] = '-';
+    str[size++] = *pbuf++;
+    if(buf_size != 1) {
+        str[size++] = '.';
+        while(*pbuf)
+            str[size++] = *pbuf++;
+        for(; prec>buf_size-1; prec--)
+            str[size++] = '0';
+    }
+    str[size++] = 'e';
+    if(dec_point >= 0) {
+        str[size++] = '+';
+    }else {
+        str[size++] = '-';
+        dec_point = -dec_point;
+    }
+    for(str[size]='0', size+=exp_size-1; dec_point>0; dec_point/=10)
+        str[size--] = '0'+dec_point%10;
+    size += exp_size+1;
+    str[size] = 0;
+
+    *out = str;
+}
+
 /* ECMA-262 3rd Edition    15.7.4.2 */
 static HRESULT Number_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei)
@@ -330,8 +394,47 @@ static HRESULT Number_toFixed(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DI
 static HRESULT Number_toExponential(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    NumberInstance *number;
+    DOUBLE val;
+    INT prec = 0;
+    BSTR str;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    if(!(number = number_this(jsthis)))
+        return throw_type_error(ctx, ei, JS_E_NUMBER_EXPECTED, NULL);
+
+    if(arg_cnt(dp)) {
+        hres = to_int32(ctx, get_arg(dp, 0), ei, &prec);
+        if(FAILED(hres))
+            return hres;
+
+        if(prec<0 || prec>20)
+            return throw_range_error(ctx, ei, JS_E_FRACTION_DIGITS_OUT_OF_RANGE, NULL);
+    }
+
+    val = number->value;
+    if(isinf(val) || isnan(val)) {
+        VARIANT v;
+
+        num_set_val(&v, val);
+        hres = to_string(ctx, &v, ei, &str);
+        if(FAILED(hres))
+            return hres;
+    }else {
+        if(!prec)
+            prec--;
+        number_to_exponential(val, prec, &str);
+    }
+
+    if(retv) {
+        V_VT(retv) = VT_BSTR;
+        V_BSTR(retv) = str;
+    }else {
+        SysFreeString(str);
+    }
+    return S_OK;
 }
 
 static HRESULT Number_toPrecision(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js
index 70b28ef..a0e23fb 100644
--- a/dlls/jscript/tests/api.js
+++ b/dlls/jscript/tests/api.js
@@ -1046,6 +1046,21 @@ ok(tmp === "Infinity", "num(1000000000000000128) = " + tmp);
 tmp = (new Number(0.12345678901234567890123)).toFixed(20);
 ok(tmp === "0.12345678901234568000", "num(0.12345678901234567890123) = " + tmp);
 
+tmp = (new Number(2)).toExponential(3);
+ok(tmp === "2.000e+0", "num(2).toExponential(3) = " + tmp);
+tmp = (new Number(1.17e-32)).toExponential(20);
+ok(tmp === "1.17000000000000000000e-32", "num(1.17e-32).toExponential(20) = " + tmp);
+tmp = (new Number(0)).toExponential(7);
+ok(tmp === "0.0000000e+0", "num(0).toExponential(7) = " + tmp);
+tmp = (new Number(0)).toExponential(0);
+ok(tmp === "0e+0", "num(0).toExponential() = " + tmp);
+tmp = (new Number(-13.7567)).toExponential();
+ok(tmp === "-1.37567e+1", "num(-13.7567).toExponential() = " + tmp);
+tmp = (new Number(-32.1)).toExponential();
+ok(tmp === "-3.21e+1", "num(-32.1).toExponential() = " + tmp);
+tmp = (new Number(4723.4235)).toExponential();
+ok(tmp === "4.7234235e+3", "num(4723.4235).toExponential() = " + tmp);
+
 ok(Number() === 0, "Number() = " + Number());
 ok(Number(false) === 0, "Number(false) = " + Number(false));
 ok(Number("43") === 43, "Number('43') = " + Number("43"));




More information about the wine-cvs mailing list