mirror of
https://github.com/dlang/phobos.git
synced 2025-04-29 22:50:38 +03:00
phobos 0.61
This commit is contained in:
parent
c528883866
commit
dba8d9bcaa
32 changed files with 1088 additions and 261 deletions
36
arraycat.d
36
arraycat.d
|
@ -24,6 +24,42 @@ byte[] _d_arraycat(byte[] x, byte[] y, uint size)
|
|||
return a;
|
||||
}
|
||||
|
||||
byte[] _d_arraycatn(uint size, uint n, ...)
|
||||
{ byte[] a;
|
||||
uint length;
|
||||
byte[]* p;
|
||||
uint i;
|
||||
byte[] b;
|
||||
|
||||
p = cast(byte[]*)(&n + 1);
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
b = *p++;
|
||||
length += b.length;
|
||||
}
|
||||
if (!length)
|
||||
return null;
|
||||
|
||||
a = new byte[length * size];
|
||||
p = cast(byte[]*)(&n + 1);
|
||||
|
||||
uint j = 0;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
b = *p++;
|
||||
if (b.length)
|
||||
{
|
||||
memcpy(&a[j], b, b.length * size);
|
||||
j += b.length * size;
|
||||
}
|
||||
}
|
||||
|
||||
*(int *)&a = length; // jam length
|
||||
//a.length = length;
|
||||
return a;
|
||||
}
|
||||
|
||||
byte[] _d_arraycopy(uint size, byte[] from, byte[] to)
|
||||
{
|
||||
//printf("f = %p,%d, t = %p,%d\n", (void*)from, from.length, (void*)to, to.length);
|
||||
|
|
|
@ -20,3 +20,10 @@ extern (C):
|
|||
void qsort(void *base, uint nelems, uint elemsize,
|
||||
int (*compare)(void *elem1, void *elem2));
|
||||
|
||||
char* getenv(char*);
|
||||
|
||||
int rand();
|
||||
void srand(uint);
|
||||
int random(int num);
|
||||
void randomize();
|
||||
|
||||
|
|
2
crc32.d
2
crc32.d
|
@ -14,7 +14,7 @@
|
|||
// CRC-32 calculation
|
||||
module crc;
|
||||
|
||||
static uint[256] crc32_table =
|
||||
private uint[256] crc32_table =
|
||||
[
|
||||
0x00000000,0x77073096,0xee0e612c,0x990951ba,0x076dc419,0x706af48f,0xe963a535,
|
||||
0x9e6495a3,0x0edb8832,0x79dcb8a4,0xe0d5e91e,0x97d2d988,0x09b64c2b,0x7eb17cbd,
|
||||
|
|
17
gc2/gc.d
17
gc2/gc.d
|
@ -92,19 +92,26 @@ void _d_delclass(Object *p)
|
|||
{
|
||||
if (*p)
|
||||
{
|
||||
version(none)
|
||||
version(0)
|
||||
{
|
||||
ClassInfo **pc = (ClassInfo **)*p;
|
||||
if (*pc)
|
||||
{
|
||||
ClassInfo c = **pc;
|
||||
|
||||
if (c.destructor)
|
||||
if (c.deallocator)
|
||||
{
|
||||
fp_t fp = (fp_t)c.destructor;
|
||||
(*fp)(*p); // call destructor
|
||||
if (c.destructor)
|
||||
{
|
||||
fp_t fp = (fp_t)c.destructor;
|
||||
(*fp)(*p); // call destructor
|
||||
}
|
||||
fp_t fp = (fp_t)c.deallocator;
|
||||
(*fp)(*p); // call deallocator
|
||||
*pc = null; // zero vptr
|
||||
*p = null;
|
||||
return;
|
||||
}
|
||||
*pc = null; // zero vptr
|
||||
}
|
||||
}
|
||||
_gc.free(*p);
|
||||
|
|
|
@ -139,7 +139,7 @@ debug (LOGGING)
|
|||
/* ============================ GC =============================== */
|
||||
|
||||
|
||||
alias int size_t;
|
||||
//alias int size_t;
|
||||
alias void (*GC_FINALIZER)(void *p, void *dummy);
|
||||
|
||||
class GCLock { } // just a dummy so we can get a global lock
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
DMD=..\..\dmd
|
||||
#DMD=\dmd\bin\dmd
|
||||
CFLAGS=-g -mn -6 -r -Igc
|
||||
DFLAGS=-unittest -g -release
|
||||
#DFLAGS=-unittest -g -release
|
||||
DFLAGS=-release -O -inline
|
||||
#DFLAGS=-release -inline -O
|
||||
CC=sc
|
||||
|
||||
.c.obj:
|
||||
|
|
|
@ -19,7 +19,7 @@ void printStats(GC *gc)
|
|||
{
|
||||
GCStats stats;
|
||||
|
||||
gc.getStats(stats);
|
||||
//gc.getStats(stats);
|
||||
printf("poolsize = x%x, usedsize = x%x, freelistsize = x%x, freeblocks = %d, pageblocks = %d\n",
|
||||
stats.poolsize, stats.usedsize, stats.freelistsize, stats.freeblocks, stats.pageblocks);
|
||||
}
|
||||
|
|
13
intrinsic.d
13
intrinsic.d
|
@ -23,9 +23,10 @@ ubyte outp(uint, ubyte);
|
|||
ushort outpw(uint, ushort);
|
||||
uint outpl(uint, uint);
|
||||
|
||||
extended cos(extended);
|
||||
extended fabs(extended);
|
||||
extended rint(extended);
|
||||
long rndtol(extended);
|
||||
extended sin(extended);
|
||||
extended sqrt(extended);
|
||||
real cos(real);
|
||||
real fabs(real);
|
||||
real rint(real);
|
||||
long rndtol(real);
|
||||
real sin(real);
|
||||
real sqrt(real);
|
||||
real ldexp(real, int);
|
||||
|
|
25
makefile
25
makefile
|
@ -13,10 +13,12 @@
|
|||
# This relies on LIB.EXE 8.00 or later, and MAKE.EXE 5.01 or later.
|
||||
|
||||
CFLAGS=-g -mn -6 -r
|
||||
DFLAGS=-unittest -g
|
||||
DFLAGS=-O -release
|
||||
#DFLAGS=-unittest -g
|
||||
|
||||
CC=sc
|
||||
DMD=\dmd\bin\dmd
|
||||
#DMD=..\dmd
|
||||
#DMD=\dmd\bin\dmd
|
||||
DMD=..\dmd
|
||||
|
||||
.c.obj:
|
||||
$(CC) -c $(CFLAGS) $*
|
||||
|
@ -56,10 +58,13 @@ OBJS= assert.obj deh.obj switch.obj complex.obj gcstats.obj \
|
|||
stream.obj switcherr.obj com.obj array.obj gc.obj adi.obj \
|
||||
qsort.obj math2.obj date.obj dateparse.obj thread.obj obj.obj \
|
||||
iunknown.obj crc32.obj conv.obj arraycast.obj \
|
||||
ti_Aa.obj ti_C.obj ti_int.obj ti_char.obj \
|
||||
ti_Aa.obj ti_Ag.obj ti_C.obj ti_int.obj ti_char.obj \
|
||||
ti_wchar.obj ti_uint.obj ti_short.obj ti_ushort.obj \
|
||||
ti_byte.obj ti_ubyte.obj ti_long.obj ti_ulong.obj ti_ptr.obj \
|
||||
ti_float.obj ti_double.obj ti_extended.obj ti_delegate.obj
|
||||
ti_float.obj ti_double.obj ti_real.obj ti_delegate.obj \
|
||||
ti_creal.obj ti_ireal.obj \
|
||||
ti_cfloat.obj ti_ifloat.obj \
|
||||
ti_cdouble.obj ti_idouble.obj
|
||||
|
||||
HDR=mars.h
|
||||
|
||||
|
@ -76,14 +81,16 @@ SRC4=dchar.d ctype.d achar.d aaA.d adi.d file.d compiler.d system.d \
|
|||
moduleinit.d cast.d math.d qsort.d
|
||||
|
||||
SRC5=outbuffer.d unittest.d stream.d ctype.d regexp.d random.d adi.d \
|
||||
ti_Aa.d ti_C.d ti_int.d ti_char.d
|
||||
ti_Aa.d ti_Ag.d ti_C.d ti_int.d ti_char.d
|
||||
|
||||
SRC6=math2.d thread.d obj.d iunknown.d intrinsic.d time.d memset.c \
|
||||
SRC6=math2.d thread.d obj.d iunknown.d intrinsic.d time.d memset.d \
|
||||
array.d switcherr.d arraycast.d
|
||||
|
||||
SRC7=ti_wchar.d ti_uint.d ti_short.d ti_ushort.d \
|
||||
ti_byte.d ti_ubyte.d ti_long.d ti_ulong.d ti_ptr.d \
|
||||
ti_float.d ti_double.d ti_extended.d ti_delegate.d
|
||||
ti_float.d ti_double.d ti_real.d ti_delegate.d \
|
||||
ti_creal.d ti_ireal.d ti_cfloat.d ti_ifloat.d \
|
||||
ti_cdouble.d ti_idouble.d
|
||||
|
||||
SRC8=crc32.d stdint.d conv.d gcstats.d
|
||||
|
||||
|
@ -109,6 +116,7 @@ gc.obj : gc.d
|
|||
invariant.obj : invariant.d
|
||||
math.obj : math.d
|
||||
math2.obj : math2.d
|
||||
memset.obj : memset.d
|
||||
minit.obj : minit.asm
|
||||
moduleinit.obj : moduleinit.d
|
||||
monitor.obj : mars.h monitor.c
|
||||
|
@ -118,6 +126,7 @@ switch.obj : switch.d
|
|||
system.obj : system.d
|
||||
thread.obj : thread.d
|
||||
ti_Aa.obj : ti_Aa.d
|
||||
ti_Ag.obj : ti_Ag.d
|
||||
ti_C.obj : ti_C.d
|
||||
ti_char.obj : ti_char.d
|
||||
ti_int.obj : ti_int.d
|
||||
|
|
486
math.d
486
math.d
|
@ -1,55 +1,51 @@
|
|||
// math.d
|
||||
// Written by Walter Bright
|
||||
// Copyright (c) 2001 Digital Mars
|
||||
// Copyright (c) 2001-2003 Digital Mars
|
||||
// All Rights Reserved
|
||||
// www.digitalmars.com
|
||||
|
||||
module math;
|
||||
|
||||
import c.stdio;
|
||||
import intrinsic;
|
||||
|
||||
extern (C)
|
||||
{
|
||||
// BUG: these have double arguments, but we need extended
|
||||
extended acos(double);
|
||||
extended asin(double);
|
||||
extended atan(double);
|
||||
extended atan2(double, double);
|
||||
extended cos(double);
|
||||
extended sin(double);
|
||||
extended tan(double);
|
||||
extended cosh(double);
|
||||
extended sinh(double);
|
||||
extended tanh(double);
|
||||
extended exp(double);
|
||||
extended frexp(double,int *);
|
||||
extended ldexp(double,int);
|
||||
extended log(double);
|
||||
extended log10(double);
|
||||
extended modf(double, double *);
|
||||
extended pow(double, double);
|
||||
extended sqrt(double);
|
||||
extended ceil(double);
|
||||
extended floor(double);
|
||||
extended log1p(double);
|
||||
extended expm1(double);
|
||||
extended atof(char *);
|
||||
extended hypot(double, double);
|
||||
// BUG: these have double arguments, but we need real
|
||||
real acos(double);
|
||||
real asin(double);
|
||||
real atan(double);
|
||||
real atan2(double, double);
|
||||
real cosh(double);
|
||||
real sinh(double);
|
||||
real tanh(double);
|
||||
real exp(double);
|
||||
real log(double);
|
||||
real log10(double);
|
||||
real modf(double, double *);
|
||||
real pow(double, double);
|
||||
real ceil(double);
|
||||
real floor(double);
|
||||
real log1p(double);
|
||||
real expm1(double);
|
||||
real atof(char *);
|
||||
}
|
||||
|
||||
const extended PI = 3.14159265358979323846;
|
||||
const extended LOG2 = 0.30102999566398119521;
|
||||
const extended LN2 = 0.6931471805599453094172321;
|
||||
const extended LOG2T = 3.32192809488736234787;
|
||||
const extended LOG2E = 1.4426950408889634074;
|
||||
const extended E = 2.7182818284590452354;
|
||||
const extended LOG10E = 0.43429448190325182765;
|
||||
const extended LN10 = 2.30258509299404568402;
|
||||
const extended PI_2 = 1.57079632679489661923;
|
||||
const extended PI_4 = 0.78539816339744830962;
|
||||
const extended M_1_PI = 0.31830988618379067154;
|
||||
const extended M_2_PI = 0.63661977236758134308;
|
||||
const extended M_2_SQRTPI = 1.12837916709551257390;
|
||||
const extended SQRT2 = 1.41421356237309504880;
|
||||
const extended SQRT1_2 = 0.70710678118654752440;
|
||||
const real PI = 3.14159265358979323846;
|
||||
const real LOG2 = 0.30102999566398119521;
|
||||
const real LN2 = 0.6931471805599453094172321;
|
||||
const real LOG2T = 3.32192809488736234787;
|
||||
const real LOG2E = 1.4426950408889634074;
|
||||
const real E = 2.7182818284590452354;
|
||||
const real LOG10E = 0.43429448190325182765;
|
||||
const real LN10 = 2.30258509299404568402;
|
||||
const real PI_2 = 1.57079632679489661923;
|
||||
const real PI_4 = 0.78539816339744830962;
|
||||
const real M_1_PI = 0.31830988618379067154;
|
||||
const real M_2_PI = 0.63661977236758134308;
|
||||
const real M_2_SQRTPI = 1.12837916709551257390;
|
||||
const real SQRT2 = 1.41421356237309504880;
|
||||
const real SQRT1_2 = 0.70710678118654752440;
|
||||
|
||||
/*
|
||||
Octal versions:
|
||||
|
@ -70,7 +66,7 @@ const extended SQRT1_2 = 0.70710678118654752440;
|
|||
* Is number a nan?
|
||||
*/
|
||||
|
||||
int isnan(extended e)
|
||||
int isnan(real e)
|
||||
{
|
||||
ushort* pe = (ushort *)&e;
|
||||
ulong* ps = (ulong *)&e;
|
||||
|
@ -83,7 +79,7 @@ unittest
|
|||
{
|
||||
assert(isnan(float.nan));
|
||||
assert(isnan(-double.nan));
|
||||
assert(isnan(extended.nan));
|
||||
assert(isnan(real.nan));
|
||||
|
||||
assert(!isnan(53.6));
|
||||
assert(!isnan(float.infinity));
|
||||
|
@ -93,7 +89,7 @@ unittest
|
|||
* Is number finite?
|
||||
*/
|
||||
|
||||
int isfinite(extended e)
|
||||
int isfinite(real e)
|
||||
{
|
||||
ushort* pe = (ushort *)&e;
|
||||
|
||||
|
@ -111,7 +107,7 @@ unittest
|
|||
/*********************************
|
||||
* Is number normalized?
|
||||
* Need one for each format because subnormal floats might
|
||||
* be converted to normal extendeds.
|
||||
* be converted to normal reals.
|
||||
*/
|
||||
|
||||
int isnormal(float f)
|
||||
|
@ -133,7 +129,7 @@ int isnormal(double d)
|
|||
return e && e != 0x7FF00000;
|
||||
}
|
||||
|
||||
int isnormal(extended e)
|
||||
int isnormal(real e)
|
||||
{
|
||||
ushort* pe = (ushort *)&e;
|
||||
long* ps = (long *)&e;
|
||||
|
@ -145,7 +141,7 @@ unittest
|
|||
{
|
||||
float f = 3;
|
||||
double d = 500;
|
||||
extended e = 10e+48;
|
||||
real e = 10e+48;
|
||||
|
||||
assert(isnormal(f));
|
||||
assert(isnormal(d));
|
||||
|
@ -156,7 +152,7 @@ unittest
|
|||
* Is number subnormal? (Also called "denormal".)
|
||||
* Subnormals have a 0 exponent and a 0 most significant mantissa bit.
|
||||
* Need one for each format because subnormal floats might
|
||||
* be converted to normal extendeds.
|
||||
* be converted to normal reals.
|
||||
*/
|
||||
|
||||
int issubnormal(float f)
|
||||
|
@ -190,7 +186,7 @@ unittest
|
|||
assert(f != 0);
|
||||
}
|
||||
|
||||
int issubnormal(extended e)
|
||||
int issubnormal(real e)
|
||||
{
|
||||
ushort* pe = (ushort *)&e;
|
||||
long* ps = (long *)&e;
|
||||
|
@ -200,7 +196,7 @@ int issubnormal(extended e)
|
|||
|
||||
unittest
|
||||
{
|
||||
extended f;
|
||||
real f;
|
||||
|
||||
for (f = 1; !issubnormal(f); f /= 2)
|
||||
assert(f != 0);
|
||||
|
@ -210,7 +206,7 @@ unittest
|
|||
* Is number infinity?
|
||||
*/
|
||||
|
||||
int isinf(extended e)
|
||||
int isinf(real e)
|
||||
{
|
||||
ushort* pe = (ushort *)&e;
|
||||
ulong* ps = (ulong *)&e;
|
||||
|
@ -224,7 +220,7 @@ unittest
|
|||
assert(isinf(float.infinity));
|
||||
assert(!isinf(float.nan));
|
||||
assert(isinf(double.infinity));
|
||||
assert(isinf(-extended.infinity));
|
||||
assert(isinf(-real.infinity));
|
||||
|
||||
assert(isinf(-1.0 / 0.0));
|
||||
}
|
||||
|
@ -233,7 +229,7 @@ unittest
|
|||
* Get sign bit.
|
||||
*/
|
||||
|
||||
int signbit(extended e)
|
||||
int signbit(real e)
|
||||
{
|
||||
ubyte* pe = (ubyte *)&e;
|
||||
|
||||
|
@ -254,7 +250,7 @@ unittest
|
|||
* Copy sign.
|
||||
*/
|
||||
|
||||
extended copysign(extended to, extended from)
|
||||
real copysign(real to, real from)
|
||||
{
|
||||
ubyte* pto = (ubyte *)&to;
|
||||
ubyte* pfrom = (ubyte *)&from;
|
||||
|
@ -267,7 +263,7 @@ extended copysign(extended to, extended from)
|
|||
|
||||
unittest
|
||||
{
|
||||
extended e;
|
||||
real e;
|
||||
|
||||
e = copysign(21, 23.8);
|
||||
assert(e == 21);
|
||||
|
@ -281,6 +277,384 @@ unittest
|
|||
e = copysign(-21, -23.8);
|
||||
assert(e == -21);
|
||||
|
||||
e = copysign(extended.nan, -23.8);
|
||||
e = copysign(real.nan, -23.8);
|
||||
assert(isnan(e) && signbit(e));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Tangent.
|
||||
*/
|
||||
|
||||
real tan(real x)
|
||||
{
|
||||
asm
|
||||
{
|
||||
fld x[EBP] ; // load theta
|
||||
fxam ; // test for oddball values
|
||||
fstsw AX ;
|
||||
sahf ;
|
||||
jc trigerr ; // x is NAN, infinity, or empty
|
||||
// 387's can handle denormals
|
||||
SC18: fptan ;
|
||||
fstp ST(0) ; // dump X, which is always 1
|
||||
fstsw AX ;
|
||||
sahf ;
|
||||
jnp Lret ; // C2 = 1 (x is out of range)
|
||||
|
||||
// Do argument reduction to bring x into range
|
||||
fldpi ;
|
||||
fxch ;
|
||||
SC17: fprem1 ;
|
||||
fstsw AX ;
|
||||
sahf ;
|
||||
jp SC17 ;
|
||||
fstp ST(1) ; // remove pi from stack
|
||||
jmp SC18 ;
|
||||
}
|
||||
|
||||
trigerr:
|
||||
return real.nan;
|
||||
|
||||
Lret:
|
||||
;
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
static real vals[][2] = // angle,tan
|
||||
[
|
||||
[ 0, 0],
|
||||
[ .5, .5463024898],
|
||||
[ 1, 1.557407725],
|
||||
[ 1.5, 14.10141995],
|
||||
[ 2, -2.185039863],
|
||||
[ 2.5,-.7470222972],
|
||||
[ 3, -.1425465431],
|
||||
[ 3.5, .3745856402],
|
||||
[ 4, 1.157821282],
|
||||
[ 4.5, 4.637332055],
|
||||
[ 5, -3.380515006],
|
||||
[ 5.5,-.9955840522],
|
||||
[ 6, -.2910061914],
|
||||
[ 6.5, .2202772003],
|
||||
[ 10, .6483608275],
|
||||
|
||||
// special angles
|
||||
[ PI_4, 1],
|
||||
//[ PI_2, real.infinity],
|
||||
[ 3*PI_4, -1],
|
||||
[ PI, 0],
|
||||
[ 5*PI_4, 1],
|
||||
//[ 3*PI_2, -real.infinity],
|
||||
[ 7*PI_4, -1],
|
||||
[ 2*PI, 0],
|
||||
|
||||
// overflow
|
||||
[ real.infinity, real.nan],
|
||||
[ real.nan, real.nan],
|
||||
[ 1e+100, real.nan],
|
||||
];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < vals.length; i++)
|
||||
{
|
||||
real x = vals[i][0];
|
||||
real r = vals[i][1];
|
||||
real t = tan(x);
|
||||
|
||||
//printf("tan(%Lg) = %Lg, should be %Lg\n", x, t, r);
|
||||
assert(mfeq(r, t, .0000001));
|
||||
|
||||
x = -x;
|
||||
r = -r;
|
||||
t = tan(x);
|
||||
//printf("tan(%Lg) = %Lg, should be %Lg\n", x, t, r);
|
||||
assert(mfeq(r, t, .0000001));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* hypotenuese.
|
||||
* This is based on code from:
|
||||
* Cephes Math Library Release 2.1: January, 1989
|
||||
* Copyright 1984, 1987, 1989 by Stephen L. Moshier
|
||||
* Direct inquiries to 30 Frost Street, Cambridge, MA 02140
|
||||
*/
|
||||
|
||||
real hypot(real zre, real zim)
|
||||
{
|
||||
|
||||
const int PRECL = 32;
|
||||
const int MAXEXPL = real.max_exp; //16384;
|
||||
const int MINEXPL = real.min_exp; //-16384;
|
||||
|
||||
real x, y, b, re, im;
|
||||
int ex, ey, e;
|
||||
|
||||
// Note, hypot(INFINITY,NAN) = INFINITY.
|
||||
if (isinf(zre) || isinf(zim))
|
||||
return real.infinity;
|
||||
|
||||
if (isnan(zre))
|
||||
return zre;
|
||||
if (isnan(zim))
|
||||
return zim;
|
||||
|
||||
re = fabs(zre);
|
||||
im = fabs(zim);
|
||||
|
||||
if (re == 0.0)
|
||||
return im;
|
||||
if (im == 0.0)
|
||||
return re;
|
||||
|
||||
// Get the exponents of the numbers
|
||||
x = frexp(re, ex);
|
||||
y = frexp(im, ey);
|
||||
|
||||
// Check if one number is tiny compared to the other
|
||||
e = ex - ey;
|
||||
if (e > PRECL)
|
||||
return re;
|
||||
if (e < -PRECL)
|
||||
return im;
|
||||
|
||||
// Find approximate exponent e of the geometric mean.
|
||||
e = (ex + ey) >> 1;
|
||||
|
||||
// Rescale so mean is about 1
|
||||
x = ldexp(re, -e);
|
||||
y = ldexp(im, -e);
|
||||
|
||||
// Hypotenuse of the right triangle
|
||||
b = sqrt(x * x + y * y);
|
||||
|
||||
// Compute the exponent of the answer.
|
||||
y = frexp(b, ey);
|
||||
ey = e + ey;
|
||||
|
||||
// Check it for overflow and underflow.
|
||||
if (ey > MAXEXPL + 2)
|
||||
{
|
||||
//return __matherr(_OVERFLOW, INFINITY, x, y, "hypotl");
|
||||
return real.infinity;
|
||||
}
|
||||
if (ey < MINEXPL - 2)
|
||||
return 0.0;
|
||||
|
||||
// Undo the scaling
|
||||
b = ldexp(b, e);
|
||||
return b;
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
static real vals[][3] = // x,y,hypot
|
||||
[
|
||||
[ 0, 0, 0],
|
||||
[ 0, -0, 0],
|
||||
[ 3, 4, 5],
|
||||
[ -300, -400, 500],
|
||||
[ real.min, real.min, 4.75473e-4932L],
|
||||
[ real.max/2, real.max/2, 0x1.6a09e667f3bcc908p+16383L /*8.41267e+4931L*/],
|
||||
[ real.infinity, real.nan, real.infinity],
|
||||
[ real.nan, real.nan, real.nan],
|
||||
];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < vals.length; i++)
|
||||
{
|
||||
real x = vals[i][0];
|
||||
real y = vals[i][1];
|
||||
real z = vals[i][2];
|
||||
real h = hypot(x, y);
|
||||
|
||||
//printf("hypot(%Lg, %Lg) = %Lg, should be %Lg\n", x, y, h, z);
|
||||
//if (!mfeq(z, h, .0000001))
|
||||
//printf("%La\n", h);
|
||||
assert(mfeq(z, h, .0000001));
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* Returns:
|
||||
* x such that value=x*2**n, .5 <= |x| < 1.0
|
||||
* x has same sign as value.
|
||||
* *eptr = n
|
||||
*
|
||||
* Special cases:
|
||||
* value x *eptr
|
||||
* +-0.0 +-0.0 0
|
||||
* +-inf +-inf int.max/int.min
|
||||
* +-NaN +-NaN int.min
|
||||
* +-NaNs +-NaN int.min
|
||||
*/
|
||||
|
||||
|
||||
real frexp(real value, out int eptr)
|
||||
{
|
||||
ushort* vu = (ushort*)&value;
|
||||
long* vl = (long*)&value;
|
||||
uint exp;
|
||||
|
||||
// If exponent is non-zero
|
||||
exp = vu[4] & 0x7FFF;
|
||||
if (exp)
|
||||
{
|
||||
if (exp == 0x7FFF)
|
||||
{ // infinity or NaN
|
||||
if (*vl & 0x7FFFFFFFFFFFFFFF) // if NaN
|
||||
{ *vl |= 0xC000000000000000; // convert NANS to NANQ
|
||||
eptr = int.min;
|
||||
}
|
||||
else if (vu[4] & 0x8000)
|
||||
{ // negative infinity
|
||||
eptr = int.min;
|
||||
}
|
||||
else
|
||||
{ // positive infinity
|
||||
eptr = int.max;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
eptr = exp - 0x3FFE;
|
||||
vu[4] = (0x8000 & vu[4]) | 0x3FFE;
|
||||
}
|
||||
}
|
||||
else if (!*vl)
|
||||
{
|
||||
// value is +-0.0
|
||||
eptr = 0;
|
||||
}
|
||||
else
|
||||
{ // denormal
|
||||
int i = -0x3FFD;
|
||||
|
||||
do
|
||||
{
|
||||
i--;
|
||||
*vl <<= 1;
|
||||
} while (*vl > 0);
|
||||
eptr = i;
|
||||
vu[4] = (0x8000 & vu[4]) | 0x3FFE;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
unittest
|
||||
{
|
||||
static real vals[][3] = // x,frexp,eptr
|
||||
[
|
||||
[0.0, 0.0, 0],
|
||||
[-0.0, -0.0, 0],
|
||||
[1.0, .5, 1],
|
||||
[-1.0, -.5, 1],
|
||||
[2.0, .5, 2],
|
||||
[155.67e20, 0x1.A5F1C2EB3FE4Fp-1, 74], // normal
|
||||
[1.0e-320, 0x1.FAp-1, -1063],
|
||||
[real.min, .5, -16381],
|
||||
[real.min/2.0L, .5, -16382], // denormal
|
||||
|
||||
[real.infinity,real.infinity,int.max],
|
||||
[-real.infinity,-real.infinity,int.min],
|
||||
[real.nan,real.nan,int.min],
|
||||
[-real.nan,-real.nan,int.min],
|
||||
|
||||
// Don't really support signalling nan's in D
|
||||
//[real.nans,real.nan,int.min],
|
||||
//[-real.nans,-real.nan,int.min],
|
||||
];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < vals.length; i++)
|
||||
{
|
||||
real x = vals[i][0];
|
||||
real e = vals[i][1];
|
||||
int exp = (int)vals[i][2];
|
||||
int eptr;
|
||||
real v = frexp(x, eptr);
|
||||
|
||||
//printf("frexp(%Lg) = %Lg, should be %Lg, eptr = %d, should be %d\n", x, v, e, eptr, exp);
|
||||
assert(mfeq(e, v, .0000001));
|
||||
assert(exp == eptr);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* Fast integral powers.
|
||||
*/
|
||||
|
||||
real pow(real x, uint n)
|
||||
{
|
||||
real p;
|
||||
|
||||
switch (n)
|
||||
{
|
||||
case 0:
|
||||
p = 1.0;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
p = x;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
p = x * x;
|
||||
break;
|
||||
|
||||
default:
|
||||
p = 1.0;
|
||||
while (1)
|
||||
{
|
||||
if (n & 1)
|
||||
p *= x;
|
||||
n >>= 1;
|
||||
if (!n)
|
||||
break;
|
||||
x *= x;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
real pow(real x, int n)
|
||||
{
|
||||
if (n < 0)
|
||||
return pow((double)x, cast(double)n);
|
||||
else
|
||||
return pow(x, cast(uint)n);
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
real x = 46;
|
||||
|
||||
assert(pow(x,0) == 1.0);
|
||||
assert(pow(x,1) == x);
|
||||
assert(pow(x,2) == x * x);
|
||||
assert(pow(x,3) == x * x * x);
|
||||
assert(pow(x,8) == (x * x) * (x * x) * (x * x) * (x * x));
|
||||
}
|
||||
|
||||
/****************************************
|
||||
* Simple function to compare two floating point values
|
||||
* to a specified precision.
|
||||
* Returns:
|
||||
* 1 match
|
||||
* 0 nomatch
|
||||
*/
|
||||
|
||||
private int mfeq(real x, real y, real precision)
|
||||
{
|
||||
if (x == y)
|
||||
return 1;
|
||||
if (isnan(x))
|
||||
return isnan(y);
|
||||
if (isnan(y))
|
||||
return 0;
|
||||
return fabs(x - y) <= precision;
|
||||
}
|
||||
|
|
201
math2.d
201
math2.d
|
@ -21,12 +21,12 @@ private import math, string, c.stdlib, c.stdio;
|
|||
* compare floats with given precision
|
||||
*/
|
||||
|
||||
bit feq(extended a, extended b)
|
||||
bit feq(real a, real b)
|
||||
{
|
||||
return feq(a, b, 0.000001);
|
||||
}
|
||||
|
||||
bit feq(extended a, extended b, extended eps)
|
||||
bit feq(real a, real b, real eps)
|
||||
{
|
||||
return abs(a - b) <= eps;
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ long abs(long n)
|
|||
return n > 0 ? n : -n;
|
||||
}
|
||||
|
||||
extended abs(extended n)
|
||||
real abs(real n)
|
||||
{
|
||||
// just let the compiler handle it
|
||||
return intrinsic.fabs(n);
|
||||
|
@ -65,7 +65,7 @@ long sqr(long n)
|
|||
return n * n;
|
||||
}
|
||||
|
||||
extended sqr(extended n)
|
||||
real sqr(real n)
|
||||
{
|
||||
return n * n;
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ private ushort fp_cw_chop = 7999;
|
|||
* Integer part
|
||||
*/
|
||||
|
||||
extended trunc(extended n)
|
||||
real trunc(real n)
|
||||
{
|
||||
ushort cw;
|
||||
asm
|
||||
|
@ -104,7 +104,7 @@ unittest
|
|||
* Fractional part
|
||||
*/
|
||||
|
||||
extended frac(extended n)
|
||||
real frac(real n)
|
||||
{
|
||||
return n - trunc(n);
|
||||
}
|
||||
|
@ -119,12 +119,12 @@ unittest
|
|||
* Polynomial of X
|
||||
*/
|
||||
|
||||
extended poly(extended x, extended[] coefficients)
|
||||
real poly(real x, real[] coefficients)
|
||||
{
|
||||
debug (math2) printf("poly(), coefficients.length = %d\n", coefficients.length);
|
||||
if (!coefficients.length)
|
||||
return 0;
|
||||
extended result = coefficients[coefficients.length - 1];
|
||||
real result = coefficients[coefficients.length - 1];
|
||||
for (int i = coefficients.length - 2; i >= 0; i--)
|
||||
result = result * x + coefficients[i];
|
||||
return result;
|
||||
|
@ -133,8 +133,8 @@ extended poly(extended x, extended[] coefficients)
|
|||
unittest
|
||||
{
|
||||
debug (math2) printf("unittest.poly()\n");
|
||||
static extended[4] k = [ 4, 3, 2, 1 ];
|
||||
assert(feq(poly(2, k), cast(extended) 8 * 1 + 4 * 2 + 2 * 3 + 4));
|
||||
static real[4] k = [ 4, 3, 2, 1 ];
|
||||
assert(feq(poly(2, k), cast(real) 8 * 1 + 4 * 2 + 2 * 3 + 4));
|
||||
}
|
||||
|
||||
/*********************************
|
||||
|
@ -165,7 +165,7 @@ unittest
|
|||
assert(sign(-666L) == -1);
|
||||
}
|
||||
|
||||
int sign(extended n)
|
||||
int sign(real n)
|
||||
{
|
||||
return (n > 0 ? +1 : (n < 0 ? -1 : 0));
|
||||
}
|
||||
|
@ -181,62 +181,62 @@ unittest
|
|||
* Cycles <-> radians <-> grads <-> degrees conversions
|
||||
*/
|
||||
|
||||
extended cycle2deg(extended c)
|
||||
real cycle2deg(real c)
|
||||
{
|
||||
return c * 360;
|
||||
}
|
||||
|
||||
extended cycle2rad(extended c)
|
||||
real cycle2rad(real c)
|
||||
{
|
||||
return c * PI * 2;
|
||||
}
|
||||
|
||||
extended cycle2grad(extended c)
|
||||
real cycle2grad(real c)
|
||||
{
|
||||
return c * 400;
|
||||
}
|
||||
|
||||
extended deg2cycle(extended d)
|
||||
real deg2cycle(real d)
|
||||
{
|
||||
return d / 360;
|
||||
}
|
||||
|
||||
extended deg2rad(extended d)
|
||||
real deg2rad(real d)
|
||||
{
|
||||
return d / 180 * PI;
|
||||
}
|
||||
|
||||
extended deg2grad(extended d)
|
||||
real deg2grad(real d)
|
||||
{
|
||||
return d / 90 * 100;
|
||||
}
|
||||
|
||||
extended rad2deg(extended r)
|
||||
real rad2deg(real r)
|
||||
{
|
||||
return r / PI * 180;
|
||||
}
|
||||
|
||||
extended rad2cycle(extended r)
|
||||
real rad2cycle(real r)
|
||||
{
|
||||
return r / (PI * 2);
|
||||
}
|
||||
|
||||
extended rad2grad(extended r)
|
||||
real rad2grad(real r)
|
||||
{
|
||||
return r / PI * 200;
|
||||
}
|
||||
|
||||
extended grad2deg(extended g)
|
||||
real grad2deg(real g)
|
||||
{
|
||||
return g / 100 * 90;
|
||||
}
|
||||
|
||||
extended grad2cycle(extended g)
|
||||
real grad2cycle(real g)
|
||||
{
|
||||
return g / 400;
|
||||
}
|
||||
|
||||
extended grad2rad(extended g)
|
||||
real grad2rad(real g)
|
||||
{
|
||||
return g / 200 * PI;
|
||||
}
|
||||
|
@ -261,9 +261,9 @@ unittest
|
|||
* Arithmetic average of values
|
||||
*/
|
||||
|
||||
extended avg(extended[] n)
|
||||
real avg(real[] n)
|
||||
{
|
||||
extended result = 0;
|
||||
real result = 0;
|
||||
for (uint i = 0; i < n.length; i++)
|
||||
result += n[i];
|
||||
return result / n.length;
|
||||
|
@ -271,7 +271,7 @@ extended avg(extended[] n)
|
|||
|
||||
unittest
|
||||
{
|
||||
static extended[4] n = [ 1, 2, 4, 5 ];
|
||||
static real[4] n = [ 1, 2, 4, 5 ];
|
||||
assert(feq(avg(n), 3));
|
||||
}
|
||||
|
||||
|
@ -307,9 +307,9 @@ unittest
|
|||
assert(sum(n) == 6);
|
||||
}
|
||||
|
||||
extended sum(extended[] n)
|
||||
real sum(real[] n)
|
||||
{
|
||||
extended result = 0;
|
||||
real result = 0;
|
||||
for (uint i = 0; i < n.length; i++)
|
||||
result += n[i];
|
||||
return result;
|
||||
|
@ -317,7 +317,7 @@ extended sum(extended[] n)
|
|||
|
||||
unittest
|
||||
{
|
||||
static extended[3] n = [ 1, 2, 3 ];
|
||||
static real[3] n = [ 1, 2, 3 ];
|
||||
assert(feq(sum(n), 6));
|
||||
}
|
||||
|
||||
|
@ -355,9 +355,9 @@ unittest
|
|||
assert(min(n) == -1);
|
||||
}
|
||||
|
||||
extended min(extended[] n)
|
||||
real min(real[] n)
|
||||
{
|
||||
extended result = extended.max;
|
||||
real result = real.max;
|
||||
for (uint i = 0; i < n.length; i++)
|
||||
{
|
||||
if (n[i] < result)
|
||||
|
@ -368,7 +368,7 @@ extended min(extended[] n)
|
|||
|
||||
unittest
|
||||
{
|
||||
static extended[3] n = [ 2.0, -1.0, 0.0 ];
|
||||
static real[3] n = [ 2.0, -1.0, 0.0 ];
|
||||
assert(feq(min(n), -1));
|
||||
}
|
||||
|
||||
|
@ -392,7 +392,7 @@ unittest
|
|||
assert(min(1L, 2L) == 1);
|
||||
}
|
||||
|
||||
extended min(extended a, extended b)
|
||||
real min(real a, real b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
@ -436,9 +436,9 @@ unittest
|
|||
assert(max(n) == 2);
|
||||
}
|
||||
|
||||
extended max(extended[] n)
|
||||
real max(real[] n)
|
||||
{
|
||||
extended result = extended.min;
|
||||
real result = real.min;
|
||||
for (uint i = 0; i < n.length; i++)
|
||||
if (n[i] > result)
|
||||
result = n[i];
|
||||
|
@ -447,7 +447,7 @@ extended max(extended[] n)
|
|||
|
||||
unittest
|
||||
{
|
||||
static extended[3] n = [ 0.0, 2.0, -1.0 ];
|
||||
static real[3] n = [ 0.0, 2.0, -1.0 ];
|
||||
assert(feq(max(n), 2));
|
||||
}
|
||||
|
||||
|
@ -471,7 +471,7 @@ unittest
|
|||
assert(max(1L, 2L) == 2);
|
||||
}
|
||||
|
||||
extended max(extended a, extended b)
|
||||
real max(real a, real b)
|
||||
{
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
@ -485,7 +485,7 @@ unittest
|
|||
* Arccosine
|
||||
*/
|
||||
|
||||
extended acos(extended x)
|
||||
real acos(real x)
|
||||
{
|
||||
return atan2(intrinsic.sqrt(1 - x * x), x);
|
||||
}
|
||||
|
@ -500,7 +500,7 @@ unittest
|
|||
*/
|
||||
|
||||
|
||||
extended asin(extended x)
|
||||
real asin(real x)
|
||||
{
|
||||
return atan2(x, intrinsic.sqrt(1 - x * x));
|
||||
}
|
||||
|
@ -515,7 +515,7 @@ unittest
|
|||
* Arctangent
|
||||
*/
|
||||
|
||||
extended atan(extended x)
|
||||
real atan(real x)
|
||||
{
|
||||
asm
|
||||
{
|
||||
|
@ -536,7 +536,7 @@ unittest
|
|||
* Arctangent y/x
|
||||
*/
|
||||
|
||||
extended atan2(extended y, extended x)
|
||||
real atan2(real y, real x)
|
||||
{
|
||||
asm
|
||||
{
|
||||
|
@ -557,7 +557,7 @@ unittest
|
|||
* Arccotangent
|
||||
*/
|
||||
|
||||
extended acot(extended x)
|
||||
real acot(real x)
|
||||
{
|
||||
return tan(1.0 / x);
|
||||
}
|
||||
|
@ -571,7 +571,7 @@ unittest
|
|||
* Arcsecant
|
||||
*/
|
||||
|
||||
extended asec(extended x)
|
||||
real asec(real x)
|
||||
{
|
||||
return intrinsic.cos(1.0 / x);
|
||||
}
|
||||
|
@ -581,7 +581,7 @@ extended asec(extended x)
|
|||
* Arccosecant
|
||||
*/
|
||||
|
||||
extended acosec(extended x)
|
||||
real acosec(real x)
|
||||
{
|
||||
return intrinsic.sin(1.0 / x);
|
||||
}
|
||||
|
@ -590,7 +590,8 @@ extended acosec(extended x)
|
|||
* Tangent
|
||||
*/
|
||||
|
||||
extended tan(extended x)
|
||||
/+
|
||||
real tan(real x)
|
||||
{
|
||||
asm
|
||||
{
|
||||
|
@ -605,12 +606,13 @@ unittest
|
|||
{
|
||||
assert(feq(tan(PI / 3), intrinsic.sqrt(3)));
|
||||
}
|
||||
+/
|
||||
|
||||
/*************************************
|
||||
* Cotangent
|
||||
*/
|
||||
|
||||
extended cot(extended x)
|
||||
real cot(real x)
|
||||
{
|
||||
asm
|
||||
{
|
||||
|
@ -630,7 +632,7 @@ unittest
|
|||
* Secant
|
||||
*/
|
||||
|
||||
extended sec(extended x)
|
||||
real sec(real x)
|
||||
{
|
||||
asm
|
||||
{
|
||||
|
@ -647,7 +649,7 @@ extended sec(extended x)
|
|||
* Cosecant
|
||||
*/
|
||||
|
||||
extended cosec(extended x)
|
||||
real cosec(real x)
|
||||
{
|
||||
asm
|
||||
{
|
||||
|
@ -662,8 +664,8 @@ extended cosec(extended x)
|
|||
/*************************************
|
||||
* Hypotenuse of right triangle
|
||||
*/
|
||||
|
||||
extended hypot(extended x, extended y)
|
||||
/+
|
||||
real hypot(real x, real y)
|
||||
{
|
||||
asm
|
||||
{
|
||||
|
@ -697,12 +699,13 @@ unittest
|
|||
{
|
||||
assert(feq(hypot(3, 4), 5));
|
||||
}
|
||||
+/
|
||||
|
||||
/*********************************************
|
||||
* Extract mantissa and exponent from float
|
||||
*/
|
||||
|
||||
extended frexp(extended x, out int exponent)
|
||||
real frexp(real x, out int exponent)
|
||||
{
|
||||
asm
|
||||
{
|
||||
|
@ -731,7 +734,7 @@ done:
|
|||
unittest
|
||||
{
|
||||
int exponent;
|
||||
extended mantissa = frexp(123.456, exponent);
|
||||
real mantissa = frexp(123.456, exponent);
|
||||
assert(feq(mantissa * pow(2, exponent), 123.456));
|
||||
}
|
||||
|
||||
|
@ -739,7 +742,7 @@ unittest
|
|||
* Make a float out of mantissa and exponent
|
||||
*/
|
||||
|
||||
extended ldexp(extended x, int exponent)
|
||||
real ldexp(real x, int exponent)
|
||||
{
|
||||
asm
|
||||
{
|
||||
|
@ -760,7 +763,7 @@ unittest
|
|||
* Round to nearest int > x
|
||||
*/
|
||||
|
||||
long ceil(extended x)
|
||||
long ceil(real x)
|
||||
{
|
||||
return frac(x) > 0 ? trunc(x) + 1 : trunc(x);
|
||||
}
|
||||
|
@ -775,7 +778,7 @@ unittest
|
|||
* Round to nearest int < x
|
||||
*/
|
||||
|
||||
long floor(extended x)
|
||||
long floor(real x)
|
||||
{
|
||||
return frac(x) < 0 ? trunc(x) - 1 : trunc(x);
|
||||
}
|
||||
|
@ -790,7 +793,7 @@ unittest
|
|||
* Base 10 logarithm
|
||||
*/
|
||||
|
||||
extended log10(extended x)
|
||||
real log10(real x)
|
||||
{
|
||||
asm
|
||||
{
|
||||
|
@ -810,7 +813,7 @@ unittest
|
|||
* Base 2 logarithm
|
||||
*/
|
||||
|
||||
extended log2(extended x)
|
||||
real log2(real x)
|
||||
{
|
||||
asm
|
||||
{
|
||||
|
@ -830,7 +833,7 @@ unittest
|
|||
* Natural logarithm
|
||||
*/
|
||||
|
||||
extended log(extended x)
|
||||
real log(real x)
|
||||
{
|
||||
asm
|
||||
{
|
||||
|
@ -850,7 +853,7 @@ unittest
|
|||
* Natural logarithm of (x + 1)
|
||||
*/
|
||||
|
||||
extended log1p(extended x)
|
||||
real log1p(real x)
|
||||
{
|
||||
asm
|
||||
{
|
||||
|
@ -870,7 +873,7 @@ unittest
|
|||
* Logarithm
|
||||
*/
|
||||
|
||||
extended log(extended x, extended base)
|
||||
real log(real x, real base)
|
||||
{
|
||||
asm
|
||||
{
|
||||
|
@ -894,7 +897,7 @@ unittest
|
|||
* (base + 1) logarithm of x
|
||||
*/
|
||||
|
||||
extended log1p(extended x, extended base)
|
||||
real log1p(real x, real base)
|
||||
{
|
||||
asm
|
||||
{
|
||||
|
@ -918,7 +921,7 @@ unittest
|
|||
* Exponent
|
||||
*/
|
||||
|
||||
extended exp(extended x)
|
||||
real exp(real x)
|
||||
{
|
||||
asm
|
||||
{
|
||||
|
@ -947,7 +950,7 @@ unittest
|
|||
* Base to exponent
|
||||
*/
|
||||
|
||||
extended pow(extended base, extended exponent)
|
||||
real pow(real base, real exponent)
|
||||
{
|
||||
return exp(exponent * log(base));
|
||||
}
|
||||
|
@ -961,9 +964,9 @@ unittest
|
|||
* Hyperbolic cosine
|
||||
*/
|
||||
|
||||
extended cosh(extended x)
|
||||
real cosh(real x)
|
||||
{
|
||||
extended z = exp(x) / 2;
|
||||
real z = exp(x) / 2;
|
||||
return z + 0.25 / z;
|
||||
}
|
||||
|
||||
|
@ -976,9 +979,9 @@ unittest
|
|||
* Hyperbolic sine
|
||||
*/
|
||||
|
||||
extended sinh(extended x)
|
||||
real sinh(real x)
|
||||
{
|
||||
extended z = exp(x) / 2;
|
||||
real z = exp(x) / 2;
|
||||
return z - 0.25 / z;
|
||||
}
|
||||
|
||||
|
@ -991,9 +994,9 @@ unittest
|
|||
* Hyperbolic tangent
|
||||
*/
|
||||
|
||||
private extended tanh_domain;
|
||||
private real tanh_domain;
|
||||
|
||||
extended tanh(extended x)
|
||||
real tanh(real x)
|
||||
{
|
||||
if (x > tanh_domain)
|
||||
return 1;
|
||||
|
@ -1001,7 +1004,7 @@ extended tanh(extended x)
|
|||
return -1;
|
||||
else
|
||||
{
|
||||
extended z = sqr(exp(x));
|
||||
real z = sqr(exp(x));
|
||||
return (z - 1) / (z + 1);
|
||||
}
|
||||
}
|
||||
|
@ -1015,7 +1018,7 @@ unittest
|
|||
* Hyperbolic cotangent
|
||||
*/
|
||||
|
||||
extended coth(extended x)
|
||||
real coth(real x)
|
||||
{
|
||||
return 1 / tanh(x);
|
||||
}
|
||||
|
@ -1029,7 +1032,7 @@ unittest
|
|||
* Hyperbolic secant
|
||||
*/
|
||||
|
||||
extended sech(extended x)
|
||||
real sech(real x)
|
||||
{
|
||||
return 1 / cosh(x);
|
||||
}
|
||||
|
@ -1038,7 +1041,7 @@ extended sech(extended x)
|
|||
* Hyperbolic cosecant
|
||||
*/
|
||||
|
||||
extended cosech(extended x)
|
||||
real cosech(real x)
|
||||
{
|
||||
return 1 / sinh(x);
|
||||
}
|
||||
|
@ -1047,7 +1050,7 @@ extended cosech(extended x)
|
|||
* Hyperbolic arccosine
|
||||
*/
|
||||
|
||||
extended acosh(extended x)
|
||||
real acosh(real x)
|
||||
{
|
||||
if (x <= 1)
|
||||
return 0;
|
||||
|
@ -1067,7 +1070,7 @@ unittest
|
|||
* Hyperbolic arcsine
|
||||
*/
|
||||
|
||||
extended asinh(extended x)
|
||||
real asinh(real x)
|
||||
{
|
||||
if (!x)
|
||||
return 0;
|
||||
|
@ -1077,7 +1080,7 @@ extended asinh(extended x)
|
|||
return -log(2) - log(1.0e10);
|
||||
else
|
||||
{
|
||||
extended z = x * x;
|
||||
real z = x * x;
|
||||
return x > 0 ?
|
||||
log1p(x + z / (1.0 + intrinsic.sqrt(1.0 + z))) :
|
||||
-log1p(-x + z / (1.0 + intrinsic.sqrt(1.0 + z)));
|
||||
|
@ -1094,16 +1097,16 @@ unittest
|
|||
* Hyperbolic arctangent
|
||||
*/
|
||||
|
||||
extended atanh(extended x)
|
||||
real atanh(real x)
|
||||
{
|
||||
if (!x)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
if (x >= 1)
|
||||
return extended.max;
|
||||
return real.max;
|
||||
else if (x <= -1)
|
||||
return -extended.max;
|
||||
return -real.max;
|
||||
else
|
||||
return x > 0 ?
|
||||
0.5 * log1p((2.0 * x) / (1.0 - x)) :
|
||||
|
@ -1121,7 +1124,7 @@ unittest
|
|||
* Hyperbolic arccotangent
|
||||
*/
|
||||
|
||||
extended acoth(extended x)
|
||||
real acoth(real x)
|
||||
{
|
||||
return 1 / acot(x);
|
||||
}
|
||||
|
@ -1135,7 +1138,7 @@ unittest
|
|||
* Hyperbolic arcsecant
|
||||
*/
|
||||
|
||||
extended asech(extended x)
|
||||
real asech(real x)
|
||||
{
|
||||
return 1 / asec(x);
|
||||
}
|
||||
|
@ -1144,7 +1147,7 @@ extended asech(extended x)
|
|||
* Hyperbolic arccosecant
|
||||
*/
|
||||
|
||||
extended acosech(extended x)
|
||||
real acosech(real x)
|
||||
{
|
||||
return 1 / acosec(x);
|
||||
}
|
||||
|
@ -1153,15 +1156,15 @@ extended acosech(extended x)
|
|||
* Convert string to float
|
||||
*/
|
||||
|
||||
extended atof(char[] s)
|
||||
real atof(char[] s)
|
||||
{
|
||||
if (!s.length)
|
||||
return extended.nan;
|
||||
extended result = 0;
|
||||
return real.nan;
|
||||
real result = 0;
|
||||
uint i = 0;
|
||||
while (s[i] == "\t" || s[i] == " ")
|
||||
if (++i >= s.length)
|
||||
return extended.nan;
|
||||
return real.nan;
|
||||
bit neg = false;
|
||||
if (s[i] == "-")
|
||||
{
|
||||
|
@ -1171,7 +1174,7 @@ extended atof(char[] s)
|
|||
else if (s[i] == "+")
|
||||
i++;
|
||||
if (i >= s.length)
|
||||
return extended.nan;
|
||||
return real.nan;
|
||||
bit hex;
|
||||
if (s[s.length - 1] == "h")
|
||||
{
|
||||
|
@ -1183,7 +1186,7 @@ extended atof(char[] s)
|
|||
hex = true;
|
||||
i += 2;
|
||||
if (i >= s.length)
|
||||
return extended.nan;
|
||||
return real.nan;
|
||||
}
|
||||
else
|
||||
hex = false;
|
||||
|
@ -1210,10 +1213,10 @@ extended atof(char[] s)
|
|||
else if (s[i] >= "A" && s[i] <= "F")
|
||||
result += s[i] - "A" + 10;
|
||||
else
|
||||
return extended.nan;
|
||||
return real.nan;
|
||||
}
|
||||
else
|
||||
return extended.nan;
|
||||
return real.nan;
|
||||
if (++i >= s.length)
|
||||
goto done;
|
||||
}
|
||||
|
@ -1246,10 +1249,10 @@ extended atof(char[] s)
|
|||
else if (s[i] >= "A" && s[i] <= "F")
|
||||
result += s[i] - "A" + 10;
|
||||
else
|
||||
return extended.nan;
|
||||
return real.nan;
|
||||
}
|
||||
else
|
||||
return extended.nan;
|
||||
return real.nan;
|
||||
if (++i >= s.length)
|
||||
{
|
||||
result /= k;
|
||||
|
@ -1259,7 +1262,7 @@ extended atof(char[] s)
|
|||
result /= k;
|
||||
}
|
||||
if (++i >= s.length)
|
||||
return extended.nan;
|
||||
return real.nan;
|
||||
bit eneg = false;
|
||||
if (s[i] == "-")
|
||||
{
|
||||
|
@ -1269,7 +1272,7 @@ extended atof(char[] s)
|
|||
else if (s[i] == "+")
|
||||
i++;
|
||||
if (i >= s.length)
|
||||
return extended.nan;
|
||||
return real.nan;
|
||||
int e = 0;
|
||||
while (i < s.length)
|
||||
{
|
||||
|
@ -1277,7 +1280,7 @@ extended atof(char[] s)
|
|||
if (s[i] >= "0" && s[i] <= "9")
|
||||
e += s[i] - "0";
|
||||
else
|
||||
return extended.nan;
|
||||
return real.nan;
|
||||
i++;
|
||||
}
|
||||
if (eneg)
|
||||
|
@ -1300,8 +1303,8 @@ unittest
|
|||
assert(feq(atof(".456"), .456));
|
||||
assert(feq(atof("123.456"), 123.456));
|
||||
assert(feq(atof("1.23456E+2"), 123.456));
|
||||
assert(feq(atof("1A2h"), 1A2h));
|
||||
assert(feq(atof("1a2h"), 1a2h));
|
||||
//assert(feq(atof("1A2h"), 1A2h));
|
||||
//assert(feq(atof("1a2h"), 1a2h));
|
||||
assert(feq(atof("0x1A2"), 0x1A2));
|
||||
assert(feq(atof("0x1a2p2"), 0x1a2p2));
|
||||
assert(feq(atof("0x1a2p+2"), 0x1a2p+2));
|
||||
|
@ -1314,7 +1317,7 @@ unittest
|
|||
* Convert float to string
|
||||
*/
|
||||
|
||||
char[] toString(extended x)
|
||||
char[] toString(real x)
|
||||
{
|
||||
char[1024] buffer;
|
||||
char* p = buffer;
|
||||
|
@ -1355,5 +1358,5 @@ unittest
|
|||
|
||||
static this()
|
||||
{
|
||||
tanh_domain = log(extended.max) / 2;
|
||||
tanh_domain = log(real.max) / 2;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
|
||||
#include <string.h>
|
||||
extern (C)
|
||||
{
|
||||
// Functions from the C library.
|
||||
void *memcpy(void *, void *, uint);
|
||||
}
|
||||
|
||||
extern (C):
|
||||
|
||||
short *_memset16(short *p, short value, int count)
|
||||
{
|
||||
|
@ -12,6 +18,21 @@ short *_memset16(short *p, short value, int count)
|
|||
}
|
||||
|
||||
int *_memset32(int *p, int value, int count)
|
||||
{
|
||||
version (X86)
|
||||
{
|
||||
asm
|
||||
{
|
||||
mov EDI,p ;
|
||||
mov EAX,value ;
|
||||
mov ECX,count ;
|
||||
mov EDX,EDI ;
|
||||
rep ;
|
||||
stosd ;
|
||||
mov EAX,EDX ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int *pstart = p;
|
||||
int *ptop;
|
||||
|
@ -20,21 +41,22 @@ int *_memset32(int *p, int value, int count)
|
|||
*p = value;
|
||||
return pstart;
|
||||
}
|
||||
}
|
||||
|
||||
long long *_memset64(long long *p, long long value, int count)
|
||||
long *_memset64(long *p, long value, int count)
|
||||
{
|
||||
long long *pstart = p;
|
||||
long long *ptop;
|
||||
long *pstart = p;
|
||||
long *ptop;
|
||||
|
||||
for (ptop = &p[count]; p < ptop; p++)
|
||||
*p = value;
|
||||
return pstart;
|
||||
}
|
||||
|
||||
long double *_memset80(long double *p, long double value, int count)
|
||||
real *_memset80(real *p, real value, int count)
|
||||
{
|
||||
long double *pstart = p;
|
||||
long double *ptop;
|
||||
real *pstart = p;
|
||||
real *ptop;
|
||||
|
||||
for (ptop = &p[count]; p < ptop; p++)
|
||||
*p = value;
|
|
@ -121,11 +121,11 @@ class OutBuffer
|
|||
offset += double.size;
|
||||
}
|
||||
|
||||
void write(extended f)
|
||||
void write(real f)
|
||||
{
|
||||
reserve(extended.size);
|
||||
*(extended *)&data[offset] = f;
|
||||
offset += extended.size;
|
||||
reserve(real.size);
|
||||
*(real *)&data[offset] = f;
|
||||
offset += real.size;
|
||||
}
|
||||
|
||||
void write(char[] s)
|
||||
|
|
8
regexp.d
8
regexp.d
|
@ -145,9 +145,9 @@ enum : ubyte
|
|||
};
|
||||
|
||||
// BUG: should this include '$'?
|
||||
static int isword(tchar c) { return isalnum(c) || c == '_'; }
|
||||
private int isword(tchar c) { return isalnum(c) || c == '_'; }
|
||||
|
||||
static uint inf = ~0u;
|
||||
private uint inf = ~0u;
|
||||
|
||||
/*********************************
|
||||
* Throws RegExpError on error
|
||||
|
@ -467,7 +467,7 @@ public tchar[][] exec()
|
|||
|
||||
tchar[][] result;
|
||||
|
||||
result = new tchar[pmatch.length][];
|
||||
result = new tchar[][pmatch.length];
|
||||
for (int i = 0; i < pmatch.length; i++)
|
||||
{
|
||||
if (pmatch[i].rm_so == pmatch[i].rm_eo)
|
||||
|
@ -2313,7 +2313,7 @@ public tchar[] replace(tchar[] format)
|
|||
|
||||
// Static version that doesn't require a RegExp object to be created
|
||||
|
||||
static tchar[] replace3(tchar[] format, tchar[] input, regmatch_t[] pmatch)
|
||||
private tchar[] replace3(tchar[] format, tchar[] input, regmatch_t[] pmatch)
|
||||
{
|
||||
OutBuffer buf;
|
||||
tchar[] result;
|
||||
|
|
52
stream.d
52
stream.d
|
@ -67,6 +67,12 @@ class Stream
|
|||
|
||||
this() { }
|
||||
|
||||
// close the stream somehow; the default
|
||||
// does nothing
|
||||
void close()
|
||||
{
|
||||
}
|
||||
|
||||
// reads block of data of specified size,
|
||||
// returns actual number of bytes read
|
||||
abstract uint readBlock(void* buffer, uint size);
|
||||
|
@ -98,9 +104,9 @@ class Stream
|
|||
void read(out ulong x) { readExact(&x, x.size); }
|
||||
void read(out float x) { readExact(&x, x.size); }
|
||||
void read(out double x) { readExact(&x, x.size); }
|
||||
void read(out extended x) { readExact(&x, x.size); }
|
||||
void read(out imaginary x) { readExact(&x, x.size); }
|
||||
void read(out complex x) { readExact(&x, x.size); }
|
||||
void read(out real x) { readExact(&x, x.size); }
|
||||
void read(out ireal x) { readExact(&x, x.size); }
|
||||
void read(out creal x) { readExact(&x, x.size); }
|
||||
void read(out char x) { readExact(&x, x.size); }
|
||||
void read(out wchar x) { readExact(&x, x.size); }
|
||||
|
||||
|
@ -442,7 +448,7 @@ class Stream
|
|||
c = getc();
|
||||
count++;
|
||||
}
|
||||
extended n = 0;
|
||||
real n = 0;
|
||||
while (isdigit(c) && width)
|
||||
{
|
||||
n = n * 10 + (c - "0");
|
||||
|
@ -487,7 +493,7 @@ class Stream
|
|||
c = getc();
|
||||
count++;
|
||||
}
|
||||
extended exp = 0;
|
||||
real exp = 0;
|
||||
while (isdigit(c) && width)
|
||||
{
|
||||
exp = exp * 10 + (c - "0");
|
||||
|
@ -518,9 +524,9 @@ class Stream
|
|||
*cast(double*)*arg = n;
|
||||
} break;
|
||||
|
||||
case "L": // extended
|
||||
case "L": // real
|
||||
{
|
||||
*cast(extended*)*arg = n;
|
||||
*cast(real*)*arg = n;
|
||||
} break;
|
||||
|
||||
default: // float
|
||||
|
@ -642,9 +648,9 @@ nws:
|
|||
void write(ulong x) { writeExact(&x, x.size); }
|
||||
void write(float x) { writeExact(&x, x.size); }
|
||||
void write(double x) { writeExact(&x, x.size); }
|
||||
void write(extended x) { writeExact(&x, x.size); }
|
||||
void write(imaginary x) { writeExact(&x, x.size); }
|
||||
void write(complex x) { writeExact(&x, x.size); }
|
||||
void write(real x) { writeExact(&x, x.size); }
|
||||
void write(ireal x) { writeExact(&x, x.size); }
|
||||
void write(creal x) { writeExact(&x, x.size); }
|
||||
void write(char x) { writeExact(&x, x.size); }
|
||||
void write(wchar x) { writeExact(&x, x.size); }
|
||||
|
||||
|
@ -944,7 +950,7 @@ class File: Stream
|
|||
}
|
||||
|
||||
// closes file, if it is open; otherwise, does nothing
|
||||
void close()
|
||||
override void close()
|
||||
{
|
||||
if (hFile)
|
||||
{
|
||||
|
@ -1165,6 +1171,7 @@ class SliceStream : Stream
|
|||
ulong low; // low stream offset.
|
||||
ulong high; // high stream offset.
|
||||
bit bounded; // upper-bounded by high.
|
||||
bit nestClose; // if set, close base when closing this stream.
|
||||
|
||||
// set the base stream and the low offset but leave the high unbounded.
|
||||
this (Stream base, ulong low)
|
||||
|
@ -1205,6 +1212,17 @@ class SliceStream : Stream
|
|||
seekable = base.seekable;
|
||||
}
|
||||
|
||||
override void close ()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (base !== null && nestClose)
|
||||
base.close ();
|
||||
}
|
||||
finally
|
||||
base = null;
|
||||
}
|
||||
|
||||
override uint readBlock (void *buffer, uint size)
|
||||
in
|
||||
{
|
||||
|
@ -1257,7 +1275,7 @@ class SliceStream : Stream
|
|||
switch (rel)
|
||||
{
|
||||
case SeekPos.Set:
|
||||
output = low;
|
||||
output = low + offset;
|
||||
break;
|
||||
|
||||
case SeekPos.Current:
|
||||
|
@ -1310,28 +1328,28 @@ class SliceStream : Stream
|
|||
}
|
||||
|
||||
// helper functions
|
||||
static bit iswhite(char c)
|
||||
private bit iswhite(char c)
|
||||
{
|
||||
return c == " " || c == "\t" || c == "\r" || c == "\n";
|
||||
}
|
||||
|
||||
static bit isdigit(char c)
|
||||
private bit isdigit(char c)
|
||||
{
|
||||
return c >= "0" && c <= "9";
|
||||
}
|
||||
|
||||
static bit isoctdigit(char c)
|
||||
private bit isoctdigit(char c)
|
||||
{
|
||||
return c >= "0" && c <= "7";
|
||||
}
|
||||
|
||||
static bit ishexdigit(char c)
|
||||
private bit ishexdigit(char c)
|
||||
{
|
||||
return isdigit(c) || (c >= "A" && c <= "F") || (c >= "a" && c <= "f");
|
||||
}
|
||||
|
||||
// API imports
|
||||
private static extern(Windows)
|
||||
private extern(Windows)
|
||||
{
|
||||
private import windows;
|
||||
HANDLE GetStdHandle(DWORD);
|
||||
|
|
10
string.d
10
string.d
|
@ -71,13 +71,13 @@ const char[6] whitespace = " \t\v\r\n\f";
|
|||
* Returns !=0 if c is whitespace
|
||||
*/
|
||||
|
||||
private int iswhite(char c)
|
||||
int iswhite(char c)
|
||||
{
|
||||
return find(whitespace, c) != -1;
|
||||
}
|
||||
|
||||
/*********************************
|
||||
* Convert string to integer / extended.
|
||||
* Convert string to integer / real.
|
||||
*/
|
||||
|
||||
long atoi(char[] s)
|
||||
|
@ -85,7 +85,7 @@ long atoi(char[] s)
|
|||
return atoi(toStringz(s));
|
||||
}
|
||||
|
||||
extended atof(char[] s)
|
||||
real atof(char[] s)
|
||||
{
|
||||
// BUG: should implement atold()
|
||||
return atof(toStringz(s));
|
||||
|
@ -616,7 +616,7 @@ unittest
|
|||
char[] word1 = "peter";
|
||||
char[] word2 = "paul";
|
||||
char[] word3 = "jerry";
|
||||
char[3][] words;
|
||||
char[][3] words;
|
||||
char[] r;
|
||||
int i;
|
||||
|
||||
|
@ -796,7 +796,7 @@ char[][] splitlines(char[] s)
|
|||
if (istart != i)
|
||||
nlines++;
|
||||
|
||||
lines = new char[nlines][];
|
||||
lines = new char[][nlines];
|
||||
nlines = 0;
|
||||
istart = 0;
|
||||
for (i = 0; i < s.length; i++)
|
||||
|
|
85
switch.d
85
switch.d
|
@ -22,27 +22,27 @@ int _d_switch_string(char[][] table, char[] ca)
|
|||
assert(ca.length >= 0);
|
||||
|
||||
// Make sure table[] is sorted correctly
|
||||
int i;
|
||||
int j;
|
||||
|
||||
for (i = 1; i < table.length; i++)
|
||||
for (j = 1; j < table.length; j++)
|
||||
{
|
||||
int len1 = table[i - 1].length;
|
||||
int len2 = table[i].length;
|
||||
int len1 = table[j - 1].length;
|
||||
int len2 = table[j].length;
|
||||
|
||||
assert(len1 <= len2);
|
||||
if (len1 == len2)
|
||||
{
|
||||
int c;
|
||||
int ci;
|
||||
|
||||
c = memcmp(table[i - 1], table[i], len1);
|
||||
assert(c < 0); // c==0 means a duplicate
|
||||
ci = memcmp(table[j - 1], table[j], len1);
|
||||
assert(ci < 0); // ci==0 means a duplicate
|
||||
}
|
||||
}
|
||||
}
|
||||
out (result)
|
||||
{
|
||||
int i;
|
||||
int c;
|
||||
int cj;
|
||||
|
||||
//printf("out _d_switch_string()\n");
|
||||
if (result == -1)
|
||||
|
@ -51,8 +51,8 @@ int _d_switch_string(char[][] table, char[] ca)
|
|||
for (i = 0; i < table.length; i++)
|
||||
{
|
||||
if (table[i].length == ca.length)
|
||||
{ c = memcmp(table[i], ca, ca.length);
|
||||
assert(c != 0);
|
||||
{ cj = memcmp(table[i], ca, ca.length);
|
||||
assert(cj != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,8 +64,8 @@ int _d_switch_string(char[][] table, char[] ca)
|
|||
assert(i < table.length);
|
||||
if (table[i].length == ca.length)
|
||||
{
|
||||
c = memcmp(table[i], ca, ca.length);
|
||||
if (c == 0)
|
||||
cj = memcmp(table[i], ca, ca.length);
|
||||
if (cj == 0)
|
||||
{
|
||||
assert(i == result);
|
||||
break;
|
||||
|
@ -95,30 +95,45 @@ int _d_switch_string(char[][] table, char[] ca)
|
|||
printf("table[%d] = %d, '%s'\n", mid, pca.length, (char *)pca);
|
||||
}
|
||||
*/
|
||||
|
||||
// Do binary search
|
||||
while (low < high)
|
||||
if (high &&
|
||||
ca.length >= table[0].length &&
|
||||
ca.length <= table[high - 1].length)
|
||||
{
|
||||
mid = (low + high) >> 1;
|
||||
pca = table[mid];
|
||||
c = ca.length - pca.length;
|
||||
if (c == 0)
|
||||
// Looking for 0 length string, which would only be at the beginning
|
||||
if (ca.length == 0)
|
||||
return 0;
|
||||
|
||||
char c1 = ca[0];
|
||||
|
||||
// Do binary search
|
||||
while (low < high)
|
||||
{
|
||||
c = memcmp(ca, pca, ca.length);
|
||||
mid = (low + high) >> 1;
|
||||
pca = table[mid];
|
||||
c = ca.length - pca.length;
|
||||
if (c == 0)
|
||||
{ //printf("found %d\n", mid);
|
||||
return mid;
|
||||
{
|
||||
c = (byte)c1 - (byte)pca[0];
|
||||
if (c == 0)
|
||||
{
|
||||
c = memcmp(ca, pca, ca.length);
|
||||
if (c == 0)
|
||||
{ //printf("found %d\n", mid);
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (c < 0)
|
||||
{
|
||||
high = mid;
|
||||
}
|
||||
else
|
||||
{
|
||||
low = mid + 1;
|
||||
}
|
||||
}
|
||||
if (c < 0)
|
||||
{
|
||||
high = mid;
|
||||
}
|
||||
else
|
||||
{
|
||||
low = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
//printf("not found\n");
|
||||
return -1; // not found
|
||||
}
|
||||
|
@ -145,19 +160,19 @@ int _d_switch_ustring(wchar[][] table, wchar[] ca)
|
|||
assert(ca.length >= 0);
|
||||
|
||||
// Make sure table[] is sorted correctly
|
||||
int i;
|
||||
int j;
|
||||
|
||||
for (i = 1; i < table.length; i++)
|
||||
for (j = 1; j < table.length; j++)
|
||||
{
|
||||
int len1 = table[i - 1].length;
|
||||
int len2 = table[i].length;
|
||||
int len1 = table[j - 1].length;
|
||||
int len2 = table[j].length;
|
||||
|
||||
assert(len1 <= len2);
|
||||
if (len1 == len2)
|
||||
{
|
||||
int c;
|
||||
|
||||
c = memcmp(table[i - 1], table[i], len1 * wchar.size);
|
||||
c = memcmp(table[j - 1], table[j], len1 * wchar.size);
|
||||
assert(c < 0); // c==0 means a duplicate
|
||||
}
|
||||
}
|
||||
|
|
71
ti_Ag.d
Normal file
71
ti_Ag.d
Normal file
|
@ -0,0 +1,71 @@
|
|||
|
||||
import string;
|
||||
|
||||
// byte[]
|
||||
|
||||
class TypeInfo_Ag : TypeInfo
|
||||
{
|
||||
uint getHash(void *p)
|
||||
{ byte[] s = *(byte[]*)p;
|
||||
uint len = s.length;
|
||||
byte *str = s;
|
||||
uint hash = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
switch (len)
|
||||
{
|
||||
case 0:
|
||||
return hash;
|
||||
|
||||
case 1:
|
||||
hash *= 9;
|
||||
hash += *(ubyte *)str;
|
||||
return hash;
|
||||
|
||||
case 2:
|
||||
hash *= 9;
|
||||
hash += *(ushort *)str;
|
||||
return hash;
|
||||
|
||||
case 3:
|
||||
hash *= 9;
|
||||
hash += (*(ushort *)str << 8) +
|
||||
((ubyte *)str)[2];
|
||||
return hash;
|
||||
|
||||
default:
|
||||
hash *= 9;
|
||||
hash += *(uint *)str;
|
||||
str += 4;
|
||||
len -= 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
byte[] s1 = *(byte[]*)p1;
|
||||
byte[] s2 = *(byte[]*)p2;
|
||||
|
||||
return s1.length == s2.length &&
|
||||
memcmp((byte *)s1, (byte *)s2, s1.length) == 0;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
char[] s1 = *(char[]*)p1;
|
||||
char[] s2 = *(char[]*)p2;
|
||||
|
||||
return string.cmp(s1, s2);
|
||||
}
|
||||
|
||||
int tsize()
|
||||
{
|
||||
return (byte[]).size;
|
||||
}
|
||||
}
|
||||
|
38
ti_cdouble.d
Normal file
38
ti_cdouble.d
Normal file
|
@ -0,0 +1,38 @@
|
|||
|
||||
// cdouble
|
||||
|
||||
class TypeInfo_r : TypeInfo
|
||||
{
|
||||
uint getHash(void *p)
|
||||
{
|
||||
return ((uint *)p)[0] + ((uint *)p)[1] +
|
||||
((uint *)p)[2] + ((uint *)p)[3];
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return *(cdouble *)p1 == *(cdouble *)p2;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
cdouble a = *(cdouble *) p1;
|
||||
cdouble b = *(cdouble *) p2;
|
||||
return a < b ? -1 : a > b ? 1 : 0;
|
||||
}
|
||||
|
||||
int tsize()
|
||||
{
|
||||
return cdouble.size;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
cdouble t;
|
||||
|
||||
t = *(cdouble *)p1;
|
||||
*(cdouble *)p1 = *(cdouble *)p2;
|
||||
*(cdouble *)p2 = t;
|
||||
}
|
||||
}
|
||||
|
37
ti_cfloat.d
Normal file
37
ti_cfloat.d
Normal file
|
@ -0,0 +1,37 @@
|
|||
|
||||
// cfloat
|
||||
|
||||
class TypeInfo_q : TypeInfo
|
||||
{
|
||||
uint getHash(void *p)
|
||||
{
|
||||
return ((uint *)p)[0] + ((uint *)p)[1];
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return *(cfloat *)p1 == *(cfloat *)p2;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
cfloat a = *(cfloat *) p1;
|
||||
cfloat b = *(cfloat *) p2;
|
||||
return a < b ? -1 : a > b ? 1 : 0;
|
||||
}
|
||||
|
||||
int tsize()
|
||||
{
|
||||
return cfloat.size;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
cfloat t;
|
||||
|
||||
t = *(cfloat *)p1;
|
||||
*(cfloat *)p1 = *(cfloat *)p2;
|
||||
*(cfloat *)p2 = t;
|
||||
}
|
||||
}
|
||||
|
39
ti_creal.d
Normal file
39
ti_creal.d
Normal file
|
@ -0,0 +1,39 @@
|
|||
|
||||
// creal
|
||||
|
||||
class TypeInfo_c : TypeInfo
|
||||
{
|
||||
uint getHash(void *p)
|
||||
{
|
||||
return ((uint *)p)[0] + ((uint *)p)[1] +
|
||||
((uint *)p)[2] + ((uint *)p)[3] +
|
||||
((uint *)p)[4];
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return *(creal *)p1 == *(creal *)p2;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
creal a = *(creal *) p1;
|
||||
creal b = *(creal *) p2;
|
||||
return a < b ? -1 : a > b ? 1 : 0;
|
||||
}
|
||||
|
||||
int tsize()
|
||||
{
|
||||
return creal.size;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
creal t;
|
||||
|
||||
t = *(creal *)p1;
|
||||
*(creal *)p1 = *(creal *)p2;
|
||||
*(creal *)p2 = t;
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ class TypeInfo_d : TypeInfo
|
|||
{
|
||||
uint getHash(void *p)
|
||||
{
|
||||
return *(double *)p;
|
||||
return ((uint *)p)[0] + ((uint *)p)[1];
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
|
|
|
@ -5,7 +5,7 @@ class TypeInfo_f : TypeInfo
|
|||
{
|
||||
uint getHash(void *p)
|
||||
{
|
||||
return *(float *)p;
|
||||
return *(uint *)p;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
|
|
35
ti_idouble.d
Normal file
35
ti_idouble.d
Normal file
|
@ -0,0 +1,35 @@
|
|||
|
||||
// idouble
|
||||
|
||||
class TypeInfo_p : TypeInfo
|
||||
{
|
||||
uint getHash(void *p)
|
||||
{
|
||||
return ((uint *)p)[0] + ((uint *)p)[1];
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return *(idouble *)p1 == *(idouble *)p2;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return *(double *)p1 - *(double *)p2;
|
||||
}
|
||||
|
||||
int tsize()
|
||||
{
|
||||
return idouble.size;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
idouble t;
|
||||
|
||||
t = *(idouble *)p1;
|
||||
*(idouble *)p1 = *(idouble *)p2;
|
||||
*(idouble *)p2 = t;
|
||||
}
|
||||
}
|
||||
|
35
ti_ifloat.d
Normal file
35
ti_ifloat.d
Normal file
|
@ -0,0 +1,35 @@
|
|||
|
||||
// ifloat
|
||||
|
||||
class TypeInfo_o : TypeInfo
|
||||
{
|
||||
uint getHash(void *p)
|
||||
{
|
||||
return *(uint *)p;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return *(ifloat *)p1 == *(ifloat *)p2;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return *(float *)p1 - *(float *)p2;
|
||||
}
|
||||
|
||||
int tsize()
|
||||
{
|
||||
return ifloat.size;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
ifloat t;
|
||||
|
||||
t = *(ifloat *)p1;
|
||||
*(ifloat *)p1 = *(ifloat *)p2;
|
||||
*(ifloat *)p2 = t;
|
||||
}
|
||||
}
|
||||
|
35
ti_ireal.d
Normal file
35
ti_ireal.d
Normal file
|
@ -0,0 +1,35 @@
|
|||
|
||||
// ireal
|
||||
|
||||
class TypeInfo_j : TypeInfo
|
||||
{
|
||||
uint getHash(void *p)
|
||||
{
|
||||
return ((uint *)p)[0] + ((uint *)p)[1] + ((ushort *)p)[4];
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return *(ireal *)p1 == *(ireal *)p2;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return *(real *)p1 - *(real *)p2;
|
||||
}
|
||||
|
||||
int tsize()
|
||||
{
|
||||
return ireal.size;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
ireal t;
|
||||
|
||||
t = *(ireal *)p1;
|
||||
*(ireal *)p1 = *(ireal *)p2;
|
||||
*(ireal *)p2 = t;
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ class TypeInfo_l : TypeInfo
|
|||
{
|
||||
uint getHash(void *p)
|
||||
{
|
||||
return *(long *)p;
|
||||
return *(uint *)p + ((uint *)p)[1];
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
|
@ -15,7 +15,11 @@ class TypeInfo_l : TypeInfo
|
|||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return *(long *)p1 - *(long *)p2;
|
||||
if (*(long *)p1 < *(long *)p2)
|
||||
return -1;
|
||||
else if (*(long *)p1 > *(long *)p2)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tsize()
|
||||
|
|
35
ti_real.d
Normal file
35
ti_real.d
Normal file
|
@ -0,0 +1,35 @@
|
|||
|
||||
// real
|
||||
|
||||
class TypeInfo_e : TypeInfo
|
||||
{
|
||||
uint getHash(void *p)
|
||||
{
|
||||
return ((uint *)p)[0] + ((uint *)p)[1] + ((ushort *)p)[4];
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return *(real *)p1 == *(real *)p2;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return *(real *)p1 - *(real *)p2;
|
||||
}
|
||||
|
||||
int tsize()
|
||||
{
|
||||
return real.size;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
real t;
|
||||
|
||||
t = *(real *)p1;
|
||||
*(real *)p1 = *(real *)p2;
|
||||
*(real *)p2 = t;
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ class TypeInfo_m : TypeInfo
|
|||
{
|
||||
uint getHash(void *p)
|
||||
{
|
||||
return *(ulong *)p;
|
||||
return *(uint *)p + ((uint *)p)[1];
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
|
@ -15,7 +15,11 @@ class TypeInfo_m : TypeInfo
|
|||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return *(ulong *)p1 - *(ulong *)p2;
|
||||
if (*(ulong *)p1 < *(ulong *)p2)
|
||||
return -1;
|
||||
else if (*(ulong *)p1 > *(ulong *)p2)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tsize()
|
||||
|
|
|
@ -17,7 +17,7 @@ class TypeInfo_u : TypeInfo
|
|||
return *(wchar *)p1 - *(wchar *)p2;
|
||||
}
|
||||
|
||||
wchar tsize()
|
||||
int tsize()
|
||||
{
|
||||
return wchar.size;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ int main(char[][] args)
|
|||
OutBuffer b = new OutBuffer(); // outbuffer
|
||||
ctype.tolower('A'); // ctype
|
||||
RegExp r = new RegExp(null, null); // regexp
|
||||
rand();
|
||||
random.rand();
|
||||
int a[];
|
||||
a.reverse; // adi
|
||||
a.sort; // qsort
|
||||
|
|
|
@ -257,9 +257,8 @@ struct WIN32_FIND_DATA {
|
|||
char cAlternateFileName[ 14 ];
|
||||
}
|
||||
|
||||
export:
|
||||
|
||||
|
||||
export
|
||||
{
|
||||
BOOL CloseHandle(HANDLE hObject);
|
||||
HANDLE CreateFileA(char *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
|
||||
SECURITY_ATTRIBUTES *lpSecurityAttributes, DWORD dwCreationDisposition,
|
||||
|
@ -280,6 +279,7 @@ DWORD SetFilePointer(HANDLE hFile, LONG lDistanceToMove,
|
|||
BOOL WriteFile(HANDLE hFile, void *lpBuffer, DWORD nNumberOfBytesToWrite,
|
||||
DWORD *lpNumberOfBytesWritten, OVERLAPPED *lpOverlapped);
|
||||
DWORD GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize);
|
||||
}
|
||||
|
||||
|
||||
export
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue