mirror of https://github.com/flysand7/ciabatta.git
bad floats for printf
This commit is contained in:
parent
e96c840ce4
commit
8f0bf83f0b
|
@ -1,6 +1,3 @@
|
||||||
[submodule "unicope"]
|
[submodule "unicope"]
|
||||||
path = unicope
|
path = unicope
|
||||||
url = https://github.com/bumbread/unicope.git
|
url = https://github.com/bumbread/unicope.git
|
||||||
[submodule "ryu"]
|
|
||||||
path = ryu
|
|
||||||
url = https://github.com/bumbread/ryu.git
|
|
||||||
|
|
25
bake.py
25
bake.py
|
@ -1,9 +1,29 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
import runpy
|
import runpy
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
for arg in sys.argv[1:]:
|
||||||
|
if arg == 'test':
|
||||||
|
test = os.getenv('test');
|
||||||
|
if test == None:
|
||||||
|
test = 'assert'
|
||||||
|
test_file = 'test/test_' + test + '.c'
|
||||||
|
subprocess.run([
|
||||||
|
'clang',
|
||||||
|
test_file,
|
||||||
|
'-Iinc',
|
||||||
|
'-g',
|
||||||
|
'-luser32',
|
||||||
|
'-lkernel32',
|
||||||
|
'-lshell32',
|
||||||
|
'-lDbghelp',
|
||||||
|
'-lciabatta.lib',
|
||||||
|
])
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
# Build dependencies rq
|
# Build dependencies rq
|
||||||
if not Path("ryu/ryu.lib").exists():
|
if not Path("ryu/ryu.lib").exists():
|
||||||
os.chdir('ryu')
|
os.chdir('ryu')
|
||||||
|
@ -23,7 +43,8 @@ do_cuik = False
|
||||||
|
|
||||||
inc_folders = [
|
inc_folders = [
|
||||||
'inc',
|
'inc',
|
||||||
os.path.join('unicope', 'inc'),
|
'unicope/inc',
|
||||||
|
'ryu',
|
||||||
]
|
]
|
||||||
|
|
||||||
definitions = [
|
definitions = [
|
||||||
|
@ -101,5 +122,5 @@ compile(os.path.normpath('src/code'), compile_map)
|
||||||
for dir, _, f in os.walk('bin'):
|
for dir, _, f in os.walk('bin'):
|
||||||
if len(f) != 0:
|
if len(f) != 0:
|
||||||
obj_paths.append(os.path.join(dir, '*.obj'))
|
obj_paths.append(os.path.join(dir, '*.obj'))
|
||||||
subprocess.run(['llvm-ar', 'rc', 'ciabatta.lib'] + obj_paths)
|
subprocess.run(['lib', '/out:ciabatta.lib'] + obj_paths)
|
||||||
print('*.obj => ciabatta.lib')
|
print('*.obj => ciabatta.lib')
|
|
@ -3,7 +3,11 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include <ryu/ryu.h>
|
||||||
|
|
||||||
typedef int (pfx(cbfn))(void *ctx, ctype ch);
|
typedef int (pfx(cbfn))(void *ctx, ctype ch);
|
||||||
|
|
||||||
|
@ -42,6 +46,24 @@ static inline int pfx(_dtoh)(
|
||||||
int width,
|
int width,
|
||||||
int flags
|
int flags
|
||||||
);
|
);
|
||||||
|
static inline int pfx(_dtoa)(
|
||||||
|
int w,
|
||||||
|
void *ctx,
|
||||||
|
pfx(cbfn) cb,
|
||||||
|
double value,
|
||||||
|
int prec,
|
||||||
|
int width,
|
||||||
|
int flags
|
||||||
|
);
|
||||||
|
static inline int pfx(_etoa)(
|
||||||
|
int w,
|
||||||
|
void *ctx,
|
||||||
|
pfx(cbfn) cb,
|
||||||
|
double value,
|
||||||
|
int prec,
|
||||||
|
int width,
|
||||||
|
int flags
|
||||||
|
);
|
||||||
static inline int pfx(_infnantoa)(
|
static inline int pfx(_infnantoa)(
|
||||||
int w,
|
int w,
|
||||||
void *ctx,
|
void *ctx,
|
||||||
|
@ -229,7 +251,38 @@ static int pfx(vprintfcb)(
|
||||||
case 'F':
|
case 'F':
|
||||||
case 'g':
|
case 'g':
|
||||||
case 'G':
|
case 'G':
|
||||||
|
if(*fmt == 'E' || *fmt == 'F' || *fmt == 'G') flags |= FLAG_UPPER;
|
||||||
|
char conv = tolower(*fmt);
|
||||||
|
++fmt;
|
||||||
|
double value = va_arg(va, double);
|
||||||
|
if(conv == 'f') {
|
||||||
|
w = pfx(_dtoa)(w, ctx, cb, value, prec, width, flags);
|
||||||
|
}
|
||||||
|
else if(conv == 'e') {
|
||||||
|
w = pfx(_etoa)(w, ctx, cb, value, prec, width, flags);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int P = prec;
|
||||||
|
if(!(flags & FLAG_PREC)) P = 6;
|
||||||
|
if(prec == 0) P = 1;
|
||||||
|
union {
|
||||||
|
uint64_t bits;
|
||||||
|
double value;
|
||||||
|
} _ = {.value = value};
|
||||||
|
uint64_t bits = _.bits;
|
||||||
|
int E = (int)((bits >> 52) & 0x7ff) - 1023;
|
||||||
|
int class = fpclassify(value);
|
||||||
|
if(class == FP_SUBNORMAL || class == FP_ZERO) {
|
||||||
|
E = 0;
|
||||||
|
}
|
||||||
|
if(P > E && E >= -4) {
|
||||||
|
w = pfx(_dtoa)(w, ctx, cb, value, P-(E+1), width, flags);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
w = pfx(_etoa)(w, ctx, cb, value, P-1, width, flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(w < 0) return -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -516,4 +569,78 @@ static inline int pfx(_dtoh)(
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int pfx(_dtoa)(
|
||||||
|
int w,
|
||||||
|
void *ctx,
|
||||||
|
pfx(cbfn) cb,
|
||||||
|
double value,
|
||||||
|
int prec,
|
||||||
|
int width,
|
||||||
|
int flags
|
||||||
|
) {
|
||||||
|
int class = fpclassify(value);
|
||||||
|
if(class == FP_INFINITE || class == FP_NAN) {
|
||||||
|
return pfx(_infnantoa)(w, ctx, cb, value, prec, width, flags);
|
||||||
|
}
|
||||||
|
// This guy does memory allocation which makes it pretty cringe
|
||||||
|
if(!(flags & FLAG_PREC)) prec = 6;
|
||||||
|
char *buf = d2fixed(value, prec);
|
||||||
|
int len = (int)strlen(buf);
|
||||||
|
int pad = width - len;
|
||||||
|
// Left pad
|
||||||
|
if(!(flags & FLAG_LEFT) && !(flags & FLAG_ZERO)) while(pad-- > 0) {
|
||||||
|
out(' ');
|
||||||
|
}
|
||||||
|
{
|
||||||
|
char *str = buf;
|
||||||
|
while(*str) {
|
||||||
|
out(*str);
|
||||||
|
++str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
// Right pad
|
||||||
|
if(flags & FLAG_LEFT) while(pad-- > 0) {
|
||||||
|
out(' ');
|
||||||
|
}
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int pfx(_etoa)(
|
||||||
|
int w,
|
||||||
|
void *ctx,
|
||||||
|
pfx(cbfn) cb,
|
||||||
|
double value,
|
||||||
|
int prec,
|
||||||
|
int width,
|
||||||
|
int flags
|
||||||
|
) {
|
||||||
|
int class = fpclassify(value);
|
||||||
|
if(class == FP_INFINITE || class == FP_NAN) {
|
||||||
|
return pfx(_infnantoa)(w, ctx, cb, value, prec, width, flags);
|
||||||
|
}
|
||||||
|
// This guy does memory allocation which makes it pretty cringe
|
||||||
|
if(!(flags & FLAG_PREC)) prec = 6;
|
||||||
|
char *buf = d2exp(value, prec);
|
||||||
|
int len = (int)strlen(buf);
|
||||||
|
int pad = width - len;
|
||||||
|
// Left pad
|
||||||
|
if(!(flags & FLAG_LEFT) && !(flags & FLAG_ZERO)) while(pad-- > 0) {
|
||||||
|
out(' ');
|
||||||
|
}
|
||||||
|
{
|
||||||
|
char *str = buf;
|
||||||
|
while(*str) {
|
||||||
|
out(*str);
|
||||||
|
++str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
// Right pad
|
||||||
|
if(flags & FLAG_LEFT) while(pad-- > 0) {
|
||||||
|
out(' ');
|
||||||
|
}
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
#undef out
|
#undef out
|
||||||
|
|
|
@ -9,9 +9,9 @@ dname = os.path.dirname(abspath)
|
||||||
os.chdir(dname)
|
os.chdir(dname)
|
||||||
|
|
||||||
data=[
|
data=[
|
||||||
('cordic_dataf.c', 'float', 'f', 32),
|
('cordic_dataf.h', 'float', 'f', 32),
|
||||||
('cordic_data.c', 'double', '', 64),
|
('cordic_data.h', 'double', '', 64),
|
||||||
('cordic_datal.c', 'long double', 'l', 64),
|
('cordic_datal.h', 'long double', 'l', 64),
|
||||||
]
|
]
|
||||||
|
|
||||||
for f in data:
|
for f in data:
|
||||||
|
|
|
@ -14,21 +14,21 @@ static double LOG2E = 1.442695040888963407359924681001892;
|
||||||
|
|
||||||
#define ftype float
|
#define ftype float
|
||||||
#define suffix(name) name ## f
|
#define suffix(name) name ## f
|
||||||
#include "cordic/cordic_dataf.c"
|
#include "cordic/cordic_dataf.h"
|
||||||
#include "gen_math.h"
|
#include "gen_math.h"
|
||||||
#undef ftype
|
#undef ftype
|
||||||
#undef suffix
|
#undef suffix
|
||||||
|
|
||||||
#define ftype double
|
#define ftype double
|
||||||
#define suffix(name) name
|
#define suffix(name) name
|
||||||
#include "cordic/cordic_data.c"
|
#include "cordic/cordic_data.h"
|
||||||
#include "gen_math.h"
|
#include "gen_math.h"
|
||||||
#undef ftype
|
#undef ftype
|
||||||
#undef suffix
|
#undef suffix
|
||||||
|
|
||||||
#define ftype long double
|
#define ftype long double
|
||||||
#define suffix(name) name ## l
|
#define suffix(name) name ## l
|
||||||
#include "cordic/cordic_datal.c"
|
#include "cordic/cordic_datal.h"
|
||||||
#include "gen_math.h"
|
#include "gen_math.h"
|
||||||
#undef ftype
|
#undef ftype
|
||||||
#undef suffix
|
#undef suffix
|
||||||
|
|
|
@ -64,7 +64,8 @@ void free(void *ptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void *malloc(size_t size) {
|
void *malloc(size_t size) {
|
||||||
return aligned_alloc(8, size);
|
if(size == 0) return NULL;
|
||||||
|
return HeapAlloc(heap_handle, 0, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *realloc(void *ptr, size_t size) {
|
void *realloc(void *ptr, size_t size) {
|
||||||
|
|
|
@ -4,14 +4,7 @@
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
printf("%a\n", 0.0);
|
printf("%g\n", 1.2345e+10);
|
||||||
printf("%a\n", 2.0);
|
printf("%g\n", 123.45);
|
||||||
printf("%#a\n", 128.0);
|
|
||||||
printf("%a\n", 128.0);
|
|
||||||
printf("%16a|\n", 128.0);
|
|
||||||
printf("%16.2a|\n", 128.0);
|
|
||||||
printf("%-16.2a|\n", 128.0);
|
|
||||||
printf("%016.2a|\n", 128.0);
|
|
||||||
printf("%.2A\n", 3.141592);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
8
todo
8
todo
|
@ -31,15 +31,21 @@ stdio.h:
|
||||||
* The only reason to keep a linked list of all streams is to make sure they
|
* The only reason to keep a linked list of all streams is to make sure they
|
||||||
are flushed after main() returns. I wonder if only remembering the files
|
are flushed after main() returns. I wonder if only remembering the files
|
||||||
with a buffer would increase performance.
|
with a buffer would increase performance.
|
||||||
* Formatted print, scan
|
* Formatted scan
|
||||||
|
* The float printing should include width specifiers
|
||||||
|
* %g should use decimal exponent
|
||||||
|
|
||||||
stdlib.h:
|
stdlib.h:
|
||||||
* Strtod base 16 must be correctly rounded
|
* Strtod base 16 must be correctly rounded
|
||||||
* Multibyte string functions
|
* Multibyte string functions
|
||||||
* Better PRNG
|
* Better PRNG
|
||||||
|
* Fix aligned_malloc
|
||||||
|
|
||||||
threads.h:
|
threads.h:
|
||||||
* TODO: add todo items
|
* TODO: add todo items
|
||||||
|
|
||||||
wchar.h:
|
wchar.h:
|
||||||
* Basically everything
|
* Basically everything
|
||||||
|
|
||||||
|
entry:
|
||||||
|
* Pretty sure there is a bug in counting wide chars for parsing argv
|
||||||
|
|
Loading…
Reference in New Issue