msvcp: Add _Exp implementation.

Signed-off-by: Piotr Caban <piotr@codeweavers.com>
This commit is contained in:
Piotr Caban 2015-10-01 18:43:18 +02:00 committed by Alexandre Julliard
parent 643ff988c4
commit ce24b284ee
11 changed files with 136 additions and 18 deletions

View file

@ -2894,14 +2894,14 @@
@ cdecl _Dscale(ptr long)
@ cdecl _Dtest(ptr)
@ extern _Eps
@ stub _Exp
@ cdecl _Exp(ptr double long)
@ stub _FCosh
@ extern _FDenorm
@ stub _FDnorm
@ cdecl _FDscale(ptr long)
@ cdecl _FDtest(ptr)
@ extern _FEps
@ stub _FExp
@ cdecl _FExp(ptr float long)
@ extern _FInf
@ extern _FNan
# extern _FRteps

View file

@ -3748,7 +3748,7 @@
@ cdecl _Dtest(ptr)
@ stub _Dunscale
@ extern _Eps
@ stub _Exp
@ cdecl _Exp(ptr double long)
@ stub _FCosh
@ extern _FDenorm
@ stub _FDint
@ -3758,7 +3758,7 @@
@ cdecl _FDtest(ptr)
@ stub _FDunscale
@ extern _FEps
@ stub _FExp
@ cdecl _FExp(ptr float long)
@ extern _FInf
@ extern _FNan
# extern _FRteps

View file

@ -3689,7 +3689,7 @@
@ cdecl _Dtest(ptr)
@ stub _Dunscale
@ extern _Eps
@ stub _Exp
@ cdecl _Exp(ptr double long)
@ stub _FCosh
@ extern _FDenorm
@ stub _FDint
@ -3699,7 +3699,7 @@
@ cdecl _FDtest(ptr)
@ stub _FDunscale
@ extern _FEps
@ stub _FExp
@ cdecl _FExp(ptr float long)
@ extern _FInf
@ extern _FNan
@ stub _FPlsw

View file

@ -19,6 +19,7 @@
#include <locale.h>
#include <stdio.h>
#include <math.h>
#include <limits.h>
#include "wine/test.h"
#include "winbase.h"
@ -65,6 +66,22 @@ enum file_type {
type_unknown
};
static BOOL compare_float(float f, float g, unsigned int ulps)
{
int x = *(int *)&f;
int y = *(int *)&g;
if (x < 0)
x = INT_MIN - x;
if (y < 0)
y = INT_MIN - y;
if (abs(x - y) > ulps)
return FALSE;
return TRUE;
}
static inline const char* debugstr_longlong(ULONGLONG ll)
{
static char string[17];
@ -87,6 +104,7 @@ static void (CDECL *p__Call_onceEx)(int *once, void (CDECL *func)(void*), void *
static void (CDECL *p__Do_call)(void *this);
static short (__cdecl *p__Dtest)(double *d);
static short (__cdecl *p__Dscale)(double *d, int exp);
static short (__cdecl *p__FExp)(float *x, float y, int exp);
/* filesystem */
static ULONGLONG(__cdecl *p_tr2_sys__File_size)(char const*);
@ -142,6 +160,8 @@ static BOOL init(void)
"_Dtest");
SET(p__Dscale,
"_Dscale");
SET(p__FExp,
"_FExp");
if(sizeof(void*) == 8) { /* 64-bit initialization */
SET(p_tr2_sys__File_size,
"?_File_size@sys@tr2@std@@YA_KPEBD@Z");
@ -514,6 +534,61 @@ static void test__Dscale(void)
ok(ret == FP_NAN, "ret = %x\n", ret);
}
static void test__FExp(void)
{
float d;
short ret;
d = 0;
ret = p__FExp(&d, 0, 0);
ok(d == 0, "d = %f\n", d);
ok(ret == FP_ZERO, "ret = %x\n", ret);
d = 0;
ret = p__FExp(&d, 1, 0);
ok(d == 1.0, "d = %f\n", d);
ok(ret == FP_NORMAL, "ret = %x\n", ret);
d = 0;
ret = p__FExp(&d, 1, 1);
ok(d == 2.0, "d = %f\n", d);
ok(ret == FP_NORMAL, "ret = %x\n", ret);
d = 0;
ret = p__FExp(&d, 1, 2);
ok(d == 4.0, "d = %f\n", d);
ok(ret == FP_NORMAL, "ret = %x\n", ret);
d = 0;
ret = p__FExp(&d, 10, 0);
ok(d == 10.0, "d = %f\n", d);
ok(ret == FP_NORMAL, "ret = %x\n", ret);
d = 1;
ret = p__FExp(&d, 0, 0);
ok(d == 0, "d = %f\n", d);
ok(ret == FP_ZERO, "ret = %x\n", ret);
d = 1;
ret = p__FExp(&d, 1, 0);
ok(compare_float(d, 2.7182817, 4), "d = %f\n", d);
ok(ret == FP_NORMAL, "ret = %x\n", ret);
d = 9e20;
ret = p__FExp(&d, 0, 0);
ok(d == 0, "d = %f\n", d);
ok(ret == FP_ZERO, "ret = %x\n", ret);
d = 90;
ret = p__FExp(&d, 1, 0);
ok(ret == FP_INFINITE, "ret = %x\n", ret);
d = 90;
ret = p__FExp(&d, 1, -50);
ok(compare_float(d, 1.0839359e+024, 4), "d = %g\n", d);
ok(ret == FP_NORMAL, "ret = %x\n", ret);
}
static void test_tr2_sys__File_size(void)
{
ULONGLONG val;
@ -1055,6 +1130,7 @@ START_TEST(msvcp120)
test__Do_call();
test__Dtest();
test__Dscale();
test__FExp();
test_tr2_sys__File_size();
test_tr2_sys__Equivalent();

View file

@ -3689,7 +3689,7 @@
@ cdecl _Dtest(ptr) msvcp120._Dtest
@ stub _Dunscale
@ extern _Eps msvcp120._Eps
@ stub _Exp
@ cdecl _Exp(ptr double long) msvcp120._Exp
@ stub _FCosh
@ extern _FDenorm msvcp120._FDenorm
@ stub _FDint
@ -3699,7 +3699,7 @@
@ cdecl _FDtest(ptr) msvcp120._FDtest
@ stub _FDunscale
@ extern _FEps msvcp120._FEps
@ stub _FExp
@ cdecl _FExp(ptr float long) msvcp120._FExp
@ extern _FInf msvcp120._FInf
@ extern _FNan msvcp120._FNan
@ stub _FPlsw

View file

@ -4260,14 +4260,14 @@
@ cdecl _Dscale(ptr long)
@ cdecl _Dtest(ptr)
@ extern _Eps _Eps
@ stub _Exp
@ cdecl _Exp(ptr double long)
@ stub _FCosh
@ extern _FDenorm _FDenorm
@ stub _FDnorm
@ cdecl _FDscale(ptr long)
@ cdecl _FDtest(ptr)
@ extern _FEps _FEps
@ stub _FExp
@ cdecl _FExp(ptr float long)
@ extern _FInf _FInf
@ extern _FNan _FNan
# extern _FRteps

View file

@ -5046,14 +5046,14 @@
@ cdecl _Dscale(ptr long)
@ cdecl _Dtest(ptr)
@ extern _Eps
@ stub _Exp
@ cdecl _Exp(ptr double long)
@ stub _FCosh
@ extern _FDenorm
@ stub _FDnorm
@ cdecl _FDscale(ptr long)
@ cdecl _FDtest(ptr)
@ extern _FEps
@ stub _FExp
@ cdecl _FExp(ptr float long)
@ extern _FInf
@ extern _FNan
# extern _FRteps

View file

@ -5100,14 +5100,14 @@
@ cdecl _Dscale(ptr long)
@ cdecl _Dtest(ptr)
@ extern _Eps
@ stub _Exp
@ cdecl _Exp(ptr double long)
@ stub _FCosh
@ extern _FDenorm
@ stub _FDnorm
@ cdecl _FDscale(ptr long)
@ cdecl _FDtest(ptr)
@ extern _FEps
@ stub _FExp
@ cdecl _FExp(ptr float long)
@ extern _FInf
@ extern _FNan
# extern _FRteps

View file

@ -5708,7 +5708,7 @@
@ cdecl _Dtest(ptr)
@ stub _Dunscale
@ extern _Eps
@ stub _Exp
@ cdecl _Exp(ptr double long)
@ stub _FCosh
@ extern _FDenorm
@ stub _FDnorm
@ -5717,7 +5717,7 @@
@ cdecl _FDtest(ptr)
@ stub _FDunscale
@ extern _FEps
@ stub _FExp
@ cdecl _FExp(ptr float long)
@ extern _FInf
@ extern _FNan
# extern _FRteps

View file

@ -2274,3 +2274,45 @@ short __cdecl _FDscale(float *x, int exp)
*x *= pow(2, exp);
return dclass(*x);
}
/* _Exp */
/* computes y * e^(*x) * 2^scale */
short __cdecl _Exp(double *x, double y, int scale)
{
double ed;
int e;
if(y == 0) {
*x = 0;
return FP_ZERO;
}
*x /= M_LN2;
ed = floor(*x);
*x -= ed;
e = ed;
if(ed!=e && ed>0)
scale = INT_MAX;
else if(ed!=e && ed<0)
scale = INT_MIN;
else if(scale>0 && e>0 && scale+e<=0)
scale = INT_MAX;
else if(scale<0 && e<0 && scale+e>=0)
scale = INT_MIN;
else
scale += e;
*x = y * pow(2.0, *x);
return _Dscale(x, scale);
}
/* _FExp */
short __cdecl _FExp(float *x, float y, short scale)
{
double d = *x;
_Exp(&d, y, scale);
*x = d;
return dclass(*x);
}

View file

@ -6482,14 +6482,14 @@
@ cdecl _Dscale(ptr long)
@ cdecl _Dtest(ptr)
@ extern _Eps
@ stub _Exp
@ cdecl _Exp(ptr double long)
@ stub _FCosh
@ extern _FDenorm
@ stub _FDnorm
@ cdecl _FDscale(ptr long)
@ cdecl _FDtest(ptr)
@ extern _FEps
@ stub _FExp
@ cdecl _FExp(ptr float long)
@ extern _FInf
@ extern _FNan
# extern _FRteps