moving some flisp-specific code out of library

This commit is contained in:
Jeff Bezanson 2012-02-17 23:59:45 -05:00
parent 689ec946d8
commit 6ed61e66ac
14 changed files with 129 additions and 830 deletions

View File

@ -1,3 +1,5 @@
#include "operators.c"
#ifdef BITS64
#define NWORDS(sz) (((sz)+7)>>3)
#else

28
flisp.h
View File

@ -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;

View File

@ -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)

View File

@ -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];
}
}
}

View File

@ -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");
}
}
}

View File

@ -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.
}

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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
View File

@ -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