Since we're using floating point values at several places in the kernel, I added
a very simplistic floating point output routine to snprintf() and friends, for your convenience. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19583 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
d6edf65b05
commit
dedf1bccfe
@ -16,6 +16,17 @@
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#define ZEROPAD 1 /* pad with zero */
|
||||
#define SIGN 2 /* unsigned/signed long */
|
||||
#define PLUS 4 /* show plus */
|
||||
#define SPACE 8 /* space if plus */
|
||||
#define LEFT 16 /* left justified */
|
||||
#define SPECIAL 32 /* 0x */
|
||||
#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
|
||||
|
||||
#define FLOATING_SUPPORT
|
||||
|
||||
|
||||
static int
|
||||
skip_atoi(const char **s)
|
||||
{
|
||||
@ -28,15 +39,6 @@ skip_atoi(const char **s)
|
||||
}
|
||||
|
||||
|
||||
#define ZEROPAD 1 /* pad with zero */
|
||||
#define SIGN 2 /* unsigned/signed long */
|
||||
#define PLUS 4 /* show plus */
|
||||
#define SPACE 8 /* space if plus */
|
||||
#define LEFT 16 /* left justified */
|
||||
#define SPECIAL 32 /* 0x */
|
||||
#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
|
||||
|
||||
|
||||
static uint64
|
||||
do_div(uint64 *_number, uint32 base)
|
||||
{
|
||||
@ -204,6 +206,68 @@ number(char **_string, int32 *_bytesLeft, int64 num, uint32 base, int size,
|
||||
}
|
||||
|
||||
|
||||
#ifdef FLOATING_SUPPORT
|
||||
/*!
|
||||
This is a very basic floating point to string conversion routine.
|
||||
It prints up to 3 fraction digits, and doesn't support any precision arguments.
|
||||
It's just here for your convenience so that you can use it for debug output.
|
||||
*/
|
||||
static bool
|
||||
floating(char **_string, int32 *_bytesLeft, double value, int fieldWidth, int flags)
|
||||
{
|
||||
char buffer[66];
|
||||
bool sign = value < 0.0;
|
||||
uint64 fraction;
|
||||
uint64 integer;
|
||||
int32 length = 0;
|
||||
|
||||
if (sign)
|
||||
value = -value;
|
||||
|
||||
fraction = (uint64)(value * 1000) % 1000;
|
||||
integer = (uint64)value;
|
||||
|
||||
// put fraction part, if any
|
||||
|
||||
if (fraction != 0) {
|
||||
bool first = true;
|
||||
while (fraction != 0) {
|
||||
int digit = do_div(&fraction, 10);
|
||||
if (!first || digit > 0) {
|
||||
buffer[length++] = '0' + digit;
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
buffer[length++] = '.';
|
||||
}
|
||||
|
||||
// put integer part
|
||||
|
||||
if (integer == 0)
|
||||
buffer[length++] = '0';
|
||||
else while (integer != 0) {
|
||||
buffer[length++] = '0' + do_div(&integer, 10);
|
||||
}
|
||||
|
||||
// write back to string
|
||||
|
||||
if (!(flags & LEFT) && !put_padding(_string, _bytesLeft, fieldWidth))
|
||||
return false;
|
||||
|
||||
while (length-- > 0) {
|
||||
if (!put_character(_string, _bytesLeft, buffer[length]))
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((flags & LEFT) != 0 && !put_padding(_string, _bytesLeft, fieldWidth))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif // FLOATING_SUPPORT
|
||||
|
||||
|
||||
int
|
||||
vsnprintf(char *buffer, size_t bufferSize, const char *format, va_list args)
|
||||
{
|
||||
@ -327,6 +391,19 @@ vsnprintf(char *buffer, size_t bufferSize, const char *format, va_list args)
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef FLOATING_SUPPORT
|
||||
case 'f':
|
||||
case 'F':
|
||||
case 'g':
|
||||
case 'G':
|
||||
{
|
||||
double value = va_arg(args, double);
|
||||
if (!floating(&string, &bytesLeft, value, flags, fieldWidth))
|
||||
goto out;
|
||||
continue;
|
||||
}
|
||||
#endif // FLOATING_SUPPORT
|
||||
|
||||
case 'p':
|
||||
if (fieldWidth == -1) {
|
||||
fieldWidth = 2*sizeof(void *);
|
||||
|
Loading…
Reference in New Issue
Block a user