STRPCT(3)

STRPCT(3) | Library Functions Manual | STRPCT(3)

# NAME

`strpct`, `strspct`, `strpct_r`, `strsptc_r`, `strpct_round` — decimal percent formatters

# LIBRARY

System Utilities Library (libutil, -lutil)

# 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.

December 14, 2025 | NetBSD 11.0