STRPCT(3)

NAME
strpct, strspct, strpct_r, strsptc_r, strpct_round - decimal percent formatters

LIBRARY
libutil

SYNOPSIS
#include <util.h>
char *
strpct(char *buf, size_t bufsiz, uintmax_t numerator, uintmax_t denominator, size_t precision);
char *
strpct_r(char *buf, size_t bufsiz, uintmax_t numerator, uintmax_t denominator, size_t precision, uint32_t rounding_mode);
char *
strspct(char *buf, size_t bufsiz, intmax_t numerator, intmax_t denominator, size_t precision);
char *
strspct_r(char *buf, size_t bufsiz, intmax_t numerator, intmax_t denominator, size_t precision, uint32_t rounding_mode);
uint32_t
strpct_round(uint32_t mode);

DESCRIPTION
The strpct_r() function formats the fraction represented by numerator and denominator into a percentage representation with the number of fractional digits specified by precision, without using floating point arithmetic.

The result is stored in the buf in which a maximum of bufsiz - 1 meaningful bytes can be stored and is rounded according to the rounding_mode. The current locale's radix character, typically period (‘’). or comma (‘’),, is inserted before the fractional digits if the precision is greater than 0.

The parameter rounding_mode should be one of the following:

STRPCT_RTN
    The result returned will be rounded to the nearest correct value. Actual values exactly mid way between one representable value and the next round away from zero.
STRPCT_RTZ
    Rounding towards 0 (truncating rather than rounding) is used.
STRPCT_RAZ
    Rounding away from 0 (toward the next bigger magnitude) is used.
STRPCT_RTI
    Rounding towards infinity, to a mathematically greater or equal value.
STRPCT_RAI
    Rounding away from infinity, towards negative innfinity, to a mathematically smaller or equal value.

Any other value causes unspecified rounding behaviour.

The strspct_r() function is identical to strpct_r() except uses signed values for the numerator and denominator, and so can return a result with a leading minus sign.

The strpct() and strspct() functions are identical to strpct_r() and strspct_r() respectively, with the rounding_mode specified as STRPCT_RTZ, unless modified by an earlier call to strpct_round().

The strpct_round() function sets the rounding mode used by subsequent calls of strpct() and strspct() to the mode specified, which must be one of those listed as a possible value for the rounding_mode parameter of strpct_r(). Alternatively, the mode may be STRPCT_RQRY, in which case the current rounding mode will not be altered. In any case, the previous rounding mode is returned.

RETURN VALUES
strpct_r(), strspct_r(), strpct() and strspct() always return a pointer to a NUL-terminated (unless bufsiz is 0) formatted string which is placed in buf.

strpct_round() returns the rounding mode that was in use for strpct() and strspct() before the call.

EXAMPLES

    strpct(buf, sizeof(buf), 1, 16, 3);
    ⇒ "6.250"
    strpct(buf, sizeof(buf), 1, 2, 0);
    ⇒ "50"
    strpct_r(buf, sizeof(buf), 2, 3, 2, STRPCT_RTN)
    ⇒ "66.67"
    strpct_r(buf, sizeof(buf), 2, 3, 2, STRPCT_RTZ)
    ⇒ "66.66"

HISTORY
strpct() was originally implemented in csh(1) for NetBSD 1.3. It printed into a static buffer, was not locale aware, handled unsigned long numbers, and printed a “%” at the end of the number. Other programs such as df(1) and time(1) started using it. strpct() and strspct() appeared separately in libutil for NetBSD 6.0.

strpct_r(), strspct_r() and strpct_round() appeared in NetBSD 11.0.

AUTHORS
Erik E. Fair <fair@NetBSD.org> Roland Illig <rillig@NetBSD.org>

BUGS
If the supplied buffer size is insufficient for the result (including a terminating nul (‘\0’) character), the result will be silently truncated with only the most significant digits included, the last of which will be rounded using the requested method. This is not useful. If the buffer space is exhausted part way through a locale's (multi-byte) radix character, even more bizarre behaviour is to be expected. Always provide a buffer bigger than can possibly be needed.

Rather than causing an abnormal process termination, as it arguably should, a denominator specified as zero will be treated as if it were one.

Using STRPCT_RTZ rather than STRPCT_RTN as the default rounding mode for strpct() and strspct() is for compatibility with historic practice, not because it is the most useful mode. That might be changed at some future time.