Skip to content

Commit

Permalink
Add conditional compilation for engineering type
Browse files Browse the repository at this point in the history
  • Loading branch information
MaJerle committed Sep 1, 2020
1 parent 9ef71fc commit af05d80
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 4 deletions.
1 change: 1 addition & 0 deletions dev/VisualStudio/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ main(void) {
printf_run(NULL, "%022.4e", 123.456);
printf_run(NULL, "%022.4e", -123.456);
printf_run(NULL, "%022.4e", 0.123456);
printf_run(NULL, "%e", 0.00000000123456);
printf_run(NULL, "%022.4e", -0.123456);

/* Add zeros if unused... tbd */
Expand Down
10 changes: 10 additions & 0 deletions lwprintf/src/include/lwprintf/lwprintf_opt.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,16 @@ extern "C" {
#define LWPRINTF_CFG_SUPPORT_TYPE_FLOAT 1
#endif

/**
* \brief Enables `1` or disables `0` support `%%e` engineering output type for float numbers
*
* \note \ref LWPRINTF_CFG_SUPPORT_TYPE_FLOAT has to be enabled to use this feature
*
*/
#ifndef LWPRINTF_CFG_SUPPORT_TYPE_ENGINNERING
#define LWPRINTF_CFG_SUPPORT_TYPE_ENGINNERING 1
#endif

/**
* \brief Specifies default number of precision for float number
*
Expand Down
24 changes: 20 additions & 4 deletions lwprintf/src/lwprintf/lwprintf.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@
#include "system/lwprintf_sys.h"
#endif /* LWPRINTF_CFG_OS */

/* Static checks */
#if LWPRINTF_CFG_SUPPORT_TYPE_ENGINNERING && !LWPRINTF_CFG_SUPPORT_TYPE_FLOAT
#error "Cannot use engineering type without float!"
#endif /* */

#define CHARISNUM(x) ((x) >= '0' && (x) <= '9')
#define CHARTONUM(x) ((x) - '0')

Expand Down Expand Up @@ -477,17 +482,21 @@ prv_double_to_str(lwprintf_int_t* p, double num) {
#else
long integer_part, decimal_part, tmp;
char str[11];
#endif
#endif /* LWPRINTF_CFG_SUPPORT_LONG_LONG */
double decimal_part_dbl, diff;
size_t i;
int digits_cnt, exp_cnt;
int digits_cnt;
#if LWPRINTF_CFG_SUPPORT_TYPE_ENGINNERING
int exp_cnt;
#endif /* LWPRINTF_CFG_SUPPORT_TYPE_ENGINNERING */

#if LWPRINTF_CFG_SUPPORT_LONG_LONG
/* Powers of 10 from beginning up to precision level */
static const long long int powers_of_10[] = { 1E00, 1E01, 1E02, 1E03, 1E04, 1E05, 1E06, 1E07, 1E08, 1E09,
1E10, 1E11, 1E12, 1E13, 1E14, 1E15, 1E16, 1E17, 1E18};
#endif

#if LWPRINTF_CFG_SUPPORT_TYPE_ENGINNERING
/* Engineering mode */
if (p->m.type == 'e') {
/* Check negative status */
Expand All @@ -503,6 +512,7 @@ prv_double_to_str(lwprintf_int_t* p, double num) {
for (exp_cnt = 0; num >= 10; num /= 10, ++exp_cnt) {}
}
}
#endif /* LWPRINTF_CFG_SUPPORT_TYPE_ENGINNERING */

/* Check for corner cases */
if (num != num) {
Expand Down Expand Up @@ -571,11 +581,13 @@ prv_double_to_str(lwprintf_int_t* p, double num) {
digits_cnt += p->m.precision + 1;
}

/* Engineering mode */
#if LWPRINTF_CFG_SUPPORT_TYPE_ENGINNERING
/* Increase number of digits to display */
if (p->m.type == 'e') {
/* Format is +Exxx, so add 4 or 5 characters (max is 307, min is 00 for exponent) */
digits_cnt += 4 + (exp_cnt >= 100 || exp_cnt <= -100);
}
#endif /* LWPRINTF_CFG_SUPPORT_TYPE_ENGINNERING */

/* Output strings */
prv_out_str_before(p, digits_cnt);
Expand Down Expand Up @@ -605,6 +617,7 @@ prv_double_to_str(lwprintf_int_t* p, double num) {
}
}

#if LWPRINTF_CFG_SUPPORT_TYPE_ENGINNERING
/* Engineering mode */
if (p->m.type == 'e') {
p->out_fn(p, p->m.flags.uc ? 'E' : 'e');
Expand All @@ -619,6 +632,7 @@ prv_double_to_str(lwprintf_int_t* p, double num) {
p->out_fn(p, '0' + (char)(exp_cnt / 10));
p->out_fn(p, '0' + (char)(exp_cnt % 10));
}
#endif /* LWPRINTF_CFG_SUPPORT_TYPE_ENGINNERING */
prv_out_str_after(p, digits_cnt);

return 1;
Expand Down Expand Up @@ -868,18 +882,20 @@ prv_format(lwprintf_int_t* p, va_list arg) {
/* Double number */
prv_double_to_str(p, (double)va_arg(arg, double));
break;
#if LWPRINTF_CFG_SUPPORT_TYPE_ENGINNERING
case 'e':
case 'g': /* Not yet supported properly */
/* Double number in engineering format */
prv_double_to_str(p, (double)va_arg(arg, double));
break;
#endif /* LWPRINTF_CFG_SUPPORT_TYPE_ENGINNERING */
#endif /* LWPRINTF_CFG_SUPPORT_TYPE_FLOAT */
case 'n': {
int* ptr = (void*)va_arg(arg, int*);
*ptr = p->n; /* Write current length */

break;
}
#endif /* LWPRINTF_CFG_SUPPORT_TYPE_FLOAT */
case '%':
p->out_fn(p, '%');
break;
Expand Down

0 comments on commit af05d80

Please sign in to comment.