ReactOS 0.4.16-dev-2104-gb84fa49
math.c File Reference
#include <assert.h>
#include <complex.h>
#include <stdio.h>
#include <fenv.h>
#include <fpieee.h>
#include <limits.h>
#include <locale.h>
#include <math.h>
#include "msvcrt.h"
#include "winternl.h"
#include "wine/asm.h"
#include "wine/debug.h"
#include <stdlib.h>
Include dependency graph for math.c:

Go to the source code of this file.

Macros

#define _DOMAIN   1 /* domain error in argument */
 
#define _SING   2 /* singularity */
 
#define _OVERFLOW   3 /* range overflow */
 
#define _UNDERFLOW   4 /* range underflow */
 
#define SET_X87_CW(MASK)
 
#define RESET_X87_CW
 

Typedefs

typedef int(CDECLMSVCRT_matherr_func) (struct _exception *)
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (msvcrt)
 
void msvcrt_init_math (void *module)
 
static double ret_nan (BOOL update_sw)
 
int CDECL _matherr (struct _exception *e)
 
double math_error (int type, const char *name, double arg1, double arg2, double retval)
 
void CDECL __setusermatherr (MSVCRT_matherr_func func)
 
int CDECL _set_SSE2_enable (int flag)
 
float CDECL _chgsignf (float num)
 
int CDECL _fpclassf (float num)
 
int CDECL _finitef (float num)
 
int CDECL _isnanf (float num)
 
float CDECL MSVCRT_atanf (float x)
 
short CDECL _fdclass (float x)
 
static BOOL sqrtf_validate (float *x)
 
float CDECL MSVCRT_sqrtf (float x)
 
float CDECL MSVCRT_tanhf (float x)
 
double CDECL MSVCRT_asin (double x)
 
double CDECL MSVCRT_atan (double x)
 
double CDECL MSVCRT_exp (double x)
 
short CDECL _dclass (double x)
 
static BOOL sqrt_validate (double *x, BOOL update_sw)
 
double CDECL MSVCRT_sqrt (double x)
 
double CDECL MSVCRT_tanh (double x)
 
int CDECL _fpclass (double num)
 
unsigned int CDECL MSVCRT__rotl (unsigned int num, int shift)
 
__msvcrt_ulong CDECL MSVCRT__lrotl (__msvcrt_ulong num, int shift)
 
__msvcrt_ulong CDECL MSVCRT__lrotr (__msvcrt_ulong num, int shift)
 
unsigned int CDECL MSVCRT__rotr (unsigned int num, int shift)
 
unsigned __int64 CDECL MSVCRT__rotl64 (unsigned __int64 num, int shift)
 
unsigned __int64 CDECL MSVCRT__rotr64 (unsigned __int64 num, int shift)
 
int CDECL abs (int n)
 
__msvcrt_long CDECL labs (__msvcrt_long n)
 
__int64 CDECL _abs64 (__int64 n)
 
static void _setfp (unsigned int *cw, unsigned int cw_mask, unsigned int *sw, unsigned int sw_mask)
 
unsigned int CDECL _statusfp (void)
 
unsigned int CDECL _clearfp (void)
 
int *CDECL __fpecode (void)
 
double CDECL ldexp (double num, int exp)
 
double CDECL _cabs (struct _complex num)
 
double CDECL _chgsign (double num)
 
unsigned int CDECL _control87 (unsigned int newval, unsigned int mask)
 
unsigned int CDECL _controlfp (unsigned int newval, unsigned int mask)
 
void CDECL _set_controlfp (unsigned int newval, unsigned int mask)
 
int CDECL _controlfp_s (unsigned int *cur, unsigned int newval, unsigned int mask)
 
int CDECL _finite (double num)
 
void CDECL _fpreset (void)
 
int CDECL _isnan (double num)
 
char *CDECL _ecvt (double number, int ndigits, int *decpt, int *sign)
 
int CDECL _ecvt_s (char *buffer, size_t length, double number, int ndigits, int *decpt, int *sign)
 
char *CDECL _fcvt (double number, int ndigits, int *decpt, int *sign)
 
int CDECL _fcvt_s (char *outbuffer, size_t size, double number, int ndigits, int *decpt, int *sign)
 
char *CDECL _gcvt (double number, int ndigit, char *buff)
 
int CDECL _gcvt_s (char *buff, size_t size, double number, int digits)
 
div_t CDECL div (int num, int denom)
 
ldiv_t CDECL ldiv (__msvcrt_long num, __msvcrt_long denom)
 
double CDECL _scalb (double num, __msvcrt_long power)
 
float CDECL _scalbf (float num, __msvcrt_long power)
 

Variables

static MSVCRT_matherr_func MSVCRT_default_matherr_func = NULL
 
BOOL sse2_supported
 
static BOOL sse2_enabled
 

Macro Definition Documentation

◆ _DOMAIN

#define _DOMAIN   1 /* domain error in argument */

Definition at line 62 of file math.c.

◆ _OVERFLOW

#define _OVERFLOW   3 /* range overflow */

Definition at line 64 of file math.c.

◆ _SING

#define _SING   2 /* singularity */

Definition at line 63 of file math.c.

◆ _UNDERFLOW

#define _UNDERFLOW   4 /* range underflow */

Definition at line 65 of file math.c.

◆ RESET_X87_CW

#define RESET_X87_CW
Value:
"movw (%esp), %ax\n\t" \
"cmpw %ax, 2(%esp)\n\t" \
"je 1f\n\t" \
"fstpl 8(%esp)\n\t" \
"fldcw (%esp)\n\t" \
"fldl 8(%esp)\n\t" \
"fwait\n\t" \
"1:\n\t" \
"addl $4, %esp\n\t" \
__ASM_CFI(".cfi_adjust_cfa_offset -4\n\t")

Definition at line 104 of file math.c.

◆ SET_X87_CW

#define SET_X87_CW (   MASK)
Value:
"subl $4, %esp\n\t" \
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") \
"fnstcw (%esp)\n\t" \
"movw (%esp), %ax\n\t" \
"movw %ax, 2(%esp)\n\t" \
"testw $" #MASK ", %ax\n\t" \
"jz 1f\n\t" \
"andw $~" #MASK ", %ax\n\t" \
"movw %ax, 2(%esp)\n\t" \
"fldcw 2(%esp)\n\t" \
"1:\n\t"
ULONG MASK
Definition: afilter.h:45

Definition at line 91 of file math.c.

Typedef Documentation

◆ MSVCRT_matherr_func

typedef int(CDECL * MSVCRT_matherr_func) (struct _exception *)

Definition at line 67 of file math.c.

Function Documentation

◆ __fpecode()

int *CDECL __fpecode ( void  )

Definition at line 1195 of file math.c.

1196{
1197 return &msvcrt_get_thread_data()->fpecode;
1198}
thread_data_t *CDECL msvcrt_get_thread_data(void)
Definition: thread.c:45

◆ __setusermatherr()

void CDECL __setusermatherr ( MSVCRT_matherr_func  func)

Definition at line 159 of file math.c.

160{
162 TRACE("new matherr handler %p\n", func);
163}
static MSVCRT_matherr_func MSVCRT_default_matherr_func
Definition: math.c:69
GLenum func
Definition: glext.h:6028
#define TRACE(s)
Definition: solgame.cpp:4

◆ _abs64()

__int64 CDECL _abs64 ( __int64  n)

Definition at line 711 of file math.c.

712{
713 return n >= 0 ? n : -n;
714}
GLdouble n
Definition: glext.h:7729

◆ _cabs()

double CDECL _cabs ( struct _complex  num)

Definition at line 1219 of file math.c.

1220{
1221 return sqrt(num.x * num.x + num.y * num.y);
1222}
_ACRTIMP double __cdecl sqrt(double)
Definition: sqrt.c:5
GLuint GLuint num
Definition: glext.h:9618

◆ _chgsign()

double CDECL _chgsign ( double  num)

Definition at line 1227 of file math.c.

1228{
1229 union { double f; UINT64 i; } u = { num };
1230 u.i ^= 1ull << 63;
1231 return u.f;
1232}
unsigned long long UINT64
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
#define f
Definition: ke_i.h:83

◆ _chgsignf()

float CDECL _chgsignf ( float  num)

Definition at line 203 of file math.c.

204{
205 union { float f; UINT32 i; } u = { num };
206 u.i ^= 0x80000000;
207 return u.f;
208}
unsigned int UINT32

◆ _clearfp()

unsigned int CDECL _clearfp ( void  )

Definition at line 1174 of file math.c.

1175{
1176 unsigned int flags = 0;
1177#ifdef __i386__
1178 _setfp(NULL, 0, &flags, _MCW_EM);
1179 if (sse2_supported)
1180 {
1181 unsigned int sse_sw = 0;
1182
1183 _setfp_sse(NULL, 0, &sse_sw, _MCW_EM);
1184 flags |= sse_sw;
1185 }
1186#else
1187 _setfp(NULL, 0, &flags, _MCW_EM);
1188#endif
1189 return flags;
1190}
#define NULL
Definition: types.h:112
#define _MCW_EM
Definition: float.h:64
BOOL sse2_supported
Definition: math.c:71
static void _setfp(unsigned int *cw, unsigned int cw_mask, unsigned int *sw, unsigned int sw_mask)
Definition: math.c:842
GLbitfield flags
Definition: glext.h:7161

◆ _control87()

unsigned int CDECL _control87 ( unsigned int  newval,
unsigned int  mask 
)

Definition at line 1265 of file math.c.

1266{
1267 unsigned int flags = 0;
1268#if defined(__i386__) && (_MSVCR_VER == 0 || _MSVCR_VER >= 80)
1269 unsigned int sse2_cw;
1270
1271 __control87_2( newval, mask, &flags, &sse2_cw );
1272
1273 if (sse2_supported)
1274 {
1275 if ((flags ^ sse2_cw) & (_MCW_EM | _MCW_RC)) flags |= _EM_AMBIGUOUS;
1276 flags |= sse2_cw;
1277 }
1278#else
1279 flags = newval;
1280 _setfp(&flags, mask, NULL, 0);
1281#endif
1282 return flags;
1283}
#define _MCW_RC
Definition: float.h:66
#define _EM_AMBIGUOUS
Definition: float.h:90
GLenum GLint GLuint mask
Definition: glext.h:6028

Referenced by _controlfp().

◆ _controlfp()

unsigned int CDECL _controlfp ( unsigned int  newval,
unsigned int  mask 
)

Definition at line 1288 of file math.c.

1289{
1290 return _control87( newval, mask & ~_EM_DENORMAL );
1291}
#define _EM_DENORMAL
Definition: float.h:72
unsigned int CDECL _control87(unsigned int newval, unsigned int mask)
Definition: math.c:1265

Referenced by _controlfp_s(), and _set_controlfp().

◆ _controlfp_s()

int CDECL _controlfp_s ( unsigned int cur,
unsigned int  newval,
unsigned int  mask 
)

Definition at line 1304 of file math.c.

1305{
1306 static const unsigned int all_flags = (_MCW_EM | _MCW_IC | _MCW_RC |
1307 _MCW_PC | _MCW_DN);
1308 unsigned int val;
1309
1310 if (!MSVCRT_CHECK_PMT( !(newval & mask & ~all_flags) ))
1311 {
1312 if (cur) *cur = _controlfp( 0, 0 ); /* retrieve it anyway */
1313 return EINVAL;
1314 }
1315 val = _controlfp( newval, mask );
1316 if (cur) *cur = val;
1317 return 0;
1318}
#define EINVAL
Definition: errno.h:44
#define _MCW_PC
Definition: float.h:67
#define _MCW_IC
Definition: float.h:65
#define _MCW_DN
Definition: float.h:68
unsigned int CDECL _controlfp(unsigned int newval, unsigned int mask)
Definition: math.c:1288
#define MSVCRT_CHECK_PMT(x)
Definition: msvcrt.h:378
FxCollectionEntry * cur
GLuint GLfloat * val
Definition: glext.h:7180

◆ _dclass()

short CDECL _dclass ( double  x)

Referenced by sqrt_validate().

◆ _ecvt()

char *CDECL _ecvt ( double  number,
int  ndigits,
int decpt,
int sign 
)

Definition at line 1748 of file math.c.

1749{
1750 int prec, len;
1752 /* FIXME: check better for overflow (native supports over 300 chars) */
1753 ndigits = min( ndigits, 80 - 8); /* 8 : space for sign, dec point, "e",
1754 * 4 for exponent and one for
1755 * terminating '\0' */
1756 if (!data->efcvt_buffer)
1757 data->efcvt_buffer = malloc( 80 ); /* ought to be enough */
1758
1759 /* handle cases with zero ndigits or less */
1760 prec = ndigits;
1761 if( prec < 1) prec = 2;
1762 len = _snprintf(data->efcvt_buffer, 80, "%.*le", prec - 1, number);
1763
1764 if (data->efcvt_buffer[0] == '-') {
1765 memmove( data->efcvt_buffer, data->efcvt_buffer + 1, len-- );
1766 *sign = 1;
1767 } else *sign = 0;
1768
1769 /* take the decimal "point away */
1770 if( prec != 1)
1771 memmove( data->efcvt_buffer + 1, data->efcvt_buffer + 2, len - 1 );
1772 /* take the exponential "e" out */
1773 data->efcvt_buffer[ prec] = '\0';
1774 /* read the exponent */
1775 sscanf( data->efcvt_buffer + prec + 1, "%d", decpt);
1776 (*decpt)++;
1777 /* adjust for some border cases */
1778 if( data->efcvt_buffer[0] == '0')/* value is zero */
1779 *decpt = 0;
1780 /* handle cases with zero ndigits or less */
1781 if( ndigits < 1){
1782 if( data->efcvt_buffer[ 0] >= '5')
1783 (*decpt)++;
1784 data->efcvt_buffer[ 0] = '\0';
1785 }
1786 TRACE("out=\"%s\"\n",data->efcvt_buffer);
1787 return data->efcvt_buffer;
1788}
#define malloc
Definition: debug_ros.c:4
_ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl sscanf(const char *, const char *,...) __WINE_CRT_SCANF_ATTR(2
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLenum GLsizei len
Definition: glext.h:6722
#define sign(x)
Definition: mapdesc.cc:613
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
static unsigned int number
Definition: dsound.c:1479
static size_t double int ndigits
Definition: printf.c:52
static size_t double int int * decpt
Definition: printf.c:52
#define min(a, b)
Definition: monoChain.cc:55
#define _snprintf
Definition: xmlstorage.h:200

◆ _ecvt_s()

int CDECL _ecvt_s ( char buffer,
size_t  length,
double  number,
int  ndigits,
int decpt,
int sign 
)

Definition at line 1793 of file math.c.

1794{
1795 int prec, len;
1796 char *result;
1797
1798 if (!MSVCRT_CHECK_PMT(buffer != NULL)) return EINVAL;
1799 if (!MSVCRT_CHECK_PMT(decpt != NULL)) return EINVAL;
1800 if (!MSVCRT_CHECK_PMT(sign != NULL)) return EINVAL;
1801 if (!MSVCRT_CHECK_PMT_ERR( length > 2, ERANGE )) return ERANGE;
1802 if (!MSVCRT_CHECK_PMT_ERR(ndigits < (int)length - 1, ERANGE )) return ERANGE;
1803
1804 /* handle cases with zero ndigits or less */
1805 prec = ndigits;
1806 if( prec < 1) prec = 2;
1807 result = malloc(prec + 8);
1808
1809 len = _snprintf(result, prec + 8, "%.*le", prec - 1, number);
1810 if (result[0] == '-') {
1811 memmove( result, result + 1, len-- );
1812 *sign = 1;
1813 } else *sign = 0;
1814
1815 /* take the decimal "point away */
1816 if( prec != 1)
1817 memmove( result + 1, result + 2, len - 1 );
1818 /* take the exponential "e" out */
1819 result[ prec] = '\0';
1820 /* read the exponent */
1821 sscanf( result + prec + 1, "%d", decpt);
1822 (*decpt)++;
1823 /* adjust for some border cases */
1824 if( result[0] == '0')/* value is zero */
1825 *decpt = 0;
1826 /* handle cases with zero ndigits or less */
1827 if( ndigits < 1){
1828 if( result[ 0] >= '5')
1829 (*decpt)++;
1830 result[ 0] = '\0';
1831 }
1832 memcpy( buffer, result, max(ndigits + 1, 1) );
1833 free( result );
1834 return 0;
1835}
#define free
Definition: debug_ros.c:5
#define ERANGE
Definition: errno.h:55
#define MSVCRT_CHECK_PMT_ERR(x, err)
Definition: msvcrt.h:377
GLuint buffer
Definition: glext.h:5915
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLuint64EXT * result
Definition: glext.h:11304
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define max(a, b)
Definition: svc.c:63

◆ _fcvt()

char *CDECL _fcvt ( double  number,
int  ndigits,
int decpt,
int sign 
)

Definition at line 1840 of file math.c.

1841{
1843 int stop, dec1, dec2;
1844 char *ptr1, *ptr2, *first;
1845 char buf[80]; /* ought to be enough */
1846 char decimal_separator = get_locinfo()->lconv->decimal_point[0];
1847
1848 if (!data->efcvt_buffer)
1849 data->efcvt_buffer = malloc( 80 ); /* ought to be enough */
1850
1851 stop = _snprintf(buf, 80, "%.*f", ndigits < 0 ? 0 : ndigits, number);
1852 ptr1 = buf;
1853 ptr2 = data->efcvt_buffer;
1854 first = NULL;
1855 dec1 = 0;
1856 dec2 = 0;
1857
1858 if (*ptr1 == '-') {
1859 *sign = 1;
1860 ptr1++;
1861 } else *sign = 0;
1862
1863 /* For numbers below the requested resolution, work out where
1864 the decimal point will be rather than finding it in the string */
1865 if (number < 1.0 && number > 0.0) {
1866 dec2 = log10(number + 1e-10);
1867 if (-dec2 <= ndigits) dec2 = 0;
1868 }
1869
1870 /* If requested digits is zero or less, we will need to truncate
1871 * the returned string */
1872 if (ndigits < 1) {
1873 stop += ndigits;
1874 }
1875
1876 while (*ptr1 == '0') ptr1++; /* Skip leading zeroes */
1877 while (*ptr1 != '\0' && *ptr1 != decimal_separator) {
1878 if (!first) first = ptr2;
1879 if ((ptr1 - buf) < stop) {
1880 *ptr2++ = *ptr1++;
1881 } else {
1882 ptr1++;
1883 }
1884 dec1++;
1885 }
1886
1887 if (ndigits > 0) {
1888 ptr1++;
1889 if (!first) {
1890 while (*ptr1 == '0') { /* Process leading zeroes */
1891 *ptr2++ = *ptr1++;
1892 dec1--;
1893 }
1894 }
1895 while (*ptr1 != '\0') {
1896 if (!first) first = ptr2;
1897 *ptr2++ = *ptr1++;
1898 }
1899 }
1900
1901 *ptr2 = '\0';
1902
1903 /* We never found a non-zero digit, then our number is either
1904 * smaller than the requested precision, or 0.0 */
1905 if (!first) {
1906 if (number > 0.0) {
1907 first = ptr2;
1908 } else {
1909 first = data->efcvt_buffer;
1910 dec1 = 0;
1911 }
1912 }
1913
1914 *decpt = dec2 ? dec2 : dec1;
1915 return first;
1916}
double log10(double x)
Definition: freeldr.c:190
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
const GLint * first
Definition: glext.h:5794
#define e
Definition: ke_i.h:82
#define get_locinfo()
Definition: winesup.h:25

◆ _fcvt_s()

int CDECL _fcvt_s ( char outbuffer,
size_t  size,
double  number,
int  ndigits,
int decpt,
int sign 
)

Definition at line 1921 of file math.c.

1922{
1923 int stop, dec1, dec2;
1924 char *ptr1, *ptr2, *first;
1925 char buf[80]; /* ought to be enough */
1926 char decimal_separator = get_locinfo()->lconv->decimal_point[0];
1927
1928 if (!outbuffer || !decpt || !sign || size == 0)
1929 {
1930 *_errno() = EINVAL;
1931 return EINVAL;
1932 }
1933
1934 stop = _snprintf(buf, 80, "%.*f", ndigits < 0 ? 0 : ndigits, number);
1935 ptr1 = buf;
1936 ptr2 = outbuffer;
1937 first = NULL;
1938 dec1 = 0;
1939 dec2 = 0;
1940
1941 if (*ptr1 == '-') {
1942 *sign = 1;
1943 ptr1++;
1944 } else *sign = 0;
1945
1946 /* For numbers below the requested resolution, work out where
1947 the decimal point will be rather than finding it in the string */
1948 if (number < 1.0 && number > 0.0) {
1949 dec2 = log10(number + 1e-10);
1950 if (-dec2 <= ndigits) dec2 = 0;
1951 }
1952
1953 /* If requested digits is zero or less, we will need to truncate
1954 * the returned string */
1955 if (ndigits < 1) {
1956 stop += ndigits;
1957 }
1958
1959 while (*ptr1 == '0') ptr1++; /* Skip leading zeroes */
1960 while (*ptr1 != '\0' && *ptr1 != decimal_separator) {
1961 if (!first) first = ptr2;
1962 if ((ptr1 - buf) < stop) {
1963 if (size > 1) {
1964 *ptr2++ = *ptr1++;
1965 size--;
1966 }
1967 } else {
1968 ptr1++;
1969 }
1970 dec1++;
1971 }
1972
1973 if (ndigits > 0) {
1974 ptr1++;
1975 if (!first) {
1976 while (*ptr1 == '0') { /* Process leading zeroes */
1977 if (number == 0.0 && size > 1) {
1978 *ptr2++ = '0';
1979 size--;
1980 }
1981 ptr1++;
1982 dec1--;
1983 }
1984 }
1985 while (*ptr1 != '\0') {
1986 if (!first) first = ptr2;
1987 if (size > 1) {
1988 *ptr2++ = *ptr1++;
1989 size--;
1990 }
1991 }
1992 }
1993
1994 *ptr2 = '\0';
1995
1996 /* We never found a non-zero digit, then our number is either
1997 * smaller than the requested precision, or 0.0 */
1998 if (!first && (number <= 0.0))
1999 dec1 = 0;
2000
2001 *decpt = dec2 ? dec2 : dec1;
2002 return 0;
2003}
int *CDECL _errno(void)
Definition: errno.c:215
GLsizeiptr size
Definition: glext.h:5919

◆ _fdclass()

short CDECL _fdclass ( float  x)

Referenced by sqrtf_validate().

◆ _finite()

int CDECL _finite ( double  num)

Definition at line 1582 of file math.c.

1583{
1584 union { double f; UINT64 i; } u = { num };
1585 return (u.i & ~0ull >> 1) < 0x7ffull << 52;
1586}

◆ _finitef()

int CDECL _finitef ( float  num)

Definition at line 239 of file math.c.

240{
241 union { float f; UINT32 i; } u = { num };
242 return (u.i & 0x7fffffff) < 0x7f800000;
243}

◆ _fpclass()

int CDECL _fpclass ( double  num)

Definition at line 595 of file math.c.

596{
597 union { double f; UINT64 i; } u = { num };
598 int e = u.i >> 52 & 0x7ff;
599 int s = u.i >> 63;
600
601 switch (e)
602 {
603 case 0:
604 if (u.i << 1) return s ? _FPCLASS_ND : _FPCLASS_PD;
605 return s ? _FPCLASS_NZ : _FPCLASS_PZ;
606 case 0x7ff:
607 if (u.i << 12) return ((u.i >> 51) & 1) ? _FPCLASS_QNAN : _FPCLASS_SNAN;
608 return s ? _FPCLASS_NINF : _FPCLASS_PINF;
609 default:
610 return s ? _FPCLASS_NN : _FPCLASS_PN;
611 }
612}
#define _FPCLASS_PZ
Definition: float.h:113
#define _FPCLASS_PD
Definition: float.h:114
#define _FPCLASS_PN
Definition: float.h:115
#define _FPCLASS_ND
Definition: float.h:111
#define _FPCLASS_QNAN
Definition: float.h:108
#define _FPCLASS_NINF
Definition: float.h:109
#define _FPCLASS_NN
Definition: float.h:110
#define _FPCLASS_SNAN
Definition: float.h:107
#define _FPCLASS_NZ
Definition: float.h:112
#define _FPCLASS_PINF
Definition: float.h:116
GLdouble s
Definition: gl.h:2039

◆ _fpclassf()

int CDECL _fpclassf ( float  num)

Definition at line 217 of file math.c.

218{
219 union { float f; UINT32 i; } u = { num };
220 int e = u.i >> 23 & 0xff;
221 int s = u.i >> 31;
222
223 switch (e)
224 {
225 case 0:
226 if (u.i << 1) return s ? _FPCLASS_ND : _FPCLASS_PD;
227 return s ? _FPCLASS_NZ : _FPCLASS_PZ;
228 case 0xff:
229 if (u.i << 9) return ((u.i >> 22) & 1) ? _FPCLASS_QNAN : _FPCLASS_SNAN;
230 return s ? _FPCLASS_NINF : _FPCLASS_PINF;
231 default:
232 return s ? _FPCLASS_NN : _FPCLASS_PN;
233 }
234}

◆ _fpreset()

void CDECL _fpreset ( void  )

Definition at line 1591 of file math.c.

1592{
1593#if (defined(__GNUC__) || defined(__clang__)) && defined(__i386__)
1594 const unsigned int x86_cw = 0x27f;
1595 __asm__ __volatile__( "fninit; fldcw %0" : : "m" (x86_cw) );
1596 if (sse2_supported)
1597 {
1598 unsigned int cw = _MCW_EM, sw = 0;
1599 _setfp_sse(&cw, ~0, &sw, ~0);
1600 }
1601#else
1602 unsigned int cw = _MCW_EM, sw = 0;
1603 _setfp(&cw, ~0, &sw, ~0);
1604#endif
1605}
__asm__(".p2align 4, 0x90\n" ".seh_proc __seh2_global_filter_func\n" "__seh2_global_filter_func:\n" "\tsub %rbp, %rax\n" "\tpush %rbp\n" "\t.seh_pushreg %rbp\n" "\tsub $32, %rsp\n" "\t.seh_stackalloc 32\n" "\t.seh_endprologue\n" "\tsub %rax, %rdx\n" "\tmov %rdx, %rbp\n" "\tjmp *%r8\n" "__seh2_global_filter_func_exit:\n" "\t.p2align 4\n" "\tadd $32, %rsp\n" "\tpop %rbp\n" "\tret\n" "\t.seh_endproc")

◆ _gcvt()

char *CDECL _gcvt ( double  number,
int  ndigit,
char buff 
)

Definition at line 2008 of file math.c.

2009{
2010 if(!buff) {
2011 *_errno() = EINVAL;
2012 return NULL;
2013 }
2014
2015 if(ndigit < 0) {
2016 *_errno() = ERANGE;
2017 return NULL;
2018 }
2019
2020 sprintf(buff, "%.*g", ndigit, number);
2021 return buff;
2022}
static unsigned char buff[32768]
Definition: fatten.c:17
#define sprintf
Definition: sprintf.c:45

◆ _gcvt_s()

int CDECL _gcvt_s ( char buff,
size_t  size,
double  number,
int  digits 
)

Definition at line 2027 of file math.c.

2028{
2029 int len;
2030
2031 if(!buff) {
2032 *_errno() = EINVAL;
2033 return EINVAL;
2034 }
2035
2036 if( digits<0 || digits>=size) {
2037 if(size)
2038 buff[0] = '\0';
2039
2040 *_errno() = ERANGE;
2041 return ERANGE;
2042 }
2043
2044 len = _scprintf("%.*g", digits, number);
2045 if(len > size) {
2046 buff[0] = '\0';
2047 *_errno() = ERANGE;
2048 return ERANGE;
2049 }
2050
2051 sprintf(buff, "%.*g", digits, number);
2052 return 0;
2053}
_ACRTIMP int __cdecl _scprintf(const char *,...) __WINE_CRT_PRINTF_ATTR(1
static const int digits[]
Definition: decode.c:71

◆ _isnan()

int CDECL _isnan ( double  num)

Definition at line 1660 of file math.c.

1661{
1662 union { double f; UINT64 i; } u = { num };
1663 return (u.i & ~0ull >> 1) > 0x7ffull << 52;
1664}

Referenced by cvt(), format_float(), ldexp(), nexttowardf(), rpn_acos(), rpn_acosh(), rpn_asin(), rpn_asinh(), rpn_atan(), rpn_atanh(), rpn_cosh(), rpn_pow_f(), rpn_sinh(), rpn_sqr_f(), rpn_tanh(), Test__isnan(), test_isnan(), TRIO_ARGS1(), ulp_error_dbl(), and ulp_error_flt().

◆ _isnanf()

int CDECL _isnanf ( float  num)

Definition at line 248 of file math.c.

249{
250 union { float f; UINT32 i; } u = { num };
251 return (u.i & 0x7fffffff) > 0x7f800000;
252}

Referenced by Test__isnanf().

◆ _matherr()

int CDECL _matherr ( struct _exception e)

Definition at line 119 of file math.c.

120{
121 return 0;
122}

◆ _scalb()

double CDECL _scalb ( double  num,
__msvcrt_long  power 
)

Definition at line 2874 of file math.c.

2875{
2876 return ldexp(num, power);
2877}
double CDECL ldexp(double num, int exp)
Definition: math.c:1204
float power
Definition: d3drm.c:3372

◆ _scalbf()

float CDECL _scalbf ( float  num,
__msvcrt_long  power 
)

Definition at line 2884 of file math.c.

2885{
2886 return ldexp(num, power);
2887}

◆ _set_controlfp()

void CDECL _set_controlfp ( unsigned int  newval,
unsigned int  mask 
)

Definition at line 1296 of file math.c.

1297{
1298 _controlfp( newval, mask );
1299}

◆ _set_SSE2_enable()

int CDECL _set_SSE2_enable ( int  flag)

Definition at line 168 of file math.c.

169{
171 return sse2_enabled;
172}
static BOOL sse2_enabled
Definition: math.c:72
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52

◆ _setfp()

static void _setfp ( unsigned int cw,
unsigned int  cw_mask,
unsigned int sw,
unsigned int  sw_mask 
)
static

Definition at line 842 of file math.c.

844{
845#if (defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)) && defined(__i386__)
846 unsigned long oldcw = 0, newcw = 0;
847 unsigned long oldsw = 0, newsw = 0;
848 unsigned int flags;
849
850 cw_mask &= _MCW_EM | _MCW_IC | _MCW_RC | _MCW_PC;
851 sw_mask &= _MCW_EM;
852
853 if (sw)
854 {
855#ifdef _MSC_VER
856 __asm { fstsw newsw }
857#else
858 __asm__ __volatile__( "fstsw %0" : "=m" (newsw) );
859#endif
860 oldsw = newsw;
861
862 flags = 0;
863 if (newsw & 0x1) flags |= _SW_INVALID;
864 if (newsw & 0x2) flags |= _SW_DENORMAL;
865 if (newsw & 0x4) flags |= _SW_ZERODIVIDE;
866 if (newsw & 0x8) flags |= _SW_OVERFLOW;
867 if (newsw & 0x10) flags |= _SW_UNDERFLOW;
868 if (newsw & 0x20) flags |= _SW_INEXACT;
869
870 *sw = (flags & ~sw_mask) | (*sw & sw_mask);
871 TRACE("x86 update sw %08x to %08x\n", flags, *sw);
872 newsw &= ~0x3f;
873 if (*sw & _SW_INVALID) newsw |= 0x1;
874 if (*sw & _SW_DENORMAL) newsw |= 0x2;
875 if (*sw & _SW_ZERODIVIDE) newsw |= 0x4;
876 if (*sw & _SW_OVERFLOW) newsw |= 0x8;
877 if (*sw & _SW_UNDERFLOW) newsw |= 0x10;
878 if (*sw & _SW_INEXACT) newsw |= 0x20;
879 *sw = flags;
880 }
881
882 if (cw)
883 {
884#ifdef _MSC_VER
885 __asm { fstcw newcw }
886#else
887 __asm__ __volatile__( "fstcw %0" : "=m" (newcw) );
888#endif
889 oldcw = newcw;
890
891 flags = 0;
892 if (newcw & 0x1) flags |= _EM_INVALID;
893 if (newcw & 0x2) flags |= _EM_DENORMAL;
894 if (newcw & 0x4) flags |= _EM_ZERODIVIDE;
895 if (newcw & 0x8) flags |= _EM_OVERFLOW;
896 if (newcw & 0x10) flags |= _EM_UNDERFLOW;
897 if (newcw & 0x20) flags |= _EM_INEXACT;
898 switch (newcw & 0xc00)
899 {
900 case 0xc00: flags |= _RC_UP|_RC_DOWN; break;
901 case 0x800: flags |= _RC_UP; break;
902 case 0x400: flags |= _RC_DOWN; break;
903 }
904 switch (newcw & 0x300)
905 {
906 case 0x0: flags |= _PC_24; break;
907 case 0x200: flags |= _PC_53; break;
908 case 0x300: flags |= _PC_64; break;
909 }
910 if (newcw & 0x1000) flags |= _IC_AFFINE;
911
912 *cw = (flags & ~cw_mask) | (*cw & cw_mask);
913 TRACE("x86 update cw %08x to %08x\n", flags, *cw);
914 newcw &= ~0x1f3f;
915 if (*cw & _EM_INVALID) newcw |= 0x1;
916 if (*cw & _EM_DENORMAL) newcw |= 0x2;
917 if (*cw & _EM_ZERODIVIDE) newcw |= 0x4;
918 if (*cw & _EM_OVERFLOW) newcw |= 0x8;
919 if (*cw & _EM_UNDERFLOW) newcw |= 0x10;
920 if (*cw & _EM_INEXACT) newcw |= 0x20;
921 switch (*cw & _MCW_RC)
922 {
923 case _RC_UP|_RC_DOWN: newcw |= 0xc00; break;
924 case _RC_UP: newcw |= 0x800; break;
925 case _RC_DOWN: newcw |= 0x400; break;
926 }
927 switch (*cw & _MCW_PC)
928 {
929 case _PC_64: newcw |= 0x300; break;
930 case _PC_53: newcw |= 0x200; break;
931 case _PC_24: newcw |= 0x0; break;
932 }
933 if (*cw & _IC_AFFINE) newcw |= 0x1000;
934 }
935
936 if (oldsw != newsw && (newsw & 0x3f))
937 {
938 struct {
939 WORD control_word;
940 WORD unused1;
941 WORD status_word;
942 WORD unused2;
943 WORD tag_word;
944 WORD unused3;
945 DWORD instruction_pointer;
946 WORD code_segment;
947 WORD unused4;
948 DWORD operand_addr;
949 WORD data_segment;
950 WORD unused5;
951 } fenv;
952
953 assert(cw);
954
955#ifdef _MSC_VER
956 __asm { fnstenv fenv }
957#else
958 __asm__ __volatile__( "fnstenv %0" : "=m" (fenv) );
959#endif
960 fenv.control_word = newcw;
961 fenv.status_word = newsw;
962#ifdef _MSC_VER
963 __asm { fldenv fenv }
964#else
965 __asm__ __volatile__( "fldenv %0" : : "m" (fenv) : "st", "st(1)",
966 "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)" );
967#endif
968 return;
969 }
970
971 if (oldsw != newsw)
972#ifdef _MSC_VER
973 __asm { fnclex }
974#else
975 __asm__ __volatile__( "fnclex" );
976#endif
977 if (oldcw != newcw)
978#ifdef _MSC_VER
979 __asm { fldcw newcw }
980#else
981 __asm__ __volatile__( "fldcw %0" : : "m" (newcw) );
982#endif
983#elif defined(__x86_64__)
984 _setfp_sse(cw, cw_mask, sw, sw_mask);
985#elif defined(__aarch64__)
986 ULONG_PTR old_fpsr = 0, fpsr = 0, old_fpcr = 0, fpcr = 0;
987 unsigned int flags;
988
989 cw_mask &= _MCW_EM | _MCW_RC;
990 sw_mask &= _MCW_EM;
991
992 if (sw)
993 {
994 __asm__ __volatile__( "mrs %0, fpsr" : "=r" (fpsr) );
995 old_fpsr = fpsr;
996
997 flags = 0;
998 if (fpsr & 0x1) flags |= _SW_INVALID;
999 if (fpsr & 0x2) flags |= _SW_ZERODIVIDE;
1000 if (fpsr & 0x4) flags |= _SW_OVERFLOW;
1001 if (fpsr & 0x8) flags |= _SW_UNDERFLOW;
1002 if (fpsr & 0x10) flags |= _SW_INEXACT;
1003 if (fpsr & 0x80) flags |= _SW_DENORMAL;
1004
1005 *sw = (flags & ~sw_mask) | (*sw & sw_mask);
1006 TRACE("aarch64 update sw %08x to %08x\n", flags, *sw);
1007 fpsr &= ~0x9f;
1008 if (*sw & _SW_INVALID) fpsr |= 0x1;
1009 if (*sw & _SW_ZERODIVIDE) fpsr |= 0x2;
1010 if (*sw & _SW_OVERFLOW) fpsr |= 0x4;
1011 if (*sw & _SW_UNDERFLOW) fpsr |= 0x8;
1012 if (*sw & _SW_INEXACT) fpsr |= 0x10;
1013 if (*sw & _SW_DENORMAL) fpsr |= 0x80;
1014 *sw = flags;
1015 }
1016
1017 if (cw)
1018 {
1019 __asm__ __volatile__( "mrs %0, fpcr" : "=r" (fpcr) );
1020 old_fpcr = fpcr;
1021
1022 flags = 0;
1023 if (!(fpcr & 0x100)) flags |= _EM_INVALID;
1024 if (!(fpcr & 0x200)) flags |= _EM_ZERODIVIDE;
1025 if (!(fpcr & 0x400)) flags |= _EM_OVERFLOW;
1026 if (!(fpcr & 0x800)) flags |= _EM_UNDERFLOW;
1027 if (!(fpcr & 0x1000)) flags |= _EM_INEXACT;
1028 if (!(fpcr & 0x8000)) flags |= _EM_DENORMAL;
1029 switch (fpcr & 0xc00000)
1030 {
1031 case 0x400000: flags |= _RC_UP; break;
1032 case 0x800000: flags |= _RC_DOWN; break;
1033 case 0xc00000: flags |= _RC_CHOP; break;
1034 }
1035
1036 *cw = (flags & ~cw_mask) | (*cw & cw_mask);
1037 TRACE("aarch64 update cw %08x to %08x\n", flags, *cw);
1038 fpcr &= ~0xc09f00ul;
1039 if (!(*cw & _EM_INVALID)) fpcr |= 0x100;
1040 if (!(*cw & _EM_ZERODIVIDE)) fpcr |= 0x200;
1041 if (!(*cw & _EM_OVERFLOW)) fpcr |= 0x400;
1042 if (!(*cw & _EM_UNDERFLOW)) fpcr |= 0x800;
1043 if (!(*cw & _EM_INEXACT)) fpcr |= 0x1000;
1044 if (!(*cw & _EM_DENORMAL)) fpcr |= 0x8000;
1045 switch (*cw & _MCW_RC)
1046 {
1047 case _RC_CHOP: fpcr |= 0xc00000; break;
1048 case _RC_UP: fpcr |= 0x400000; break;
1049 case _RC_DOWN: fpcr |= 0x800000; break;
1050 }
1051 }
1052
1053 /* mask exceptions if needed */
1054 if (old_fpcr != fpcr && ~(old_fpcr >> 8) & fpsr & 0x9f != fpsr & 0x9f)
1055 {
1056 ULONG_PTR mask = fpcr & ~0x9f00;
1057 __asm__ __volatile__( "msr fpcr, %0" :: "r" (mask) );
1058 }
1059
1060 if (old_fpsr != fpsr)
1061 __asm__ __volatile__( "msr fpsr, %0" :: "r" (fpsr) );
1062 if (old_fpcr != fpcr)
1063 __asm__ __volatile__( "msr fpcr, %0" :: "r" (fpcr) );
1064#elif defined(__arm__)
1065 DWORD old_fpscr, fpscr;
1066 unsigned int flags;
1067
1068 __asm__ __volatile__( "vmrs %0, fpscr" : "=r" (fpscr) );
1069 old_fpscr = fpscr;
1070
1071 cw_mask &= _MCW_EM | _MCW_RC;
1072 sw_mask &= _MCW_EM;
1073
1074 if (sw)
1075 {
1076 flags = 0;
1077 if (fpscr & 0x1) flags |= _SW_INVALID;
1078 if (fpscr & 0x2) flags |= _SW_ZERODIVIDE;
1079 if (fpscr & 0x4) flags |= _SW_OVERFLOW;
1080 if (fpscr & 0x8) flags |= _SW_UNDERFLOW;
1081 if (fpscr & 0x10) flags |= _SW_INEXACT;
1082 if (fpscr & 0x80) flags |= _SW_DENORMAL;
1083
1084 *sw = (flags & ~sw_mask) | (*sw & sw_mask);
1085 TRACE("arm update sw %08x to %08x\n", flags, *sw);
1086 fpscr &= ~0x9f;
1087 if (*sw & _SW_INVALID) fpscr |= 0x1;
1088 if (*sw & _SW_ZERODIVIDE) fpscr |= 0x2;
1089 if (*sw & _SW_OVERFLOW) fpscr |= 0x4;
1090 if (*sw & _SW_UNDERFLOW) fpscr |= 0x8;
1091 if (*sw & _SW_INEXACT) fpscr |= 0x10;
1092 if (*sw & _SW_DENORMAL) fpscr |= 0x80;
1093 *sw = flags;
1094 }
1095
1096 if (cw)
1097 {
1098 flags = 0;
1099 if (!(fpscr & 0x100)) flags |= _EM_INVALID;
1100 if (!(fpscr & 0x200)) flags |= _EM_ZERODIVIDE;
1101 if (!(fpscr & 0x400)) flags |= _EM_OVERFLOW;
1102 if (!(fpscr & 0x800)) flags |= _EM_UNDERFLOW;
1103 if (!(fpscr & 0x1000)) flags |= _EM_INEXACT;
1104 if (!(fpscr & 0x8000)) flags |= _EM_DENORMAL;
1105 switch (fpscr & 0xc00000)
1106 {
1107 case 0x400000: flags |= _RC_UP; break;
1108 case 0x800000: flags |= _RC_DOWN; break;
1109 case 0xc00000: flags |= _RC_CHOP; break;
1110 }
1111
1112 *cw = (flags & ~cw_mask) | (*cw & cw_mask);
1113 TRACE("arm update cw %08x to %08x\n", flags, *cw);
1114 fpscr &= ~0xc09f00ul;
1115 if (!(*cw & _EM_INVALID)) fpscr |= 0x100;
1116 if (!(*cw & _EM_ZERODIVIDE)) fpscr |= 0x200;
1117 if (!(*cw & _EM_OVERFLOW)) fpscr |= 0x400;
1118 if (!(*cw & _EM_UNDERFLOW)) fpscr |= 0x800;
1119 if (!(*cw & _EM_INEXACT)) fpscr |= 0x1000;
1120 if (!(*cw & _EM_DENORMAL)) fpscr |= 0x8000;
1121 switch (*cw & _MCW_RC)
1122 {
1123 case _RC_CHOP: fpscr |= 0xc00000; break;
1124 case _RC_UP: fpscr |= 0x400000; break;
1125 case _RC_DOWN: fpscr |= 0x800000; break;
1126 }
1127 }
1128
1129 if (old_fpscr != fpscr)
1130 __asm__ __volatile__( "vmsr fpscr, %0" :: "r" (fpscr) );
1131#else
1132 FIXME("not implemented\n");
1133 if (cw) *cw = 0;
1134 if (sw) *sw = 0;
1135#endif
1136}
#define FIXME(fmt,...)
Definition: precomp.h:53
#define assert(_expr)
Definition: assert.h:32
#define _IC_AFFINE
Definition: float.h:77
#define _RC_UP
Definition: float.h:80
#define _SW_INEXACT
Definition: float.h:93
#define _PC_64
Definition: float.h:85
#define _SW_OVERFLOW
Definition: float.h:95
#define _EM_UNDERFLOW
Definition: float.h:75
#define _SW_DENORMAL
Definition: float.h:104
#define _EM_ZERODIVIDE
Definition: float.h:73
#define _EM_INEXACT
Definition: float.h:76
#define _EM_OVERFLOW
Definition: float.h:74
#define _EM_INVALID
Definition: float.h:71
#define _PC_24
Definition: float.h:83
#define _SW_ZERODIVIDE
Definition: float.h:96
#define _SW_UNDERFLOW
Definition: float.h:94
#define _RC_DOWN
Definition: float.h:81
#define _RC_CHOP
Definition: float.h:79
#define _SW_INVALID
Definition: float.h:97
#define _PC_53
Definition: float.h:84
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by _clearfp(), _control87(), _fpreset(), and _statusfp().

◆ _statusfp()

unsigned int CDECL _statusfp ( void  )

Definition at line 1156 of file math.c.

1157{
1158 unsigned int flags = 0;
1159#if defined(__i386__)
1160 unsigned int x86_sw, sse2_sw;
1161
1162 _statusfp2( &x86_sw, &sse2_sw );
1163 /* FIXME: there's no definition for ambiguous status, just return all status bits for now */
1164 flags = x86_sw | sse2_sw;
1165#else
1166 _setfp(NULL, 0, &flags, 0);
1167#endif
1168 return flags;
1169}

◆ abs()

int CDECL abs ( int  n)

Definition at line 672 of file math.c.

673{
674 return n >= 0 ? n : -n;
675}

◆ div()

div_t CDECL div ( int  num,
int  denom 
)

Definition at line 2081 of file math.c.

2082{
2083 div_t ret;
2084
2085 ret.quot = num / denom;
2086 ret.rem = num % denom;
2087 return ret;
2088}
return ret
Definition: mutex.c:146
Definition: stdlib.h:47

◆ labs()

Definition at line 680 of file math.c.

681{
682 return n >= 0 ? n : -n;
683}

◆ ldexp()

double CDECL ldexp ( double  num,
int  exp 
)

Definition at line 1204 of file math.c.

1205{
1206 double z = scalbn(num, exp);
1207
1208 if (isfinite(num) && !isfinite(z))
1209 return math_error(_OVERFLOW, "ldexp", num, exp, z);
1210 if (num && isfinite(num) && !z)
1211 return math_error(_UNDERFLOW, "ldexp", num, exp, z);
1212 return z;
1213}
#define isfinite(x)
Definition: math.h:363
_ACRTIMP double __cdecl scalbn(double, int)
Definition: scalbn.c:14
#define _UNDERFLOW
Definition: math.c:65
double math_error(int type, const char *name, double arg1, double arg2, double retval)
Definition: math.c:125
#define _OVERFLOW
Definition: math.c:64
GLdouble GLdouble z
Definition: glext.h:5874
DWORD exp
Definition: msg.c:16058

Referenced by _scalb(), and _scalbf().

◆ ldiv()

ldiv_t CDECL ldiv ( __msvcrt_long  num,
__msvcrt_long  denom 
)

Definition at line 2115 of file math.c.

2116{
2117 ldiv_t ret;
2118
2119 ret.quot = num / denom;
2120 ret.rem = num % denom;
2121 return ret;
2122}
Definition: stdlib.h:52

◆ math_error()

double math_error ( int  type,
const char name,
double  arg1,
double  arg2,
double  retval 
)

Definition at line 125 of file math.c.

126{
127 struct _exception exception = {type, (char *)name, arg1, arg2, retval};
128
129 TRACE("(%d, %s, %g, %g, %g)\n", type, debugstr_a(name), arg1, arg2, retval);
130
132 return exception.retval;
133
134 switch (type)
135 {
136 case 0:
137 /* don't set errno */
138 break;
139 case _DOMAIN:
140 *_errno() = EDOM;
141 break;
142 case _SING:
143 case _OVERFLOW:
144 *_errno() = ERANGE;
145 break;
146 case _UNDERFLOW:
147 /* don't set errno */
148 break;
149 default:
150 ERR("Unhandled math error!\n");
151 }
152
153 return exception.retval;
154}
#define ERR(fmt,...)
Definition: precomp.h:57
#define EDOM
Definition: errno.h:54
#define _DOMAIN
Definition: math.c:62
#define _SING
Definition: math.c:63
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint GLuint GLuint arg1
Definition: glext.h:9513
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514
#define debugstr_a
Definition: kernel32.h:31
Definition: name.c:39
int retval
Definition: wcstombs.cpp:91

Referenced by ldexp(), MSVCRT_asin(), MSVCRT_atan(), MSVCRT_atanf(), MSVCRT_exp(), MSVCRT_tanh(), MSVCRT_tanhf(), sqrt_validate(), and sqrtf_validate().

◆ MSVCRT__lrotl()

__msvcrt_ulong CDECL MSVCRT__lrotl ( __msvcrt_ulong  num,
int  shift 
)

Definition at line 627 of file math.c.

628{
629 shift &= 0x1f;
630 return (num << shift) | (num >> (32-shift));
631}
#define shift
Definition: input.c:1755

◆ MSVCRT__lrotr()

__msvcrt_ulong CDECL MSVCRT__lrotr ( __msvcrt_ulong  num,
int  shift 
)

Definition at line 636 of file math.c.

637{
638 shift &= 0x1f;
639 return (num >> shift) | (num << (32-shift));
640}

◆ MSVCRT__rotl()

unsigned int CDECL MSVCRT__rotl ( unsigned int  num,
int  shift 
)

Definition at line 618 of file math.c.

619{
620 shift &= 31;
621 return (num << shift) | (num >> (32-shift));
622}

◆ MSVCRT__rotl64()

unsigned __int64 CDECL MSVCRT__rotl64 ( unsigned __int64  num,
int  shift 
)

Definition at line 654 of file math.c.

655{
656 shift &= 63;
657 return (num << shift) | (num >> (64-shift));
658}

◆ MSVCRT__rotr()

unsigned int CDECL MSVCRT__rotr ( unsigned int  num,
int  shift 
)

Definition at line 645 of file math.c.

646{
647 shift &= 0x1f;
648 return (num >> shift) | (num << (32-shift));
649}

◆ MSVCRT__rotr64()

unsigned __int64 CDECL MSVCRT__rotr64 ( unsigned __int64  num,
int  shift 
)

Definition at line 663 of file math.c.

664{
665 shift &= 63;
666 return (num >> shift) | (num << (64-shift));
667}

◆ MSVCRT_asin()

double CDECL MSVCRT_asin ( double  x)

Definition at line 352 of file math.c.

353{
354#ifdef __i386__
355 unsigned int x87_cw, sse2_cw;
356 unsigned int hx = *(ULONGLONG*)&x >> 32;
357 unsigned int ix = hx & 0x7fffffff;
358
359 if (isnan(x)) return math_error(_DOMAIN, "asin", x, 0, x);
360
361 /* |x| < 1 */
362 if (ix < 0x3ff00000)
363 {
364 __control87_2(0, 0, &x87_cw, &sse2_cw);
365 if (!sse2_enabled || (x87_cw & _MCW_EM) != _MCW_EM
366 || (sse2_cw & (_MCW_EM | _MCW_RC)) != _MCW_EM)
367 return x87_asin(x);
368 }
369#else
370 if (isnan(x)) return x;
371#endif
372
373 return asin( x );
374}
#define isnan(x)
Definition: math.h:360
_ACRTIMP double __cdecl asin(double)
Definition: asin.c:31
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
uint64_t ULONGLONG
Definition: typedefs.h:67

◆ MSVCRT_atan()

double CDECL MSVCRT_atan ( double  x)

Definition at line 380 of file math.c.

381{
382 if (isnan(x)) return math_error(_DOMAIN, "atan", x, 0, x);
383 return atan( x );
384}
_ACRTIMP double __cdecl atan(double)
Definition: atan.c:44

◆ MSVCRT_atanf()

float CDECL MSVCRT_atanf ( float  x)

Definition at line 258 of file math.c.

259{
260 if (isnan(x)) return math_error(_DOMAIN, "atanf", x, 0, x);
261 return atanf( x );
262}
_ACRTIMP float __cdecl atanf(float)
Definition: atanf.c:47

◆ MSVCRT_exp()

double CDECL MSVCRT_exp ( double  x)

Definition at line 391 of file math.c.

392{
393 if (isnan( x )) return math_error(_DOMAIN, "exp", x, 0, 1.0 + x);
394 return exp( x );
395}

◆ msvcrt_init_math()

void msvcrt_init_math ( void module)

Definition at line 74 of file math.c.

75{
77#if _MSVCR_VER <=71
79#else
81#endif
82}
#define FALSE
Definition: types.h:117
BOOL WINAPI IsProcessorFeaturePresent(IN DWORD ProcessorFeature)
Definition: sysinfo.c:169
#define PF_XMMI64_INSTRUCTIONS_AVAILABLE
Definition: ketypes.h:186

◆ MSVCRT_sqrt()

double CDECL MSVCRT_sqrt ( double  x)

Definition at line 452 of file math.c.

453{
454 if (!sqrt_validate(&x, TRUE))
455 return x;
456
457 return asm_sqrt(x);
458}
#define TRUE
Definition: types.h:120
static BOOL sqrt_validate(double *x, BOOL update_sw)
Definition: math.c:400

◆ MSVCRT_sqrtf()

float CDECL MSVCRT_sqrtf ( float  x)

Definition at line 303 of file math.c.

304{
305#ifndef __i386__
306 if (!sqrtf_validate(&x))
307 return x;
308
309 return asm_sqrtf(x);
310#else
311 return sqrtf( x );
312#endif
313}
static BOOL sqrtf_validate(float *x)
Definition: math.c:268
#define sqrtf(x)
Definition: mymath.h:59

◆ MSVCRT_tanh()

double CDECL MSVCRT_tanh ( double  x)

Definition at line 464 of file math.c.

465{
466 if (isnan( x ))
467 {
468 *(UINT64*)&x |= 0x0008000000000000ULL;
469 return math_error(_DOMAIN, "tanh", x, 0, x);
470 }
471 return tanh( x );
472}
_ACRTIMP double __cdecl tanh(double)
Definition: tanh.c:46

◆ MSVCRT_tanhf()

float CDECL MSVCRT_tanhf ( float  x)

Definition at line 319 of file math.c.

320{
321 if (isnan( x ))
322 {
323 *(UINT32*)&x |= 0x400000;
324 return math_error(_DOMAIN, "tanhf", x, 0, x);
325 }
326 return tanhf( x );
327}
_ACRTIMP float __cdecl tanhf(float)
Definition: tanhf.c:49

◆ ret_nan()

static double ret_nan ( BOOL  update_sw)
inlinestatic

Definition at line 84 of file math.c.

85{
86 double x = 1.0;
87 if (!update_sw) return -NAN;
88 return (x - x) / (x - x);
89}
#define NAN
Definition: math.h:273

Referenced by JSGlobal_parseFloat(), sqrt_validate(), and sqrtf_validate().

◆ sqrt_validate()

static BOOL sqrt_validate ( double x,
BOOL  update_sw 
)
static

Definition at line 400 of file math.c.

401{
402 short c = _dclass(*x);
403
404 if (c == FP_ZERO) return FALSE;
405 if (c == FP_NAN)
406 {
407#ifdef __i386__
408 if (update_sw)
409 *x = math_error(_DOMAIN, "sqrt", *x, 0, *x);
410#else
411 /* set signaling bit */
412 *(ULONGLONG*)x |= 0x8000000000000ULL;
413#endif
414 return FALSE;
415 }
416 if (signbit(*x))
417 {
418 *x = math_error(_DOMAIN, "sqrt", *x, 0, ret_nan(update_sw));
419 return FALSE;
420 }
421 if (c == FP_INFINITE) return FALSE;
422 return TRUE;
423}
#define FP_NAN
Definition: math.h:278
#define FP_ZERO
Definition: math.h:281
#define FP_INFINITE
Definition: math.h:277
#define signbit(x)
Definition: math.h:362
static double ret_nan(BOOL update_sw)
Definition: math.c:84
short CDECL _dclass(double x)
const GLubyte * c
Definition: glext.h:8905

Referenced by MSVCRT_sqrt().

◆ sqrtf_validate()

static BOOL sqrtf_validate ( float x)
static

Definition at line 268 of file math.c.

269{
270 short c = _fdclass(*x);
271
272 if (c == FP_ZERO) return FALSE;
273 if (c == FP_NAN) return FALSE;
274 if (signbit(*x))
275 {
276 *x = math_error(_DOMAIN, "sqrtf", *x, 0, ret_nan(TRUE));
277 return FALSE;
278 }
279 if (c == FP_INFINITE) return FALSE;
280 return TRUE;
281}
short CDECL _fdclass(float x)

Referenced by MSVCRT_sqrtf().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( msvcrt  )

Variable Documentation

◆ MSVCRT_default_matherr_func

MSVCRT_matherr_func MSVCRT_default_matherr_func = NULL
static

Definition at line 69 of file math.c.

Referenced by __setusermatherr(), and math_error().

◆ sse2_enabled

BOOL sse2_enabled
static

Definition at line 72 of file math.c.

Referenced by _set_SSE2_enable(), MSVCRT_asin(), and msvcrt_init_math().

◆ sse2_supported

BOOL sse2_supported

Definition at line 71 of file math.c.

Referenced by _clearfp(), _control87(), _fpreset(), _set_SSE2_enable(), memmove(), and msvcrt_init_math().