mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-16 08:09:32 +02:00
120 lines
2.6 KiB
C
120 lines
2.6 KiB
C
/*
|
|
* This file is in the Public Domain
|
|
*
|
|
* Based on code from Public Domain snprintf.c from mutt
|
|
* http://dev.mutt.org/hg/mutt/file/55cd4cb611d9/snprintf.c
|
|
* Tue Aug 08 22:49:12 2006 +0000
|
|
*
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <raptor_config.h>
|
|
#endif
|
|
|
|
#include "raptor.h"
|
|
#include "raptor_internal.h"
|
|
|
|
#include <float.h>
|
|
#define __USE_ISOC99 1
|
|
#include <math.h>
|
|
|
|
#ifndef HAVE_ROUND
|
|
/* round (C99): round x to the nearest integer, away from zero */
|
|
#define round(x) (((x) < 0) ? (long)((x)-0.5) : (long)((x)+0.5))
|
|
#endif
|
|
|
|
#ifndef HAVE_TRUNC
|
|
/* trunc (C99): round x to the nearest integer, towards zero */
|
|
#define trunc(x) (((x) < 0) ? ceil((x)) : floor((x)))
|
|
#endif
|
|
|
|
/* Convert a double to xsd:decimal representation.
|
|
* Returned is a pointer to the first character of the number
|
|
* in buffer (don't free it).
|
|
*/
|
|
char*
|
|
raptor_format_float(char *buffer, size_t *currlen, size_t maxlen,
|
|
double fvalue, unsigned int min, unsigned int max,
|
|
int flags)
|
|
{
|
|
/* DBL_EPSILON = 52 digits */
|
|
#define FRAC_MAX_LEN 52
|
|
|
|
double ufvalue;
|
|
double intpart;
|
|
double fracpart = 0;
|
|
double frac;
|
|
double frac_delta = 10;
|
|
double mod_10;
|
|
size_t exp_len;
|
|
size_t frac_len = 0;
|
|
size_t idx;
|
|
|
|
if (max < min)
|
|
max = min;
|
|
|
|
/* index to the last char */
|
|
idx = maxlen - 1;
|
|
|
|
buffer[idx--] = '\0';
|
|
|
|
ufvalue = fabs (fvalue);
|
|
intpart = round(ufvalue);
|
|
|
|
/* We "cheat" by converting the fractional part to integer by
|
|
* multiplying by a factor of 10
|
|
*/
|
|
|
|
|
|
frac = (ufvalue - intpart);
|
|
|
|
for (exp_len=0; exp_len <= max; ++exp_len) {
|
|
frac *= 10;
|
|
|
|
mod_10 = trunc(fmod(trunc(frac), 10));
|
|
|
|
if (fabs(frac_delta - (fracpart / pow(10, exp_len))) < (DBL_EPSILON * 2.0)) {
|
|
break;
|
|
}
|
|
|
|
frac_delta = fracpart / pow(10, exp_len);
|
|
|
|
/* Only "append" (numerically) if digit is not a zero */
|
|
if (mod_10 > 0 && mod_10 < 10) {
|
|
fracpart = round(frac);
|
|
frac_len = exp_len;
|
|
}
|
|
}
|
|
|
|
if (frac_len < min) {
|
|
buffer[idx--] = '0';
|
|
} else {
|
|
/* Convert/write fractional part (right to left) */
|
|
do {
|
|
mod_10 = fmod(trunc(fracpart), 10);
|
|
--frac_len;
|
|
|
|
buffer[idx--] = "0123456789"[(unsigned)mod_10];
|
|
fracpart /= 10;
|
|
|
|
} while(fracpart > 1 && (frac_len + 1) > 0);
|
|
}
|
|
|
|
buffer[idx--] = '.';
|
|
|
|
/* Convert/write integer part (right to left) */
|
|
do {
|
|
buffer[idx--] = "0123456789"[(int)fmod(intpart, 10)];
|
|
intpart /= 10;
|
|
} while(round(intpart));
|
|
|
|
/* Write a sign, if requested */
|
|
if(fvalue < 0)
|
|
buffer[idx--] = '-';
|
|
else if(flags)
|
|
buffer[idx--] = '+';
|
|
|
|
*currlen = maxlen - idx - 2;
|
|
return buffer + idx + 1;
|
|
}
|