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