moving some flisp-specific code out of library
This commit is contained in:
parent
689ec946d8
commit
6ed61e66ac
|
@ -1,3 +1,5 @@
|
|||
#include "operators.c"
|
||||
|
||||
#ifdef BITS64
|
||||
#define NWORDS(sz) (((sz)+7)>>3)
|
||||
#else
|
||||
|
|
28
flisp.h
28
flisp.h
|
@ -208,6 +208,19 @@ typedef struct {
|
|||
} cvtable_t;
|
||||
|
||||
/* functions needed to implement the value interface (cvtable_t) */
|
||||
typedef enum { T_INT8, T_UINT8, T_INT16, T_UINT16, T_INT32, T_UINT32,
|
||||
T_INT64, T_UINT64, T_FLOAT, T_DOUBLE } numerictype_t;
|
||||
|
||||
#define N_NUMTYPES ((int)T_DOUBLE+1)
|
||||
|
||||
#ifdef BITS64
|
||||
# define T_LONG T_INT64
|
||||
# define T_ULONG T_UINT64
|
||||
#else
|
||||
# define T_LONG T_INT32
|
||||
# define T_ULONG T_UINT32
|
||||
#endif
|
||||
|
||||
value_t relocate_lispvalue(value_t v);
|
||||
void print_traverse(value_t v);
|
||||
void fl_print_chr(char c, ios_t *f);
|
||||
|
@ -351,6 +364,21 @@ value_t mk_wchar(int32_t n);
|
|||
value_t return_from_uint64(uint64_t Uaccum);
|
||||
value_t return_from_int64(int64_t Saccum);
|
||||
|
||||
numerictype_t effective_numerictype(double r);
|
||||
double conv_to_double(void *data, numerictype_t tag);
|
||||
void conv_from_double(void *data, double d, numerictype_t tag);
|
||||
int64_t conv_to_int64(void *data, numerictype_t tag);
|
||||
uint64_t conv_to_uint64(void *data, numerictype_t tag);
|
||||
int32_t conv_to_int32(void *data, numerictype_t tag);
|
||||
uint32_t conv_to_uint32(void *data, numerictype_t tag);
|
||||
#ifdef BITS64
|
||||
#define conv_to_long conv_to_int64
|
||||
#define conv_to_ulong conv_to_uint64
|
||||
#else
|
||||
#define conv_to_long conv_to_int32
|
||||
#define conv_to_ulong conv_to_uint32
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
builtin_t fptr;
|
||||
|
|
16
llt/Makefile
16
llt/Makefile
|
@ -1,14 +1,11 @@
|
|||
CC = gcc
|
||||
|
||||
SRCS = bitvector.c hashing.c socket.c timefuncs.c dblprint.c ptrhash.c \
|
||||
utf8.c ios.c operators.c cplxprint.c dirpath.c htable.c \
|
||||
bitvector-ops.c int2str.c dump.c random.c bswap.c memalign.c \
|
||||
swapreverse.c lltinit.c arraylist.c
|
||||
SRCS = bitvector.c hashing.c socket.c timefuncs.c ptrhash.c utf8.c ios.c \
|
||||
dirpath.c htable.c bitvector-ops.c int2str.c dump.c random.c \
|
||||
lltinit.c arraylist.c
|
||||
OBJS = $(SRCS:%.c=%.o)
|
||||
DOBJS = $(SRCS:%.c=%.do)
|
||||
TARGET = libllt.a
|
||||
TESTSRC = unittest.c
|
||||
TESTER = llttest
|
||||
|
||||
# OS flags: LINUX, WIN32, MACOSX
|
||||
# architecture flags: __CPU__=xxx, BITS64, ARCH_X86, ARCH_X86_64
|
||||
|
@ -34,16 +31,9 @@ release: $(OBJS)
|
|||
rm -rf $(TARGET)
|
||||
ar rs $(TARGET) $(OBJS)
|
||||
|
||||
test:
|
||||
make clean
|
||||
make debug CFLAGS=-DENABLE_LLT_TEST
|
||||
gcc $(TESTSRC) $(TARGET) -o $(TESTER) -lm
|
||||
./$(TESTER)
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
rm -f *.do
|
||||
rm -f *~
|
||||
rm -f core*
|
||||
rm -f $(TARGET)
|
||||
rm -f $(TESTER)
|
||||
|
|
87
llt/bswap.c
87
llt/bswap.c
|
@ -1,87 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <alloca.h>
|
||||
#include "dtypes.h"
|
||||
#include "utils.h"
|
||||
|
||||
void bswap_buffer(byte_t *data, size_t sz, size_t npts)
|
||||
{
|
||||
size_t i, b;
|
||||
byte_t *el;
|
||||
byte_t temp;
|
||||
|
||||
if (sz <= 1)
|
||||
return;
|
||||
|
||||
switch (sz) {
|
||||
case 8:
|
||||
for(i=0; i < npts; i++) {
|
||||
((u_int64_t*)data)[i] = bswap_64(((u_int64_t*)data)[i]);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
for(i=0; i < npts; i++) {
|
||||
((u_int32_t*)data)[i] = bswap_32(((u_int32_t*)data)[i]);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
for(i=0; i < npts; i++) {
|
||||
((u_int16_t*)data)[i] = bswap_16(((u_int16_t*)data)[i]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
for(i=0; i < sz * npts; i += sz) {
|
||||
el = data + i;
|
||||
for(b=0; b < sz/2; b++) {
|
||||
temp = el[b];
|
||||
el[b] = el[sz-b-1];
|
||||
el[sz-b-1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bswap(byte_t *s, size_t n)
|
||||
{
|
||||
unsigned int i;
|
||||
char temp;
|
||||
|
||||
switch (n) {
|
||||
case 8:
|
||||
*(u_int64_t*)s = bswap_64(*(u_int64_t*)s); break;
|
||||
case 4:
|
||||
*(u_int32_t*)s = bswap_32(*(u_int32_t*)s); break;
|
||||
case 2:
|
||||
*(u_int16_t*)s = bswap_16(*(u_int16_t*)s); break;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
for(i=0; i < n/2; i++) {
|
||||
temp = s[i];
|
||||
s[i] = s[n-i-1];
|
||||
s[n-i-1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bswap_to(byte_t *dest, byte_t *src, size_t n)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
switch (n) {
|
||||
case 8:
|
||||
*(u_int64_t*)dest = bswap_64(*(u_int64_t*)src); break;
|
||||
case 4:
|
||||
*(u_int32_t*)dest = bswap_32(*(u_int32_t*)src); break;
|
||||
case 2:
|
||||
*(u_int16_t*)dest = bswap_16(*(u_int16_t*)src); break;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
for(i=0; i < n; i++) {
|
||||
dest[i] = src[n-i-1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "dtypes.h"
|
||||
#include "utils.h"
|
||||
|
||||
void snprint_cplx(char *s, size_t cnt, double re, double im,
|
||||
// args to pass on to snprint_real
|
||||
int width, int dec,
|
||||
int max_digs_rt, int max_digs_lf,
|
||||
// print spaces around sign in a+bi
|
||||
int spflag)
|
||||
{
|
||||
int fzr = (re==0) || rel_zero(re,im);
|
||||
int fzi = (im==0) || rel_zero(im,re);
|
||||
size_t len, sl;
|
||||
size_t space = cnt;
|
||||
|
||||
s[0] = '\0';
|
||||
if (isnan(im) && fzr) {
|
||||
if (space < 2) return;
|
||||
snprint_real(s, space-2, im, width, dec, max_digs_rt, max_digs_lf);
|
||||
strcat(s, "i");
|
||||
return;
|
||||
}
|
||||
if (!fzr || (fzr && fzi)) {
|
||||
if (space < 4) return;
|
||||
snprint_real(s, space-4, re, width, dec, max_digs_rt, max_digs_lf);
|
||||
if ((im >= 0 || (isnan(im)&&!sign_bit(im))) && !fzi) {
|
||||
if (spflag) {
|
||||
strcat(s, " + ");
|
||||
}
|
||||
else {
|
||||
strcat(s, "+");
|
||||
}
|
||||
}
|
||||
else if (!fzi) {
|
||||
im = -im;
|
||||
if (spflag)
|
||||
strcat(s, " - ");
|
||||
else
|
||||
strcat(s, "-");
|
||||
}
|
||||
}
|
||||
if (!fzi) {
|
||||
len = sl = strlen(s);
|
||||
if (im == -1) {
|
||||
while ((long)(len-sl) < (long)(width-2) && len < (space-3))
|
||||
s[len++] = ' ';
|
||||
s[len] = '-';
|
||||
s[len+1] = 'i';
|
||||
s[len+2] = '\0';
|
||||
}
|
||||
else if (im == 1) {
|
||||
while ((long)(len-sl) < (long)(width-1) && len < (space-2))
|
||||
s[len++] = ' ';
|
||||
s[len] = 'i';
|
||||
s[len+1] = '\0';
|
||||
}
|
||||
else {
|
||||
snprint_real(s+len, space-len-2, im, width, dec,
|
||||
max_digs_rt, max_digs_lf);
|
||||
strcat(s, "i");
|
||||
}
|
||||
}
|
||||
}
|
122
llt/dblprint.c
122
llt/dblprint.c
|
@ -1,122 +0,0 @@
|
|||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "dtypes.h"
|
||||
#include "ieee754.h"
|
||||
#include "utils.h"
|
||||
|
||||
int double_exponent(double d)
|
||||
{
|
||||
union ieee754_double dl;
|
||||
|
||||
dl.d = d;
|
||||
return dl.ieee.exponent - IEEE754_DOUBLE_BIAS;
|
||||
}
|
||||
|
||||
double double_mantissa(double d)
|
||||
{
|
||||
union ieee754_double dl;
|
||||
|
||||
dl.d = d;
|
||||
dl.ieee.exponent = IEEE754_DOUBLE_BIAS;
|
||||
dl.ieee.negative = 0;
|
||||
return dl.d;
|
||||
}
|
||||
|
||||
int float_exponent(float f)
|
||||
{
|
||||
union ieee754_float fl;
|
||||
|
||||
fl.f = f;
|
||||
return fl.ieee.exponent - IEEE754_FLOAT_BIAS;
|
||||
}
|
||||
|
||||
float float_mantissa(float f)
|
||||
{
|
||||
union ieee754_float fl;
|
||||
|
||||
fl.f = f;
|
||||
fl.ieee.exponent = IEEE754_FLOAT_BIAS;
|
||||
fl.ieee.negative = 0;
|
||||
return fl.f;
|
||||
}
|
||||
|
||||
void snprint_real(char *s, size_t cnt, double r,
|
||||
int width, // printf field width, or 0
|
||||
int dec, // # decimal digits desired, recommend 16
|
||||
// # of zeros in .00...0x before using scientific notation
|
||||
// recommend 3-4 or so
|
||||
int max_digs_rt,
|
||||
// # of digits left of decimal before scientific notation
|
||||
// recommend 10
|
||||
int max_digs_lf)
|
||||
{
|
||||
int mag;
|
||||
double fpart, temp;
|
||||
char format[8];
|
||||
char num_format[3];
|
||||
int sz, keepz=0;
|
||||
|
||||
s[0] = '\0';
|
||||
if (width == -1) {
|
||||
width = 0;
|
||||
keepz=1;
|
||||
}
|
||||
if (isnan(r)) {
|
||||
if (sign_bit(r))
|
||||
strncpy(s, "-nan", cnt);
|
||||
else
|
||||
strncpy(s, "nan", cnt);
|
||||
return;
|
||||
}
|
||||
if (r == 0) {
|
||||
strncpy(s, "0", cnt);
|
||||
return;
|
||||
}
|
||||
|
||||
num_format[0] = 'l';
|
||||
num_format[2] = '\0';
|
||||
|
||||
mag = double_exponent(r);
|
||||
|
||||
mag = (int)(((double)mag)/LOG2_10 + 0.5);
|
||||
if (r == 0)
|
||||
mag = 0;
|
||||
if ((mag > max_digs_lf-1) || (mag < -max_digs_rt)) {
|
||||
num_format[1] = 'e';
|
||||
temp = r/pow(10, mag); /* see if number will have a decimal */
|
||||
fpart = temp - floor(temp); /* when written in scientific notation */
|
||||
}
|
||||
else {
|
||||
num_format[1] = 'f';
|
||||
fpart = r - floor(r);
|
||||
}
|
||||
if (fpart == 0)
|
||||
dec = 0;
|
||||
if (width == 0) {
|
||||
snprintf(format, 8, "%%.%d%s", dec, num_format);
|
||||
}
|
||||
else {
|
||||
snprintf(format, 8, "%%%d.%d%s", width, dec, num_format);
|
||||
}
|
||||
sz = snprintf(s, cnt, format, r);
|
||||
/* trim trailing zeros from fractions. not when using scientific
|
||||
notation, since we might have e.g. 1.2000e+100. also not when we
|
||||
need a specific output width */
|
||||
if (width == 0 && !keepz) {
|
||||
if (sz > 2 && fpart && num_format[1]!='e') {
|
||||
while (s[sz-1] == '0') {
|
||||
s[sz-1]='\0';
|
||||
sz--;
|
||||
}
|
||||
// don't need trailing .
|
||||
if (s[sz-1] == '.') {
|
||||
s[sz-1] = '\0';
|
||||
sz--;
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO. currently 1.1e20 prints as 1.1000000000000000e+20; be able to
|
||||
// get rid of all those zeros.
|
||||
}
|
13
llt/dtypes.h
13
llt/dtypes.h
|
@ -178,17 +178,4 @@ extern float F_NNAN;
|
|||
extern float F_PINF;
|
||||
extern float F_NINF;
|
||||
|
||||
typedef enum { T_INT8, T_UINT8, T_INT16, T_UINT16, T_INT32, T_UINT32,
|
||||
T_INT64, T_UINT64, T_FLOAT, T_DOUBLE } numerictype_t;
|
||||
|
||||
#define N_NUMTYPES ((int)T_DOUBLE+1)
|
||||
|
||||
#ifdef BITS64
|
||||
# define T_LONG T_INT64
|
||||
# define T_ULONG T_UINT64
|
||||
#else
|
||||
# define T_LONG T_INT32
|
||||
# define T_ULONG T_UINT32
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <alloca.h>
|
||||
#include "dtypes.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define ALIGNED_TO_ACTUAL(p) (((char*)p) - ((long*)p)[-1])
|
||||
|
||||
static void *aligned_ptr(char *ptr, size_t align_size)
|
||||
{
|
||||
char *ptr2, *aligned_ptr;
|
||||
|
||||
ptr2 = ptr + sizeof(long);
|
||||
aligned_ptr = (char*)LLT_ALIGN(((uptrint_t)ptr2), align_size);
|
||||
|
||||
((long*)aligned_ptr)[-1] = (long)(aligned_ptr - ptr);
|
||||
|
||||
return aligned_ptr;
|
||||
}
|
||||
|
||||
/* align_size has to be a power of two */
|
||||
void *malloc_aligned(size_t size, size_t align_size)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
ptr = (char*)LLT_ALLOC(size + align_size-1 + sizeof(long));
|
||||
if (ptr == NULL)
|
||||
return NULL;
|
||||
|
||||
return aligned_ptr(ptr, align_size);
|
||||
}
|
||||
|
||||
void free_aligned(void *ptr)
|
||||
{
|
||||
LLT_FREE(ALIGNED_TO_ACTUAL(ptr));
|
||||
}
|
||||
|
||||
void *realloc_aligned(void *ptr, size_t size, size_t align_size)
|
||||
{
|
||||
char *pnew;
|
||||
|
||||
if (ptr != NULL)
|
||||
ptr = ALIGNED_TO_ACTUAL(ptr);
|
||||
pnew = LLT_REALLOC(ptr, size + align_size-1 + sizeof(long));
|
||||
if (pnew == NULL)
|
||||
return NULL;
|
||||
|
||||
return aligned_ptr(pnew, align_size);
|
||||
}
|
|
@ -1,187 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <alloca.h>
|
||||
#include "dtypes.h"
|
||||
#include "utils.h"
|
||||
|
||||
void memswap(char *a, char *b, size_t sz)
|
||||
{
|
||||
int8_t i8;
|
||||
int32_t i32;
|
||||
int32_t *a4, *b4;
|
||||
|
||||
if (sz < 4) {
|
||||
while (sz--) {
|
||||
i8 = *a;
|
||||
*a++ = *b;
|
||||
*b++ = i8;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (sz & 0x3) {
|
||||
i8 = *a;
|
||||
*a++ = *b;
|
||||
*b++ = i8;
|
||||
sz--;
|
||||
}
|
||||
a4 = (int32_t*)a;
|
||||
b4 = (int32_t*)b;
|
||||
sz >>= 2;
|
||||
while (sz--) {
|
||||
i32 = *a4;
|
||||
*a4++ = *b4;
|
||||
*b4++ = i32;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void memreverse(char *a, size_t n, size_t elsz)
|
||||
{
|
||||
int64_t i64, *pi64;
|
||||
int32_t i32, *pi32;
|
||||
int16_t i16, *pi16;
|
||||
int8_t i8;
|
||||
size_t i;
|
||||
char *temp;
|
||||
size_t eli, tot;
|
||||
|
||||
if (n==0 || elsz==0) return;
|
||||
switch(elsz) {
|
||||
case 16:
|
||||
pi64 = (int64_t*)a;
|
||||
for(i=0; i < n/2; i++) {
|
||||
i64 = pi64[2*i];
|
||||
pi64[2*i] = pi64[2*(n-i-1)];
|
||||
pi64[2*(n-i-1)] = i64;
|
||||
|
||||
i64 = pi64[2*i+1];
|
||||
pi64[2*i+1] = pi64[2*(n-i-1)+1];
|
||||
pi64[2*(n-i-1)+1] = i64;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
pi64 = (int64_t*)a;
|
||||
for(i=0; i < n/2; i++) {
|
||||
i64 = pi64[i];
|
||||
pi64[i] = pi64[n-i-1];
|
||||
pi64[n-i-1] = i64;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
pi32 = (int32_t*)a;
|
||||
for(i=0; i < n/2; i++) {
|
||||
i32 = pi32[i];
|
||||
pi32[i] = pi32[n-i-1];
|
||||
pi32[n-i-1] = i32;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
pi16 = (int16_t*)a;
|
||||
for(i=0; i < n/2; i++) {
|
||||
i16 = pi16[i];
|
||||
pi16[i] = pi16[n-i-1];
|
||||
pi16[n-i-1] = i16;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
for(i=0; i < n/2; i++) {
|
||||
i8 = a[i];
|
||||
a[i] = a[n-i-1];
|
||||
a[n-i-1] = i8;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
tot = n*elsz;
|
||||
if (elsz < 4097)
|
||||
temp = alloca(elsz);
|
||||
else
|
||||
temp = malloc(elsz);
|
||||
|
||||
if (temp != NULL) {
|
||||
for(i=0, eli=0; i < n/2; i++, eli+=elsz) {
|
||||
memcpy(temp, &a[eli], elsz);
|
||||
memcpy(&a[eli], &a[tot-eli-elsz], elsz);
|
||||
memcpy(&a[tot-eli-elsz], temp, elsz);
|
||||
}
|
||||
|
||||
if (elsz >= 4097)
|
||||
free(temp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void memreverse_to(char *dest, char *a, size_t n, size_t elsz)
|
||||
{
|
||||
int64_t *pi64, *di64;
|
||||
int32_t *pi32, *di32;
|
||||
int16_t *pi16, *di16;
|
||||
size_t i;
|
||||
size_t eli, tot;
|
||||
if (n==0 || elsz==0) return;
|
||||
switch(elsz) {
|
||||
case 16:
|
||||
pi64 = (int64_t*)a;
|
||||
di64 = (int64_t*)dest;
|
||||
for(i=0; i < n/2; i++) {
|
||||
di64[2*i] = pi64[2*(n-i-1)];
|
||||
di64[2*(n-i-1)] = pi64[2*i];
|
||||
|
||||
di64[2*i+1] = pi64[2*(n-i-1)+1];
|
||||
di64[2*(n-i-1)+1] = pi64[2*i+1];
|
||||
}
|
||||
if (n&0x1) {
|
||||
di64[2*i] = pi64[2*i];
|
||||
di64[2*i+1] = pi64[2*i+1];
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
pi64 = (int64_t*)a;
|
||||
di64 = (int64_t*)dest;
|
||||
for(i=0; i < n/2; i++) {
|
||||
di64[i] = pi64[n-i-1];
|
||||
di64[n-i-1] = pi64[i];
|
||||
}
|
||||
if (n&0x1)
|
||||
di64[i] = pi64[i];
|
||||
break;
|
||||
case 4:
|
||||
pi32 = (int32_t*)a;
|
||||
di32 = (int32_t*)dest;
|
||||
for(i=0; i < n/2; i++) {
|
||||
di32[i] = pi32[n-i-1];
|
||||
di32[n-i-1] = pi32[i];
|
||||
}
|
||||
if (n&0x1)
|
||||
di32[i] = pi32[i];
|
||||
break;
|
||||
case 2:
|
||||
pi16 = (int16_t*)a;
|
||||
di16 = (int16_t*)dest;
|
||||
for(i=0; i < n/2; i++) {
|
||||
di16[i] = pi16[n-i-1];
|
||||
di16[n-i-1] = pi16[i];
|
||||
}
|
||||
if (n&0x1)
|
||||
di16[i] = pi16[i];
|
||||
break;
|
||||
case 1:
|
||||
for(i=0; i < n/2; i++) {
|
||||
dest[i] = a[n-i-1];
|
||||
dest[n-i-1] = a[i];
|
||||
}
|
||||
if (n&0x1)
|
||||
dest[i] = a[i];
|
||||
break;
|
||||
default:
|
||||
tot = n*elsz;
|
||||
for(i=0, eli=0; i < n/2; i++, eli+=elsz) {
|
||||
memcpy(&dest[eli], &a[tot - eli - elsz], elsz);
|
||||
memcpy(&dest[tot - eli - elsz], &a[eli], elsz);
|
||||
}
|
||||
if (n&0x1)
|
||||
memcpy(&dest[eli], &a[eli], elsz);
|
||||
break;
|
||||
}
|
||||
}
|
142
llt/unittest.c
142
llt/unittest.c
|
@ -1,142 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
#include "llt.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
llt_init();
|
||||
|
||||
test_dblprint();
|
||||
test_operators();
|
||||
|
||||
/*
|
||||
char *buf = malloc(20000);
|
||||
char *buf2 = malloc(20000);
|
||||
FILE *f = fopen("textread.m","rb");
|
||||
int i=0;
|
||||
while (!feof(f))
|
||||
buf[i++] = fgetc(f);
|
||||
buf[i-1] = '\0';
|
||||
int len = i-1;
|
||||
double t0 = clock_now();
|
||||
int j=0;
|
||||
for(i=0; i < 20000; i++) {
|
||||
//j+=u8_charnum(buf,len);
|
||||
u8_reverse(buf2, buf, len);
|
||||
}
|
||||
printf("textread took %.4f sec (%d)\n", clock_now()-t0, j);
|
||||
|
||||
FILE *f2 = fopen("u8.txt","rb");
|
||||
i=0;
|
||||
while (!feof(f2))
|
||||
buf[i++] = fgetc(f2);
|
||||
buf[i-1] = '\0';
|
||||
len = i-1;
|
||||
t0 = clock_now();
|
||||
j=0;
|
||||
for(i=0; i < 20000; i++) {
|
||||
//j+=u8_charnum(buf,len);
|
||||
u8_reverse(buf2, buf, len);
|
||||
}
|
||||
printf("u8 took %.4f sec (%d)\n\n", clock_now()-t0, j);
|
||||
*/
|
||||
|
||||
test_ios();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void prettycplx(double r, double i)
|
||||
{
|
||||
char str[64];
|
||||
snprint_cplx(str, sizeof(str), r, i, 0, 16, 3, 10, 1);
|
||||
fputs(str, stdout);
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
|
||||
static void prettyreal(double r)
|
||||
{
|
||||
char str[64];
|
||||
snprint_real(str, sizeof(str), r, 0, 16, 3, 10);
|
||||
fputs(str, stdout);
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
|
||||
void test_dblprint()
|
||||
{
|
||||
char str[64];
|
||||
|
||||
prettycplx(0,0);
|
||||
prettycplx(1,0);
|
||||
prettycplx(0,1);
|
||||
prettycplx(1,1);
|
||||
prettycplx(-1,0);
|
||||
prettycplx(0,-1);
|
||||
prettycplx(1,-1);
|
||||
prettycplx(-1,1);
|
||||
prettycplx(-1,-1);
|
||||
prettycplx(2,0);
|
||||
prettycplx(0,2);
|
||||
prettycplx(2,2);
|
||||
prettycplx(-2,0);
|
||||
prettycplx(0,-2);
|
||||
prettycplx(2,-2);
|
||||
prettycplx(-2,2);
|
||||
prettycplx(-2,-2);
|
||||
|
||||
prettyreal(1.5);
|
||||
prettyreal(1.1);
|
||||
prettyreal(1.1e-100);
|
||||
prettyreal(1.1e20);
|
||||
prettyreal(123456789);
|
||||
prettyreal(1234567890);
|
||||
prettyreal(12345678901);
|
||||
prettyreal(-12345678901);
|
||||
prettyreal(12345678901223);
|
||||
prettyreal(-12345678901223);
|
||||
prettyreal(.02);
|
||||
prettyreal(.002);
|
||||
prettyreal(.0002);
|
||||
prettyreal(-.0002);
|
||||
prettyreal(.00002);
|
||||
prettyreal(-.00002);
|
||||
|
||||
prettyreal(1.0/0);
|
||||
prettyreal(-1.0/0);
|
||||
prettyreal(strtod("nan",NULL));
|
||||
prettyreal(0.0/0);
|
||||
prettyreal(-0.0/0);
|
||||
|
||||
prettyreal(DBL_EPSILON);
|
||||
}
|
||||
|
||||
void test_ios()
|
||||
{
|
||||
ios_t *out = ios_stdout();
|
||||
ios_t *in = ios_stdin();
|
||||
|
||||
ios_putc('a', out);
|
||||
ios_putc('b', out);
|
||||
ios_putc('\n', out);
|
||||
|
||||
char c[80];
|
||||
size_t i=0;
|
||||
ios_t sts;
|
||||
ios_str(&sts, "Test string.");
|
||||
c[i++] = ios_getc(&sts);
|
||||
c[i++] = ios_getc(&sts);
|
||||
c[i++] = ios_getc(&sts);
|
||||
c[i++] = '\0';
|
||||
printf("got: \"%s\"\n", c);
|
||||
|
||||
ios_t ms;
|
||||
ios_mem(&ms, 10);
|
||||
int j;
|
||||
for(j=0; j < 16; j++)
|
||||
ios_puts("passersby were amazed by the ", &ms);
|
||||
size_t bs;
|
||||
char *bigstr = ios_takebuf(&ms, &bs);
|
||||
printf("got: \"%s\" (size %d)\n", bigstr, bs);
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
#include "llt.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
llt_init();
|
||||
|
||||
test_dblprint();
|
||||
test_operators();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void prettycplx(double r, double i)
|
||||
{
|
||||
char str[64];
|
||||
snprint_cplx(str, sizeof(str), r, i, 0, 16, 3, 10, 1);
|
||||
fputs(str, stdout);
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
|
||||
static void prettyreal(double r)
|
||||
{
|
||||
char str[64];
|
||||
snprint_real(str, sizeof(str), r, 0, 16, 3, 10);
|
||||
fputs(str, stdout);
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
|
||||
void test_dblprint()
|
||||
{
|
||||
char str[64];
|
||||
|
||||
dbl_tolerance(1e-12);
|
||||
|
||||
prettycplx(0,0);
|
||||
prettycplx(1,0);
|
||||
prettycplx(0,1);
|
||||
prettycplx(1,1);
|
||||
prettycplx(-1,0);
|
||||
prettycplx(0,-1);
|
||||
prettycplx(1,-1);
|
||||
prettycplx(-1,1);
|
||||
prettycplx(-1,-1);
|
||||
prettycplx(2,0);
|
||||
prettycplx(0,2);
|
||||
prettycplx(2,2);
|
||||
prettycplx(-2,0);
|
||||
prettycplx(0,-2);
|
||||
prettycplx(2,-2);
|
||||
prettycplx(-2,2);
|
||||
prettycplx(-2,-2);
|
||||
|
||||
prettyreal(1.5);
|
||||
prettyreal(1.1);
|
||||
prettyreal(1.1e-100);
|
||||
prettyreal(1.1e20);
|
||||
prettyreal(123456789);
|
||||
prettyreal(1234567890);
|
||||
prettyreal(12345678901);
|
||||
prettyreal(-12345678901);
|
||||
prettyreal(12345678901223);
|
||||
prettyreal(-12345678901223);
|
||||
prettyreal(.02);
|
||||
prettyreal(.002);
|
||||
prettyreal(.0002);
|
||||
prettyreal(-.0002);
|
||||
prettyreal(.00002);
|
||||
prettyreal(-.00002);
|
||||
|
||||
prettyreal(1.0/0);
|
||||
prettyreal(-1.0/0);
|
||||
prettyreal(strtod("nan",NULL));
|
||||
prettyreal(0.0/0);
|
||||
prettyreal(-0.0/0);
|
||||
|
||||
prettyreal(DBL_EPSILON);
|
||||
}
|
69
llt/utils.h
69
llt/utils.h
|
@ -1,79 +1,10 @@
|
|||
#ifndef __UTILS_H_
|
||||
#define __UTILS_H_
|
||||
|
||||
/* these functions byteswap any-size units --------------------- */
|
||||
void bswap(byte_t *s, size_t n);
|
||||
void bswap_to(byte_t *dest, byte_t *src, size_t n);
|
||||
void bswap_buffer(byte_t *data, size_t sz, size_t npts);
|
||||
/* ------------------------------------------------------------- */
|
||||
|
||||
/* reverse the order of elements of any size, in place or out of place */
|
||||
/* n is the number of elements */
|
||||
void memreverse(char *a, size_t n, size_t elsz);
|
||||
void memreverse_to(char *dest, char *a, size_t n, size_t elsz);
|
||||
|
||||
/* swap the contents of two buffers */
|
||||
void memswap(char *a, char *b, size_t sz);
|
||||
|
||||
/* allocating aligned blocks ----------------------------------- */
|
||||
void *malloc_aligned(size_t size, size_t align_size);
|
||||
void free_aligned(void *ptr);
|
||||
void *realloc_aligned(void *ptr, size_t size, size_t align_size);
|
||||
/* ------------------------------------------------------------- */
|
||||
|
||||
int double_exponent(double d);
|
||||
double double_mantissa(double d);
|
||||
int float_exponent(float f);
|
||||
float float_mantissa(float f);
|
||||
void snprint_real(char *s, size_t cnt, double r,
|
||||
int width, // printf field width, or 0
|
||||
int dec, // # decimal digits desired, recommend 16
|
||||
// # of zeros in .00...0x before using scientific notation
|
||||
// recommend 3-4 or so
|
||||
int max_digs_rt,
|
||||
// # of digits left of decimal before scientific notation
|
||||
// recommend 10
|
||||
int max_digs_lf);
|
||||
void snprint_cplx(char *s, size_t cnt, double re, double im,
|
||||
// args to pass on to snprint_real
|
||||
int width, int dec,
|
||||
int max_digs_rt, int max_digs_lf,
|
||||
// print spaces around sign in a+bi
|
||||
int spflag);
|
||||
|
||||
char *uint2str(char *dest, size_t len, uint64_t num, uint32_t base);
|
||||
int str2int(char *str, size_t len, int64_t *res, uint32_t base);
|
||||
int isdigit_base(char c, int base);
|
||||
|
||||
extern double trunc(double x);
|
||||
|
||||
STATIC_INLINE double fpart(double arg)
|
||||
{
|
||||
return arg - trunc(arg);
|
||||
}
|
||||
|
||||
#define ipart(x) trunc(x)
|
||||
|
||||
numerictype_t effective_numerictype(double r);
|
||||
double conv_to_double(void *data, numerictype_t tag);
|
||||
void conv_from_double(void *data, double d, numerictype_t tag);
|
||||
int64_t conv_to_int64(void *data, numerictype_t tag);
|
||||
uint64_t conv_to_uint64(void *data, numerictype_t tag);
|
||||
int32_t conv_to_int32(void *data, numerictype_t tag);
|
||||
uint32_t conv_to_uint32(void *data, numerictype_t tag);
|
||||
#ifdef BITS64
|
||||
#define conv_to_long conv_to_int64
|
||||
#define conv_to_ulong conv_to_uint64
|
||||
#else
|
||||
#define conv_to_long conv_to_int32
|
||||
#define conv_to_ulong conv_to_uint32
|
||||
#endif
|
||||
int cmp_same_lt(void *a, void *b, numerictype_t tag);
|
||||
int cmp_same_eq(void *a, void *b, numerictype_t tag);
|
||||
int cmp_lt(void *a, numerictype_t atag, void *b, numerictype_t btag);
|
||||
int cmp_eq(void *a, numerictype_t atag, void *b, numerictype_t btag,
|
||||
int equalnans);
|
||||
|
||||
#ifdef ARCH_X86_64
|
||||
# define LEGACY_REGS "=Q"
|
||||
#else
|
||||
|
|
|
@ -4,6 +4,13 @@
|
|||
#include "utils.h"
|
||||
#include "ieee754.h"
|
||||
|
||||
extern double trunc(double x);
|
||||
|
||||
STATIC_INLINE double fpart(double arg)
|
||||
{
|
||||
return arg - trunc(arg);
|
||||
}
|
||||
|
||||
// given a number, determine an appropriate type for storing it
|
||||
#if 0
|
||||
numerictype_t effective_numerictype(double r)
|
89
print.c
89
print.c
|
@ -1,3 +1,5 @@
|
|||
#include "ieee754.h"
|
||||
|
||||
extern void *memrchr(const void *s, int c, size_t n);
|
||||
|
||||
static htable_t printconses;
|
||||
|
@ -518,6 +520,93 @@ static void print_string(ios_t *f, char *str, size_t sz)
|
|||
outc('"', f);
|
||||
}
|
||||
|
||||
int double_exponent(double d)
|
||||
{
|
||||
union ieee754_double dl;
|
||||
|
||||
dl.d = d;
|
||||
return dl.ieee.exponent - IEEE754_DOUBLE_BIAS;
|
||||
}
|
||||
|
||||
void snprint_real(char *s, size_t cnt, double r,
|
||||
int width, // printf field width, or 0
|
||||
int dec, // # decimal digits desired, recommend 16
|
||||
// # of zeros in .00...0x before using scientific notation
|
||||
// recommend 3-4 or so
|
||||
int max_digs_rt,
|
||||
// # of digits left of decimal before scientific notation
|
||||
// recommend 10
|
||||
int max_digs_lf)
|
||||
{
|
||||
int mag;
|
||||
double fpart, temp;
|
||||
char format[8];
|
||||
char num_format[3];
|
||||
int sz, keepz=0;
|
||||
|
||||
s[0] = '\0';
|
||||
if (width == -1) {
|
||||
width = 0;
|
||||
keepz=1;
|
||||
}
|
||||
if (isnan(r)) {
|
||||
if (sign_bit(r))
|
||||
strncpy(s, "-nan", cnt);
|
||||
else
|
||||
strncpy(s, "nan", cnt);
|
||||
return;
|
||||
}
|
||||
if (r == 0) {
|
||||
strncpy(s, "0", cnt);
|
||||
return;
|
||||
}
|
||||
|
||||
num_format[0] = 'l';
|
||||
num_format[2] = '\0';
|
||||
|
||||
mag = double_exponent(r);
|
||||
|
||||
mag = (int)(((double)mag)/LOG2_10 + 0.5);
|
||||
if (r == 0)
|
||||
mag = 0;
|
||||
if ((mag > max_digs_lf-1) || (mag < -max_digs_rt)) {
|
||||
num_format[1] = 'e';
|
||||
temp = r/pow(10, mag); /* see if number will have a decimal */
|
||||
fpart = temp - floor(temp); /* when written in scientific notation */
|
||||
}
|
||||
else {
|
||||
num_format[1] = 'f';
|
||||
fpart = r - floor(r);
|
||||
}
|
||||
if (fpart == 0)
|
||||
dec = 0;
|
||||
if (width == 0) {
|
||||
snprintf(format, 8, "%%.%d%s", dec, num_format);
|
||||
}
|
||||
else {
|
||||
snprintf(format, 8, "%%%d.%d%s", width, dec, num_format);
|
||||
}
|
||||
sz = snprintf(s, cnt, format, r);
|
||||
/* trim trailing zeros from fractions. not when using scientific
|
||||
notation, since we might have e.g. 1.2000e+100. also not when we
|
||||
need a specific output width */
|
||||
if (width == 0 && !keepz) {
|
||||
if (sz > 2 && fpart && num_format[1]!='e') {
|
||||
while (s[sz-1] == '0') {
|
||||
s[sz-1]='\0';
|
||||
sz--;
|
||||
}
|
||||
// don't need trailing .
|
||||
if (s[sz-1] == '.') {
|
||||
s[sz-1] = '\0';
|
||||
sz--;
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO. currently 1.1e20 prints as 1.1000000000000000e+20; be able to
|
||||
// get rid of all those zeros.
|
||||
}
|
||||
|
||||
static numerictype_t sym_to_numtype(value_t type);
|
||||
|
||||
// 'weak' means we don't need to accurately reproduce the type, so
|
||||
|
|
Loading…
Reference in New Issue