Add custom div functions
This commit is contained in:
parent
60245f9da0
commit
a3c69113f4
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
all: test
|
||||
|
||||
test: test.c uprintf.c uprintf.h
|
||||
gcc -std=c89 -Os -o test test.c uprintf.c
|
||||
gcc -std=c89 -Os -DUPRINTF_CUSTOM_DIV_FUNC -o test test.c uprintf.c idiv.c
|
||||
|
||||
clean:
|
||||
rm -rf test
|
||||
|
||||
83
idiv.c
Normal file
83
idiv.c
Normal file
@ -0,0 +1,83 @@
|
||||
#include <stdint.h>
|
||||
#include "idiv.h"
|
||||
|
||||
#define _IDIV_UU(_INT_WIDTH_) \
|
||||
uint ## _INT_WIDTH_ ## _t idiv ## _INT_WIDTH_ ## _uu( \
|
||||
uint ## _INT_WIDTH_ ## _t n, \
|
||||
uint ## _INT_WIDTH_ ## _t d, \
|
||||
uint ## _INT_WIDTH_ ## _t *rp) \
|
||||
{ \
|
||||
uint ## _INT_WIDTH_ ## _t q = 0, r = 0; \
|
||||
int i; \
|
||||
if (d == 0) { \
|
||||
if (rp) *rp = 0; \
|
||||
return 0; \
|
||||
} \
|
||||
for (i = _INT_WIDTH_-1; i >= 0; i --) { \
|
||||
r <<= 1; \
|
||||
q <<= 1; \
|
||||
r |= (n & (1ull << (_INT_WIDTH_-1))) ? 1 : 0; \
|
||||
if (r >= d) { \
|
||||
r -= d; \
|
||||
q |= 1; \
|
||||
} \
|
||||
n <<= 1; \
|
||||
} \
|
||||
if (rp) *rp = r; \
|
||||
return q; \
|
||||
}
|
||||
|
||||
|
||||
#define _IDIV_II(_INT_WIDTH_) \
|
||||
int ## _INT_WIDTH_ ## _t idiv ## _INT_WIDTH_ ## _ii( \
|
||||
int ## _INT_WIDTH_ ## _t n, \
|
||||
int ## _INT_WIDTH_ ## _t d, \
|
||||
int ## _INT_WIDTH_ ## _t *rp) \
|
||||
{ \
|
||||
uint ## _INT_WIDTH_ ## _t qu = 0, ru = 0, nu, du; \
|
||||
int qneg = (n >= 0 && d < 0) | (n < 0 && d >= 0); \
|
||||
int rneg = (n < 0); \
|
||||
nu = (n < 0) ? -n : n; \
|
||||
du = (d < 0) ? -d : d; \
|
||||
qu = idiv ## _INT_WIDTH_ ## _uu(nu, du, &ru); \
|
||||
if (rp) *rp = rneg ? -ru : ru; \
|
||||
return qneg ? -qu : qu; \
|
||||
}
|
||||
|
||||
#define _IDIV_UI(_INT_WIDTH_) \
|
||||
int ## _INT_WIDTH_ ## _t idiv ## _INT_WIDTH_ ## _ui( \
|
||||
uint ## _INT_WIDTH_ ## _t n, \
|
||||
int ## _INT_WIDTH_ ## _t d, \
|
||||
uint ## _INT_WIDTH_ ## _t *rp) \
|
||||
{ \
|
||||
uint ## _INT_WIDTH_ ## _t qu = 0, ru = 0, du; \
|
||||
int qneg = (d < 0); \
|
||||
du = (d < 0) ? -d : d; \
|
||||
qu = idiv ## _INT_WIDTH_ ## _uu(n, du, &ru); \
|
||||
if (rp) *rp = ru; \
|
||||
return qneg ? -qu : qu; \
|
||||
}
|
||||
|
||||
#define _IDIV_IU(_INT_WIDTH_) \
|
||||
int ## _INT_WIDTH_ ## _t idiv ## _INT_WIDTH_ ## _iu( \
|
||||
int ## _INT_WIDTH_ ## _t n, \
|
||||
uint ## _INT_WIDTH_ ## _t d, \
|
||||
int ## _INT_WIDTH_ ## _t *rp) \
|
||||
{ \
|
||||
uint ## _INT_WIDTH_ ## _t qu = 0, ru = 0, nu; \
|
||||
int neg = (n < 0); \
|
||||
nu = (n < 0) ? -n : n; \
|
||||
qu = idiv ## _INT_WIDTH_ ## _uu(nu, d, &ru); \
|
||||
if (rp) *rp = neg ? -ru : ru; \
|
||||
return neg ? -qu : qu; \
|
||||
}
|
||||
|
||||
_IDIV_UU(32)
|
||||
_IDIV_II(32)
|
||||
_IDIV_UI(32)
|
||||
_IDIV_IU(32)
|
||||
|
||||
_IDIV_UU(64)
|
||||
_IDIV_II(64)
|
||||
_IDIV_UI(64)
|
||||
_IDIV_IU(64)
|
||||
16
idiv.h
Normal file
16
idiv.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef _IDIV_H_
|
||||
#define _IDIV_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint32_t idiv32_uu(uint32_t n, uint32_t d, uint32_t *rp);
|
||||
int32_t idiv32_ii(int32_t n, int32_t d, int32_t *rp);
|
||||
int32_t idiv32_ui(uint32_t n, int32_t d, uint32_t *rp);
|
||||
int32_t idiv32_iu(int32_t n, uint32_t d, int32_t *rp);
|
||||
|
||||
uint64_t idiv64_uu(uint64_t n, uint64_t d, uint64_t *rp);
|
||||
int64_t idiv64_ii(int64_t n, int64_t d, int64_t *rp);
|
||||
int64_t idiv64_ui(uint64_t n, int64_t d, uint64_t *rp);
|
||||
int64_t idiv64_iu(int64_t n, uint64_t d, int64_t *rp);
|
||||
|
||||
#endif
|
||||
2
test.c
2
test.c
@ -20,6 +20,8 @@ int main(void)
|
||||
p("7: |%*s|\n", 5, "s");
|
||||
p("8: |%'-*s|\n", -5, "s");
|
||||
|
||||
p("9: |%016ulx|\n", 0x55555555AAAAAAAAll);
|
||||
|
||||
/* TODO more tests */
|
||||
|
||||
return 0;
|
||||
|
||||
13
uprintf.c
13
uprintf.c
@ -2,6 +2,10 @@
|
||||
#include <stdarg.h>
|
||||
#include "uprintf.h"
|
||||
|
||||
#ifdef UPRINTF_CUSTOM_DIV_FUNC
|
||||
#include "idiv.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ------------------- Простая замена printf ------------------------
|
||||
*
|
||||
@ -97,8 +101,15 @@ static void print_decimal(put_char_func pc, uint64_t u, int negative, unsigned i
|
||||
s[si--] = 0;
|
||||
|
||||
do {
|
||||
int l = (int)(u % base);
|
||||
uint64_t l;
|
||||
|
||||
#ifdef UPRINTF_CUSTOM_DIV_FUNC
|
||||
u = idiv64_uu(u, (uint64_t)base, &l);
|
||||
#else
|
||||
l = u % base;
|
||||
u = u / base;
|
||||
#endif
|
||||
|
||||
s[si--] = abet[lcase][l];
|
||||
} while (u > 0);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user