strpct.3 revision 1.8
$NetBSD: strpct.3,v 1.8 2025/12/14 16:28:05 kre Exp $

Copyright (c) 2011 The NetBSD Foundation, Inc.
All rights reserved.

This file was contributed to The NetBSD Foundation by Christos Zoulas.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

.Dd December 14, 2025 .Dt STRPCT 3 .Os .Sh NAME .Nm strpct , .Nm strspct , .Nm strpct_r , .Nm strsptc_r , .Nm strpct_round .Nd decimal percent formatters .Sh LIBRARY .Lb libutil .Sh SYNOPSIS n util.h .Ft char * .Fn strpct "char *buf" "size_t bufsiz" "uintmax_t numerator" "uintmax_t denominator" "size_t precision" .Ft char * .Fn strpct_r "char *buf" "size_t bufsiz" "uintmax_t numerator" "uintmax_t denominator" "size_t precision" "uint32_t rounding_mode" .Ft char * .Fn strspct "char *buf" "size_t bufsiz" "intmax_t numerator" "intmax_t denominator" "size_t precision" .Ft char * .Fn strspct_r "char *buf" "size_t bufsiz" "intmax_t numerator" "intmax_t denominator" "size_t precision" "uint32_t rounding_mode" .Ft uint32_t .Fn strpct_round "uint32_t mode" .Sh DESCRIPTION The .Fn strpct_r function formats the fraction represented by .Fa numerator and .Fa denominator into a percentage representation with the number of fractional digits specified by .Fa precision , without using floating point arithmetic.

p The result is stored in the .Fa buf in which a maximum of .Fa bufsiz - 1 meaningful bytes can be stored and is rounded according to the .Fa rounding_mode . The current locale's radix character, typically period

q Sq . or comma

q Sq , , is inserted before the fractional digits if the .Fa precision is greater than 0.

p The parameter .Fa rounding_mode should be one of the following:

p l -tag -width 12n -compact t Dv 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. t Dv STRPCT_RTZ Rounding towards 0 (truncating rather than rounding) is used. t Dv STRPCT_RAZ Rounding away from 0 (toward the next bigger magnitude) is used. t Dv STRPCT_RTI Rounding towards infinity, to a mathematically greater or equal value. t Dv STRPCT_RAI Rounding away from infinity, towards negative innfinity, to a mathematically smaller or equal value. .El

p Any other value causes unspecified rounding behaviour.

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

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

p The .Fn strpct_round function sets the rounding mode used by subsequent calls of .Fn strpct and .Fn strspct to the .Fa mode specified, which must be one of those listed as a possible value for the .Fa rounding_mode parameter of .Fn strpct_r . Alternatively, the .Fa mode may be .Dv STRPCT_RQRY , in which case the current rounding mode will not be altered. In any case, the previous rounding mode is returned. .Sh RETURN VALUES .Fn strpct_r , .Fn strspct_r , .Fn strpct and .Fn strspct always return a pointer to a NUL-terminated (unless .Fa bufsiz is .Dv 0 ) formatted string which is placed in .Fa buf .

p .Fn strpct_round returns the rounding mode that was in use for .Fn strpct and .Fn strspct before the call. .Sh EXAMPLES d -literal -offset indent strpct(buf, sizeof(buf), 1, 16, 3); \(rA "6.250" strpct(buf, sizeof(buf), 1, 2, 0); \(rA "50" strpct_r(buf, sizeof(buf), 2, 3, 2, STRPCT_RTN) \(rA "66.67" strpct_r(buf, sizeof(buf), 2, 3, 2, STRPCT_RTZ) \(rA "66.66" .Ed .Sh HISTORY .Fn strpct was originally implemented in .Xr csh 1 for .Nx 1.3 . It printed into a static buffer, was not locale aware, handled .Ft unsigned long numbers, and printed a .Dq % at the end of the number. Other programs such as .Xr df 1 and .Xr time 1 started using it. .Fn strpct and .Fn strspct appeared separately in libutil for .Nx 6.0 .

p .Fn strpct_r , .Fn strspct_r and .Fn strpct_round appeared in .Nx 11.0 . .Sh AUTHORS .An Erik E. Fair Aq Mt fair@NetBSD.org .An Roland Illig Aq Mt rillig@NetBSD.org .Sh BUGS If the supplied buffer size is insufficient for the result (including a terminating nul

q Sq \e0 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.

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

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