aboutsummaryrefslogtreecommitdiff
path: root/share/man/man3/qmath.3
blob: 5c2332f0bc5520ae473e7f29e0badbde2e523cc5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
.\"
.\" Copyright (c) 2018 Netflix, Inc.
.\" All rights reserved.
.\"
.\" 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,
.\"    without modification, immediately at the beginning of the file.
.\" 2. The name of the author may not be used to endorse or promote products
.\"    derived from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 July 4, 2019
.Dt QMATH 3
.Os
.Sh NAME
.Nm qmath
.Nd fixed-point math library based on the
.Dq Q
number format
.Sh SYNOPSIS
.In sys/qmath.h
.Sh DESCRIPTION
The
.Nm
data types and APIs support fixed-point math based on the
.Dq Q
number format.
The APIs have been built around the following data types:
.Vt s8q_t ,
.Vt u8q_t ,
.Vt s16q_t ,
.Vt u16q_t ,
.Vt s32q_t ,
.Vt u32q_t ,
.Vt s64q_t ,
and
.Vt u64q_t ,
which are referred to generically in the earlier API definitions as
.Fa QTYPE .
The
.Fa ITYPE
refers to the
.Xr stdint 7
integer types.
.Fa NTYPE
is used to refer to any numeric type and is therefore a superset of
.Fa QTYPE
and
.Fa ITYPE .
.Pp
This scheme can represent Q numbers with
.Bq 2, 4, 6, 8, 16, 32, 48
bits of precision after the binary radix point,
depending on the
.Fa rpshft
argument to
.Fn Q_INI .
The number of bits available for the integral component is not explicitly
specified, and implicitly consumes the remaining available bits of the chosen Q
data type.
.Pp
Operations on Q numbers maintain the precision of their arguments.
The fractional component is truncated to fit into the destination,
with no rounding.
None of the operations is affected by the floating-point environment.
.Pp
For more details, see the
.Sx IMPLEMENTATION DETAILS
below.
.Sh LIST OF FUNCTIONS
.de Cl
.Bl -column "isgreaterequal" "bessel function of the second kind of the order 0"
.Em "Name	Description"
..
.Ss Functions which create/initialise a Q number
.Cl
.Xr Q_INI 3	initialise a Q number
.El
.Ss Numeric functions which operate on two Q numbers
.Cl
.Xr Q_QADDQ 3	addition
.Xr Q_QDIVQ 3	division
.Xr Q_QMULQ 3	multiplication
.Xr Q_QSUBQ 3	subtraction
.Xr Q_NORMPREC 3	normalisation
.Xr Q_QMAXQ 3	maximum function
.Xr Q_QMINQ 3	minimum function
.Xr Q_QCLONEQ 3	identical copy
.Xr Q_QCPYVALQ 3	representational copy
.El
.Ss Numeric functions which apply integers to a Q number
.Cl
.Xr Q_QADDI 3	addition
.Xr Q_QDIVI 3	division
.Xr Q_QMULI 3	multiplication
.Xr Q_QSUBI 3	subtraction
.Xr Q_QFRACI 3	fraction
.Xr Q_QCPYVALI 3	overwrite
.El
.Ss Numeric functions which operate on a single Q number
.Cl
.Xr Q_QABS 3	absolute value
.Xr Q_Q2D 3	double representation
.Xr Q_Q2F 3	float representation
.El
.Ss Comparison and logic functions
.Cl
.Xr Q_SIGNED 3	determine sign
.Xr Q_LTZ 3	less than zero
.Xr Q_PRECEQ 3	compare bits
.Xr Q_QLTQ 3	less than
.Xr Q_QLEQ 3	less or equal
.Xr Q_QGTQ 3	greater than
.Xr Q_QGEQ 3	greater or equal
.Xr Q_QEQ 3	equal
.Xr Q_QNEQ 3	not equal
.Xr Q_OFLOW 3	would overflow
.Xr Q_RELPREC 3	relative precision
.El
.Ss Functions which manipulate the control/sign data bits
.Cl
.Xr Q_SIGNSHFT 3	sign bit position
.Xr Q_SSIGN 3	sign bit
.Xr Q_CRAWMASK 3	control bitmask
.Xr Q_SRAWMASK 3	sign bitmask
.Xr Q_GCRAW 3	raw control bits
.Xr Q_GCVAL 3	value of control bits
.Xr Q_SCVAL 3	set control bits
.El
.Ss Functions which manipulate the combined integer/fractional data bits
.Cl
.Xr Q_IFRAWMASK 3	integer/fractional bitmask
.Xr Q_IFVALIMASK 3	value of integer bits
.Xr Q_IFVALFMASK 3	value of fractional bits
.Xr Q_GIFRAW 3	raw integer/fractional bits
.Xr Q_GIFABSVAL 3	absolute value of fractional bits
.Xr Q_GIFVAL 3	real value of fractional bits
.Xr Q_SIFVAL 3	set integer/fractional bits
.Xr Q_SIFVALS 3	set separate integer/fractional values
.El
.Ss Functions which manipulate the integer data bits
.Cl
.Xr Q_IRAWMASK 3	integer bitmask
.Xr Q_GIRAW 3	raw integer bits
.Xr Q_GIABSVAL 3	absolute value of integer bits
.Xr Q_GIVAL 3	real value of integer bits
.Xr Q_SIVAL 3	set integer bits
.El
.Ss Functions which manipulate the fractional data bits
.Cl
.Xr Q_FRAWMASK 3	fractional bitmask
.Xr Q_GFRAW 3	raw fractional bits
.Xr Q_GFABSVAL 3	absolute value of fractional bits
.Xr Q_GFVAL 3	real value of fractional bits
.Xr Q_SFVAL 3	set fractional bits
.El
.Ss Miscellaneous functions/variables
.Cl
.Xr Q_NCBITS 3	number of reserved control bits
.Xr Q_BT 3	C data type
.Xr Q_TC 3	casted data type
.Xr Q_NTBITS 3	number of total bits
.Xr Q_NFCBITS 3	number of control-encoded fractional bits
.Xr Q_MAXNFBITS 3	number of maximum fractional bits
.Xr Q_NFBITS 3	number of effective fractional bits
.Xr Q_NIBITS 3	number of integer bits
.Xr Q_RPSHFT 3	bit position of radix point
.Xr Q_ABS 3	absolute value
.Xr Q_MAXSTRLEN 3	number of characters to render string
.Xr Q_TOSTR 3	render string
.Xr Q_SHL 3	left-shifted value
.Xr Q_SHR 3	right-shifted value
.Xr Q_DEBUG 3	render debugging information
.Xr Q_DFV2BFV 3	convert decimal fractional value
.El
.Sh IMPLEMENTATION DETAILS
The
.Nm
data types and APIs support fixed-point math based on the
.Dq Q
number format.
This implementation uses the Q notation
.Em Qm.n ,
where
.Em m
specifies the number of bits for integral data
.Pq excluding the sign bit for signed types ,
and
.Em n
specifies the number of bits for fractional data.
.Pp
The APIs have been built around the following q_t derived data types:
.Bd -literal -offset indent
typedef int8_t		s8q_t;
typedef uint8_t		u8q_t;
typedef int16_t		s16q_t;
typedef uint16_t	u16q_t;
typedef int32_t		s32q_t;
typedef uint32_t	u32q_t;
typedef int64_t		s64q_t;
typedef uint64_t	u64q_t;
.Ed
.Pp
These types are referred to generically in the earlier API definitions as
.Fa QTYPE ,
while
.Fa ITYPE
refers to the
.Xr stdint 7
integer types the Q data types are derived from.
.Fa NTYPE
is used to refer to any numeric type and is therefore a superset of
.Fa QTYPE
and
.Fa ITYPE .
.Pp
The 3 least significant bits
.Pq LSBs
of all q_t data types are reserved for embedded control data:
.Bl -dash
.It
bits 1-2 specify the binary radix point shift index operand, with 00,01,10,11 ==
1,2,3,4.
.It
bit 3 specifies the radix point shift index operand multiplier as 2
.Pq 0
or 16
.Pq 1 .
.El
.Pp
This scheme can therefore represent Q numbers with
.Bq 2,4,6,8,16,32,48,64
bits of precision after the binary radix point.
The number of bits available for the integral component is not explicitly
specified, and implicitly consumes the remaining available bits of the chosen Q
data type.
.Pp
Additionally, the most significant bit
.Pq MSB
of signed Q types stores the sign bit, with bit value 0 representing a positive
number and bit value 1 representing a negative number.
Negative numbers are stored as absolute values with the sign bit set, rather
than the more typical two's complement representation.
This avoids having to bit shift negative numbers, which can result in undefined
behaviour from some compilers.
.Pp
This binary representation used for Q numbers therefore comprises a set of
distinct data bit types and associated bit counts.
Data bit types/labels, listed in LSB to MSB order, are: control
.Sq C ,
fractional
.Sq F ,
integer
.Sq I
and sign
.Sq S .
The following example illustrates the binary representation of a Q20.8 number
represented using a s32q_t variable:
.Bd -literal -offset indent
M                                                             L
S                                                             S
B                                                             B

3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0

S I I I I I I I I I I I I I I I I I I I I F F F F F F F F C C C
.Ed
.Pp
Important bit counts are: total, control, control-encoded fractional, maximum
fractional, effective fractional and integer bits.
.Pp
The count of total bits is derived from the size of the q_t data type.
For example, a s32q_t has 32 total bits.
.Pp
The count of control-encoded fractional bits is derived from calculating the
number of fractional bits per the control bit encoding scheme.
For example, the control bits binary value of 101 encodes a fractional bit
count of 2 x 16 = 32 fractional bits.
.Pp
The count of maximum fractional bits is derived from the difference between the
counts of total bits and control/sign bits.
For example, a s32q_t has a maximum of 32 - 3 - 1 = 28 fractional bits.
.Pp
The count of effective fractional bits is derived from the minimum of the
control-encoded fractional bits and the maximum fractional bits.
For example, a s32q_t with 32 control-encoded fractional bits is effectively
limited to 28 fractional bits.
.Pp
The count of integer bits is derived from the difference between the counts of
total bits and all other non-integer data bits
.Pq the sum of control, fractional and sign bits.
For example, a s32q_t with 8 effective fractional bits has 32 - 3 - 8 - 1 = 20 integer
bits.
The count of integer bits can be zero if all available numeric data bits have
been reserved for fractional data, e.g., when the number of control-encoded
fractional bits is greater than or equal to the underlying Q data type's maximum
fractional bits.
.Sh EXAMPLES
.Ss Calculating area of a circle with r=4.2 and rpshft=16
.Bd -literal -offset indent
u64q_t a, pi, r;
char buf[32]

Q_INI(&a, 0, 0, 16);
Q_INI(&pi, 3, 14159, 16);
Q_INI(&r, 4, 2, 16);

Q_QCLONEQ(&a, r);
Q_QMULQ(&a, r);
Q_QMULQ(&a, pi);

Q_TOSTR(a, -1, 10, buf, sizeof(buf));
printf("%s\\n", buf);
.Ed
.Ss Debugging
Declare a Q20.8 s32q_t number
.Fa s32 ,
initialise it with the fixed-point value for 5/3, and render a debugging
representation of the variable
.Pq including its full precision decimal C-string representation ,
to the console:
.Bd -literal -offset indent
s32q_t s32;
Q_INI(&s32, 0, 0, 8);
Q_QFRACI(&s32, 5, 3);
char buf[Q_MAXSTRLEN(s32, 10)];
Q_TOSTR(s32, -1, 10, buf, sizeof(buf));
printf(Q_DEBUG(s32, "", "\\n\\ttostr=%s\\n\\n", 0), buf);
.Ed
.Pp
The above code outputs the following to the console:
.Bd -literal -offset indent
"s32"@0x7fffffffe7d4
	type=s32q_t, Qm.n=Q20.8, rpshft=11, imin=0xfff00001, \\
imax=0xfffff
	qraw=0x00000d53
	imask=0x7ffff800, fmask=0x000007f8, cmask=0x00000007, \\
ifmask=0x7ffffff8
	iraw=0x00000800, iabsval=0x1, ival=0x1
	fraw=0x00000550, fabsval=0xaa, fval=0xaa
	tostr=1.664
.Ed
.Pp
Note: The
.Qq \e
present in the rendered output above indicates a manual line break inserted to
keep the man page within 80 columns and is not part of the actual output.
.Sh SEE ALSO
.Xr errno 2 ,
.Xr math 3 ,
.Xr Q_FRAWMASK 3 ,
.Xr Q_IFRAWMASK 3 ,
.Xr Q_INI 3 ,
.Xr Q_IRAWMASK 3 ,
.Xr Q_QABS 3 ,
.Xr Q_QADDI 3 ,
.Xr Q_QADDQ 3 ,
.Xr Q_SIGNED 3 ,
.Xr Q_SIGNSHFT 3 ,
.Xr stdint 7
.Sh HISTORY
The
.Nm
functions first appeared in
.Fx 13.0 .
.Sh AUTHORS
.An -nosplit
The
.Nm
functions and this manual page were written by
.An Lawrence Stewart Aq Mt lstewart@FreeBSD.org
and sponsored by Netflix, Inc.