b70fecf21d
Wanted to see how gnarly it is to do. Big number handling could be done with better algorithms since it can get a bit slow with large integers or tiny fractions with many lead zeros when only a few digits are needed. Anyway, it supports %e, %E, %f, %F, %g and %G. No %a or long double support seems warranted at the moment. Assumes IEEE 754 double format but it's laid out to be able to replace a function to handle others if needed. Tested in a driver program that has a duplicate vuprintf and the content was pasted in once it looked sound enough to put up a patch. Change-Id: I6dae8624d3208e644c88e36e6a17d8fc9144f988
59 lines
2.1 KiB
C
59 lines
2.1 KiB
C
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
* $Id$
|
|
*
|
|
* Copyright (C) 2018 by Michael A. Sevakis
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
****************************************************************************/
|
|
#ifndef AP_INT_H
|
|
#define AP_INT_H
|
|
|
|
/* Miscellaneous large-sized integer functions */
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
/* return floor(log(2)*base2exp) - assists in estimating buffer sizes
|
|
* when converting to decimal */
|
|
static inline int base10exp(int base2exp)
|
|
{
|
|
/* 1292913986 = floor(2^32*log(2)) */
|
|
static const long log10of2 = 1292913986L;
|
|
return log10of2 * (int64_t)base2exp >> 32;
|
|
}
|
|
|
|
struct ap_int
|
|
{
|
|
long numchunks; /* number of uint32_t chunks or zero */
|
|
long basechunk; /* chunk of start of value bits */
|
|
uint32_t *chunks; /* pointer to chunk array (caller alloced) */
|
|
long len; /* length of output */
|
|
long shift; /* number of fractional bits */
|
|
uint64_t val; /* value, if it fits and numchunks is zero */
|
|
};
|
|
|
|
bool round_number_string10(char *p_rdig, long len);
|
|
|
|
/* format arbitrary-precision base 10 integer */
|
|
char * format_ap_int10(struct ap_int *a,
|
|
char *p_end);
|
|
|
|
/* format arbitrary-precision base 10 fraction */
|
|
char * format_ap_frac10(struct ap_int *a,
|
|
char *p_start,
|
|
long precision);
|
|
|
|
#endif /* AP_INT_H */
|