Index: head/lib/msun/man/math.3 =================================================================== --- head/lib/msun/man/math.3 (revision 351543) +++ head/lib/msun/man/math.3 (revision 351544) @@ -1,248 +1,249 @@ .\" Copyright (c) 1985 Regents of the University of California. .\" 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. .\" 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. .\" 3. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. .\" .\" from: @(#)math.3 6.10 (Berkeley) 5/6/91 .\" $FreeBSD$ .\" .Dd December 7, 2017 .Dt MATH 3 .Os .Sh NAME .Nm math .Nd "floating-point mathematical library" .Sh LIBRARY .Lb libm .Sh SYNOPSIS .In math.h .Sh DESCRIPTION The math library includes the following components: .Bl -column "" "polymorphic (type-generic) versions of functions" -compact -offset indent .In math.h Ta basic routines and real-valued functions .In complex.h Ta complex number support .In tgmath.h Ta polymorphic (type-generic) versions of functions .In fenv.h Ta routines to control rounding and exceptions .El The rest of this manual page describes the functions provided by .In math.h . Please consult .Xr complex 3 , .Xr tgmath 3 , and .Xr fenv 3 for information on the other components. .Sh "LIST OF FUNCTIONS" Each of the following .Vt double functions has a .Vt float counterpart with an .Ql f appended to the name and a .Vt "long double" counterpart with an .Ql l appended. As an example, the .Vt float and .Vt "long double" counterparts of .Ft double .Fn acos "double x" are .Ft float .Fn acosf "float x" and .Ft "long double" .Fn acosl "long double x" , respectively. The classification macros and silent order predicates are type generic and should not be suffixed with .Ql f or .Ql l . .de Cl .Bl -column "isgreaterequal" "bessel function of the second kind of the order 0" .Em "Name Description" .. .Ss Algebraic Functions .Cl cbrt cube root fma fused multiply-add hypot Euclidean distance sqrt square root .El .Ss Classification Macros .Cl fpclassify classify a floating-point value isfinite determine whether a value is finite isinf determine whether a value is infinite isnan determine whether a value is \*(Na isnormal determine whether a value is normalized .El .Ss Exponent Manipulation Functions .Cl frexp extract exponent and mantissa ilogb extract exponent ldexp multiply by power of 2 logb extract exponent scalbln adjust exponent scalbn adjust exponent .El .Ss Extremum- and Sign-Related Functions .Cl copysign copy sign bit fabs absolute value fdim positive difference fmax maximum function fmin minimum function signbit extract sign bit .El .Ss Not a Number Functions .Cl nan generate a quiet \*(Na .El .Ss Residue and Rounding Functions .Cl ceil integer no less than floor integer no greater than fmod positive remainder llrint round to integer in fixed-point format llround round to nearest integer in fixed-point format lrint round to integer in fixed-point format lround round to nearest integer in fixed-point format modf extract integer and fractional parts nearbyint round to integer (silent) nextafter next representable value nexttoward next representable value remainder remainder remquo remainder with partial quotient rint round to integer round round to nearest integer trunc integer no greater in magnitude than .El .Pp The .Fn ceil , .Fn floor , .Fn llround , .Fn lround , .Fn round , and .Fn trunc functions round in predetermined directions, whereas .Fn llrint , .Fn lrint , and .Fn rint round according to the current (dynamic) rounding mode. For more information on controlling the dynamic rounding mode, see .Xr fenv 3 and .Xr fesetround 3 . .Ss Silent Order Predicates .Cl isgreater greater than relation isgreaterequal greater than or equal to relation isless less than relation islessequal less than or equal to relation islessgreater less than or greater than relation isunordered unordered relation .El .Ss Transcendental Functions .Cl acos inverse cosine acosh inverse hyperbolic cosine asin inverse sine asinh inverse hyperbolic sine atan inverse tangent atanh inverse hyperbolic tangent atan2 atan(y/x); complex argument cos cosine cosh hyperbolic cosine erf error function erfc complementary error function exp exponential base e exp2 exponential base 2 expm1 exp(x)\-1 j0 Bessel function of the first kind of the order 0 j1 Bessel function of the first kind of the order 1 jn Bessel function of the first kind of the order n lgamma log gamma function log natural logarithm log10 logarithm to base 10 log1p log(1+x) log2 base 2 logarithm pow exponential x**y sin trigonometric function sinh hyperbolic function tan trigonometric function tanh hyperbolic function tgamma gamma function y0 Bessel function of the second kind of the order 0 y1 Bessel function of the second kind of the order 1 yn Bessel function of the second kind of the order n .El .Pp The routines in this section might not produce a result that is correctly rounded, so reproducible results cannot be guaranteed across platforms. For most of these functions, however, incorrect rounding occurs rarely, and then only in very-close-to-halfway cases. .Sh SEE ALSO .Xr complex 3 , .Xr fenv 3 , .Xr ieee 3 , +.Xr qmath 3 , .Xr tgmath 3 .Sh HISTORY A math library with many of the present functions appeared in .At v7 . The library was substantially rewritten for .Bx 4.3 to provide better accuracy and speed on machines supporting either VAX or IEEE 754 floating-point. Most of this library was replaced with FDLIBM, developed at Sun Microsystems, in .Fx 1.1.5 . Additional routines, including ones for .Vt float and .Vt long double values, were written for or imported into subsequent versions of FreeBSD. .Sh BUGS Many of the routines to compute transcendental functions produce inaccurate results in other than the default rounding mode. .Pp On the i386 platform, trigonometric argument reduction is not performed accurately for huge arguments, resulting in large errors for such arguments to .Fn cos , .Fn sin , and .Fn tan . Index: head/share/man/man3/Makefile =================================================================== --- head/share/man/man3/Makefile (revision 351543) +++ head/share/man/man3/Makefile (revision 351544) @@ -1,372 +1,444 @@ # @(#)Makefile 8.2 (Berkeley) 12/13/93 # $FreeBSD$ .include MAN= assert.3 \ ATOMIC_VAR_INIT.3 \ bitstring.3 \ CMSG_DATA.3 \ end.3 \ fpgetround.3 \ intro.3 \ makedev.3 \ offsetof.3 \ ${PTHREAD_MAN} \ + Q_FRAWMASK.3 \ + Q_IFRAWMASK.3 \ + Q_INI.3 \ + Q_IRAWMASK.3 \ + Q_QABS.3 \ + Q_QADDI.3 \ + Q_QADDQ.3 \ + Q_SIGNED.3 \ + Q_SIGNSHFT.3 \ + qmath.3 \ queue.3 \ sigevent.3 \ siginfo.3 \ stdarg.3 \ sysexits.3 \ tgmath.3 \ timeradd.3 \ tree.3 MLINKS= ATOMIC_VAR_INIT.3 atomic_compare_exchange_strong.3 \ ATOMIC_VAR_INIT.3 atomic_compare_exchange_strong_explicit.3 \ ATOMIC_VAR_INIT.3 atomic_compare_exchange_weak.3 \ ATOMIC_VAR_INIT.3 atomic_compare_exchange_weak_explicit.3 \ ATOMIC_VAR_INIT.3 atomic_exchange.3 \ ATOMIC_VAR_INIT.3 atomic_exchange_explicit.3 \ ATOMIC_VAR_INIT.3 atomic_fetch_add.3 \ ATOMIC_VAR_INIT.3 atomic_fetch_add_explicit.3 \ ATOMIC_VAR_INIT.3 atomic_fetch_and.3 \ ATOMIC_VAR_INIT.3 atomic_fetch_and_explicit.3 \ ATOMIC_VAR_INIT.3 atomic_fetch_or.3 \ ATOMIC_VAR_INIT.3 atomic_fetch_or_explicit.3 \ ATOMIC_VAR_INIT.3 atomic_fetch_sub.3 \ ATOMIC_VAR_INIT.3 atomic_fetch_sub_explicit.3 \ ATOMIC_VAR_INIT.3 atomic_fetch_xor.3 \ ATOMIC_VAR_INIT.3 atomic_fetch_xor_explicit.3 \ ATOMIC_VAR_INIT.3 atomic_init.3 \ ATOMIC_VAR_INIT.3 atomic_is_lock_free.3 \ ATOMIC_VAR_INIT.3 atomic_load.3 \ ATOMIC_VAR_INIT.3 atomic_load_explicit.3 \ ATOMIC_VAR_INIT.3 atomic_store.3 \ ATOMIC_VAR_INIT.3 atomic_store_explicit.3 MLINKS+= bitstring.3 bit_alloc.3 \ bitstring.3 bit_clear.3 \ bitstring.3 bit_decl.3 \ bitstring.3 bit_ffc.3 \ bitstring.3 bit_ffc_at.3 \ bitstring.3 bit_ffs.3 \ bitstring.3 bit_ffs_at.3 \ bitstring.3 bit_nclear.3 \ bitstring.3 bit_nset.3 \ bitstring.3 bit_set.3 \ bitstring.3 bitstr_size.3 \ bitstring.3 bit_test.3 MLINKS+= CMSG_DATA.3 CMSG_FIRSTHDR.3 \ CMSG_DATA.3 CMSG_LEN.3 \ CMSG_DATA.3 CMSG_NEXTHDR.3 \ CMSG_DATA.3 CMSG_SPACE.3 MLINKS+= end.3 edata.3 \ end.3 etext.3 MLINKS+= fpgetround.3 fpgetmask.3 \ fpgetround.3 fpgetprec.3 \ fpgetround.3 fpgetsticky.3 \ fpgetround.3 fpresetsticky.3 \ fpgetround.3 fpsetmask.3 \ fpgetround.3 fpsetprec.3 \ fpgetround.3 fpsetround.3 MLINKS+= makedev.3 major.3 \ makedev.3 minor.3 MLINKS+= ${PTHREAD_MLINKS} +MLINKS+= Q_FRAWMASK.3 Q_GFRAW.3 \ + Q_FRAWMASK.3 Q_GFABSVAL.3 \ + Q_FRAWMASK.3 Q_GFVAL.3 \ + Q_FRAWMASK.3 Q_SFVAL.3 +MLINKS+= Q_IFRAWMASK.3 Q_IFVALIMASK.3 \ + Q_IFRAWMASK.3 Q_IFVALFMASK.3 \ + Q_IFRAWMASK.3 Q_GIFRAW.3 \ + Q_IFRAWMASK.3 Q_GIFABSVAL.3 \ + Q_IFRAWMASK.3 Q_GIFVAL.3 \ + Q_IFRAWMASK.3 Q_SIFVAL.3 \ + Q_IFRAWMASK.3 Q_SIFVALS.3 +MLINKS+= Q_INI.3 Q_NCBITS.3 \ + Q_INI.3 Q_BT.3 \ + Q_INI.3 Q_TC.3 \ + Q_INI.3 Q_NTBITS.3 \ + Q_INI.3 Q_NFCBITS.3 \ + Q_INI.3 Q_MAXNFBITS.3 \ + Q_INI.3 Q_NFBITS.3 \ + Q_INI.3 Q_NIBITS.3 \ + Q_INI.3 Q_RPSHFT.3 \ + Q_INI.3 Q_ABS.3 \ + Q_INI.3 Q_MAXSTRLEN.3 \ + Q_INI.3 Q_TOSTR.3 \ + Q_INI.3 Q_SHL.3 \ + Q_INI.3 Q_SHR.3 \ + Q_INI.3 Q_DEBUG.3 \ + Q_INI.3 Q_DFV2BFV.3 +MLINKS+= Q_IRAWMASK.3 Q_GIRAW.3 \ + Q_IRAWMASK.3 Q_GIABSVAL.3 \ + Q_IRAWMASK.3 Q_GIVAL.3 \ + Q_IRAWMASK.3 Q_SIVAL.3 +MLINKS+= Q_QABS.3 Q_Q2D.3 \ + Q_QABS.3 Q_Q2F.3 +MLINKS+= Q_QADDI.3 Q_QDIVI.3 \ + Q_QADDI.3 Q_QMULI.3 \ + Q_QADDI.3 Q_QSUBI.3 \ + Q_QADDI.3 Q_QFRACI.3 \ + Q_QADDI.3 Q_QCPYVALI.3 +MLINKS+= Q_QADDQ.3 Q_QDIVQ.3 \ + Q_QADDQ.3 Q_QMULQ.3 \ + Q_QADDQ.3 Q_QSUBQ.3 \ + Q_QADDQ.3 Q_NORMPREC.3 \ + Q_QADDQ.3 Q_QMAXQ.3 \ + Q_QADDQ.3 Q_QMINQ.3 \ + Q_QADDQ.3 Q_QCLONEQ.3 \ + Q_QADDQ.3 Q_QCPYVALQ.3 +MLINKS+= Q_SIGNED.3 Q_LTZ.3 \ + Q_SIGNED.3 Q_PRECEQ.3 \ + Q_SIGNED.3 Q_QLTQ.3 \ + Q_SIGNED.3 Q_QLEQ.3 \ + Q_SIGNED.3 Q_QGTQ.3 \ + Q_SIGNED.3 Q_QGEQ.3 \ + Q_SIGNED.3 Q_QEQ.3 \ + Q_SIGNED.3 Q_QNEQ.3 \ + Q_SIGNED.3 Q_OFLOW.3 \ + Q_SIGNED.3 Q_RELPREC.3 +MLINKS+= Q_SIGNSHFT.3 Q_SSIGN.3 \ + Q_SIGNSHFT.3 Q_CRAWMASK.3 \ + Q_SIGNSHFT.3 Q_SRAWMASK.3 \ + Q_SIGNSHFT.3 Q_GCRAW.3 \ + Q_SIGNSHFT.3 Q_GCVAL.3 \ + Q_SIGNSHFT.3 Q_SCVAL.3 MLINKS+= queue.3 LIST_CLASS_ENTRY.3 \ queue.3 LIST_CLASS_HEAD.3 \ queue.3 LIST_EMPTY.3 \ queue.3 LIST_ENTRY.3 \ queue.3 LIST_FIRST.3 \ queue.3 LIST_FOREACH.3 \ queue.3 LIST_FOREACH_FROM.3 \ queue.3 LIST_FOREACH_FROM_SAFE.3 \ queue.3 LIST_FOREACH_SAFE.3 \ queue.3 LIST_HEAD.3 \ queue.3 LIST_HEAD_INITIALIZER.3 \ queue.3 LIST_INIT.3 \ queue.3 LIST_INSERT_AFTER.3 \ queue.3 LIST_INSERT_BEFORE.3 \ queue.3 LIST_INSERT_HEAD.3 \ queue.3 LIST_NEXT.3 \ queue.3 LIST_PREV.3 \ queue.3 LIST_REMOVE.3 \ queue.3 LIST_SWAP.3 \ queue.3 SLIST_CLASS_ENTRY.3 \ queue.3 SLIST_CLASS_HEAD.3 \ queue.3 SLIST_EMPTY.3 \ queue.3 SLIST_ENTRY.3 \ queue.3 SLIST_FIRST.3 \ queue.3 SLIST_FOREACH.3 \ queue.3 SLIST_FOREACH_FROM.3 \ queue.3 SLIST_FOREACH_FROM_SAFE.3 \ queue.3 SLIST_FOREACH_SAFE.3 \ queue.3 SLIST_HEAD.3 \ queue.3 SLIST_HEAD_INITIALIZER.3 \ queue.3 SLIST_INIT.3 \ queue.3 SLIST_INSERT_AFTER.3 \ queue.3 SLIST_INSERT_HEAD.3 \ queue.3 SLIST_NEXT.3 \ queue.3 SLIST_REMOVE.3 \ queue.3 SLIST_REMOVE_AFTER.3 \ queue.3 SLIST_REMOVE_HEAD.3 \ queue.3 SLIST_REMOVE_PREVPTR.3 \ queue.3 SLIST_SWAP.3 \ queue.3 STAILQ_CLASS_ENTRY.3 \ queue.3 STAILQ_CLASS_HEAD.3 \ queue.3 STAILQ_CONCAT.3 \ queue.3 STAILQ_EMPTY.3 \ queue.3 STAILQ_ENTRY.3 \ queue.3 STAILQ_FIRST.3 \ queue.3 STAILQ_FOREACH.3 \ queue.3 STAILQ_FOREACH_FROM.3 \ queue.3 STAILQ_FOREACH_FROM_SAFE.3 \ queue.3 STAILQ_FOREACH_SAFE.3 \ queue.3 STAILQ_HEAD.3 \ queue.3 STAILQ_HEAD_INITIALIZER.3 \ queue.3 STAILQ_INIT.3 \ queue.3 STAILQ_INSERT_AFTER.3 \ queue.3 STAILQ_INSERT_HEAD.3 \ queue.3 STAILQ_INSERT_TAIL.3 \ queue.3 STAILQ_LAST.3 \ queue.3 STAILQ_NEXT.3 \ queue.3 STAILQ_REMOVE.3 \ queue.3 STAILQ_REMOVE_AFTER.3 \ queue.3 STAILQ_REMOVE_HEAD.3 \ queue.3 STAILQ_SWAP.3 \ queue.3 TAILQ_CLASS_ENTRY.3 \ queue.3 TAILQ_CLASS_HEAD.3 \ queue.3 TAILQ_CONCAT.3 \ queue.3 TAILQ_EMPTY.3 \ queue.3 TAILQ_ENTRY.3 \ queue.3 TAILQ_FIRST.3 \ queue.3 TAILQ_FOREACH.3 \ queue.3 TAILQ_FOREACH_FROM.3 \ queue.3 TAILQ_FOREACH_FROM_SAFE.3 \ queue.3 TAILQ_FOREACH_REVERSE.3 \ queue.3 TAILQ_FOREACH_REVERSE_FROM.3 \ queue.3 TAILQ_FOREACH_REVERSE_FROM_SAFE.3 \ queue.3 TAILQ_FOREACH_REVERSE_SAFE.3 \ queue.3 TAILQ_FOREACH_SAFE.3 \ queue.3 TAILQ_HEAD.3 \ queue.3 TAILQ_HEAD_INITIALIZER.3 \ queue.3 TAILQ_INIT.3 \ queue.3 TAILQ_INSERT_AFTER.3 \ queue.3 TAILQ_INSERT_BEFORE.3 \ queue.3 TAILQ_INSERT_HEAD.3 \ queue.3 TAILQ_INSERT_TAIL.3 \ queue.3 TAILQ_LAST.3 \ queue.3 TAILQ_NEXT.3 \ queue.3 TAILQ_PREV.3 \ queue.3 TAILQ_REMOVE.3 \ queue.3 TAILQ_SWAP.3 MLINKS+= stdarg.3 va_arg.3 \ stdarg.3 va_copy.3 \ stdarg.3 va_end.3 \ stdarg.3 varargs.3 \ stdarg.3 va_start.3 MLINKS+= timeradd.3 timerclear.3 \ timeradd.3 timercmp.3 \ timeradd.3 timerisset.3 \ timeradd.3 timersub.3 \ timeradd.3 timespecadd.3 \ timeradd.3 timespecsub.3 \ timeradd.3 timespecclear.3 \ timeradd.3 timespecisset.3 \ timeradd.3 timespeccmp.3 MLINKS+= tree.3 RB_EMPTY.3 \ tree.3 RB_ENTRY.3 \ tree.3 RB_FIND.3 \ tree.3 RB_FOREACH.3 \ tree.3 RB_FOREACH_FROM.3 \ tree.3 RB_FOREACH_REVERSE.3 \ tree.3 RB_FOREACH_REVERSE_FROM.3 \ tree.3 RB_FOREACH_REVERSE_SAFE.3 \ tree.3 RB_FOREACH_SAFE.3 \ tree.3 RB_GENERATE.3 \ tree.3 RB_GENERATE_FIND.3 \ tree.3 RB_GENERATE_INSERT.3 \ tree.3 RB_GENERATE_INSERT_COLOR.3 \ tree.3 RB_GENERATE_MINMAX.3 \ tree.3 RB_GENERATE_NEXT.3 \ tree.3 RB_GENERATE_NFIND.3 \ tree.3 RB_GENERATE_PREV.3 \ tree.3 RB_GENERATE_REMOVE.3 \ tree.3 RB_GENERATE_REMOVE_COLOR.3 \ tree.3 RB_GENERATE_STATIC.3 \ tree.3 RB_HEAD.3 \ tree.3 RB_INIT.3 \ tree.3 RB_INITIALIZER.3 \ tree.3 RB_INSERT.3 \ tree.3 RB_LEFT.3 \ tree.3 RB_MAX.3 \ tree.3 RB_MIN.3 \ tree.3 RB_NEXT.3 \ tree.3 RB_NFIND.3 \ tree.3 RB_PARENT.3 \ tree.3 RB_PREV.3 \ tree.3 RB_PROTOTYPE.3 \ tree.3 RB_PROTOTYPE_FIND.3 \ tree.3 RB_PROTOTYPE_INSERT.3 \ tree.3 RB_PROTOTYPE_INSERT_COLOR.3 \ tree.3 RB_PROTOTYPE_MINMAX.3 \ tree.3 RB_PROTOTYPE_NEXT.3 \ tree.3 RB_PROTOTYPE_NFIND.3 \ tree.3 RB_PROTOTYPE_PREV.3 \ tree.3 RB_PROTOTYPE_REMOVE.3 \ tree.3 RB_PROTOTYPE_REMOVE_COLOR.3 \ tree.3 RB_PROTOTYPE_STATIC.3 \ tree.3 RB_REMOVE.3 \ tree.3 RB_RIGHT.3 \ tree.3 RB_ROOT.3 \ tree.3 SPLAY_EMPTY.3 \ tree.3 SPLAY_ENTRY.3 \ tree.3 SPLAY_FIND.3 \ tree.3 SPLAY_FOREACH.3 \ tree.3 SPLAY_GENERATE.3 \ tree.3 SPLAY_HEAD.3 \ tree.3 SPLAY_INIT.3 \ tree.3 SPLAY_INITIALIZER.3 \ tree.3 SPLAY_INSERT.3 \ tree.3 SPLAY_LEFT.3 \ tree.3 SPLAY_MAX.3 \ tree.3 SPLAY_MIN.3 \ tree.3 SPLAY_NEXT.3 \ tree.3 SPLAY_PROTOTYPE.3 \ tree.3 SPLAY_REMOVE.3 \ tree.3 SPLAY_RIGHT.3 \ tree.3 SPLAY_ROOT.3 .if ${MK_LIBTHR} != "no" PTHREAD_MAN= pthread.3 \ pthread_affinity_np.3 \ pthread_atfork.3 \ pthread_attr.3 \ pthread_attr_affinity_np.3 \ pthread_attr_get_np.3 \ pthread_attr_setcreatesuspend_np.3 \ pthread_barrierattr.3 \ pthread_barrier_destroy.3 \ pthread_cancel.3 \ pthread_cleanup_pop.3 \ pthread_cleanup_push.3 \ pthread_condattr.3 \ pthread_cond_broadcast.3 \ pthread_cond_destroy.3 \ pthread_cond_init.3 \ pthread_cond_signal.3 \ pthread_cond_timedwait.3 \ pthread_cond_wait.3 \ pthread_create.3 \ pthread_detach.3 \ pthread_equal.3 \ pthread_exit.3 \ pthread_getconcurrency.3 \ pthread_getcpuclockid.3 \ pthread_getspecific.3 \ pthread_getthreadid_np.3 \ pthread_join.3 \ pthread_key_create.3 \ pthread_key_delete.3 \ pthread_kill.3 \ pthread_main_np.3 \ pthread_multi_np.3 \ pthread_mutexattr.3 \ pthread_mutexattr_getkind_np.3 \ pthread_mutex_consistent.3 \ pthread_mutex_destroy.3 \ pthread_mutex_init.3 \ pthread_mutex_lock.3 \ pthread_mutex_timedlock.3 \ pthread_mutex_trylock.3 \ pthread_mutex_unlock.3 \ pthread_once.3 \ pthread_resume_all_np.3 \ pthread_resume_np.3 \ pthread_rwlockattr_destroy.3 \ pthread_rwlockattr_getpshared.3 \ pthread_rwlockattr_init.3 \ pthread_rwlockattr_setpshared.3 \ pthread_rwlock_destroy.3 \ pthread_rwlock_init.3 \ pthread_rwlock_rdlock.3 \ pthread_rwlock_timedrdlock.3 \ pthread_rwlock_timedwrlock.3 \ pthread_rwlock_unlock.3 \ pthread_rwlock_wrlock.3 \ pthread_schedparam.3 \ pthread_self.3 \ pthread_set_name_np.3 \ pthread_setspecific.3 \ pthread_sigmask.3 \ pthread_spin_init.3 \ pthread_spin_lock.3 \ pthread_suspend_all_np.3 \ pthread_suspend_np.3 \ pthread_switch_add_np.3 \ pthread_testcancel.3 \ pthread_yield.3 PTHREAD_MLINKS= pthread_affinity_np.3 pthread_getaffinity_np.3 \ pthread_affinity_np.3 pthread_setaffinity_np.3 PTHREAD_MLINKS+=pthread_attr.3 pthread_attr_destroy.3 \ pthread_attr.3 pthread_attr_getdetachstate.3 \ pthread_attr.3 pthread_attr_getguardsize.3 \ pthread_attr.3 pthread_attr_getinheritsched.3 \ pthread_attr.3 pthread_attr_getschedparam.3 \ pthread_attr.3 pthread_attr_getschedpolicy.3 \ pthread_attr.3 pthread_attr_getscope.3 \ pthread_attr.3 pthread_attr_getstack.3 \ pthread_attr.3 pthread_attr_getstackaddr.3 \ pthread_attr.3 pthread_attr_getstacksize.3 \ pthread_attr.3 pthread_attr_init.3 \ pthread_attr.3 pthread_attr_setdetachstate.3 \ pthread_attr.3 pthread_attr_setguardsize.3 \ pthread_attr.3 pthread_attr_setinheritsched.3 \ pthread_attr.3 pthread_attr_setschedparam.3 \ pthread_attr.3 pthread_attr_setschedpolicy.3 \ pthread_attr.3 pthread_attr_setscope.3 \ pthread_attr.3 pthread_attr_setstack.3 \ pthread_attr.3 pthread_attr_setstackaddr.3 \ pthread_attr.3 pthread_attr_setstacksize.3 PTHREAD_MLINKS+=pthread_attr_affinity_np.3 pthread_attr_getaffinity_np.3 \ pthread_attr_affinity_np.3 pthread_attr_setaffinity_np.3 PTHREAD_MLINKS+=pthread_barrierattr.3 pthread_barrierattr_destroy.3 \ pthread_barrierattr.3 pthread_barrierattr_getpshared.3 \ pthread_barrierattr.3 pthread_barrierattr_init.3 \ pthread_barrierattr.3 pthread_barrierattr_setpshared.3 PTHREAD_MLINKS+=pthread_barrier_destroy.3 pthread_barrier_init.3 \ pthread_barrier_destroy.3 pthread_barrier_wait.3 PTHREAD_MLINKS+=pthread_condattr.3 pthread_condattr_destroy.3 \ pthread_condattr.3 pthread_condattr_init.3 \ pthread_condattr.3 pthread_condattr_getclock.3 \ pthread_condattr.3 pthread_condattr_setclock.3 \ pthread_condattr.3 pthread_condattr_getpshared.3 \ pthread_condattr.3 pthread_condattr_setpshared.3 PTHREAD_MLINKS+=pthread_getconcurrency.3 pthread_setconcurrency.3 PTHREAD_MLINKS+=pthread_multi_np.3 pthread_single_np.3 PTHREAD_MLINKS+=pthread_mutexattr.3 pthread_mutexattr_destroy.3 \ pthread_mutexattr.3 pthread_mutexattr_getprioceiling.3 \ pthread_mutexattr.3 pthread_mutexattr_getprotocol.3 \ pthread_mutexattr.3 pthread_mutexattr_getrobust.3 \ pthread_mutexattr.3 pthread_mutexattr_gettype.3 \ pthread_mutexattr.3 pthread_mutexattr_init.3 \ pthread_mutexattr.3 pthread_mutexattr_setprioceiling.3 \ pthread_mutexattr.3 pthread_mutexattr_setprotocol.3 \ pthread_mutexattr.3 pthread_mutexattr_setrobust.3 \ pthread_mutexattr.3 pthread_mutexattr_settype.3 PTHREAD_MLINKS+=pthread_mutexattr_getkind_np.3 pthread_mutexattr_setkind_np.3 PTHREAD_MLINKS+=pthread_rwlock_rdlock.3 pthread_rwlock_tryrdlock.3 PTHREAD_MLINKS+=pthread_rwlock_wrlock.3 pthread_rwlock_trywrlock.3 PTHREAD_MLINKS+=pthread_schedparam.3 pthread_getschedparam.3 \ pthread_schedparam.3 pthread_setschedparam.3 PTHREAD_MLINKS+=pthread_set_name_np.3 pthread_get_name_np.3 PTHREAD_MLINKS+=pthread_spin_init.3 pthread_spin_destroy.3 \ pthread_spin_lock.3 pthread_spin_trylock.3 \ pthread_spin_lock.3 pthread_spin_unlock.3 PTHREAD_MLINKS+=pthread_switch_add_np.3 pthread_switch_delete_np.3 PTHREAD_MLINKS+=pthread_testcancel.3 pthread_setcancelstate.3 \ pthread_testcancel.3 pthread_setcanceltype.3 PTHREAD_MLINKS+=pthread_join.3 pthread_timedjoin_np.3 .endif .include Index: head/share/man/man3/Q_FRAWMASK.3 =================================================================== --- head/share/man/man3/Q_FRAWMASK.3 (nonexistent) +++ head/share/man/man3/Q_FRAWMASK.3 (revision 351544) @@ -0,0 +1,125 @@ +.\" +.\" 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. +.\" +.\" $FreeBSD$ +.\" +.Dd July 8, 2018 +.Dt Q_FRAWMASK 3 +.Os +.Sh NAME +.Nm Q_FRAWMASK , +.Nm Q_GFRAW , +.Nm Q_GFABSVAL , +.Nm Q_GFVAL , +.Nm Q_SFVAL +.Nd fixed-point math functions which manipulate the fractional data bits +.Sh SYNOPSIS +.In sys/qmath.h +.Ft ITYPE +.Fn Q_FRAWMASK "QTYPE q" +.Ft ITYPE +.Fn Q_GFRAW "QTYPE q" +.Ft ITYPE +.Fn Q_GFABSVAL "QTYPE q" +.Ft ITYPE +.Fn Q_GFVAL "QTYPE q" +.Ft QTYPE +.Fn Q_SFVAL "QTYPE q" "ITYPE fv" +.Sh DESCRIPTION +.Fn Q_FRAWMASK +returns a +.Fa q Ns -specific +bit mask for +.Fa q Ap s +fractional data bits. +.Pp +.Fn Q_GFRAW +returns +.Fa q Ap s +raw masked fractional data bits. +.Pp +.Fn Q_GFABSVAL +and +.Fn Q_GFVAL +return the absolute and real values of +.Fa q Ap s +fractional data bits respectively. +.Pp +.Fn Q_SFVAL +sets +.Fa q Ap s +fractional data bits to the value +.Fa fv . +.Pp +All of those functions operate on +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 as +.Fa QTYPE . +The +.Fa ITYPE +refers to the +.Xr stdint 7 +integer types. +.Pp +For more details, see +.Xr qmath 3 . +.Sh RETURN VALUES +.Fn Q_FRAWMASK , +.Fn Q_GFRAW , +.Fn Q_GFABSVAL +and +.Fn Q_GFVAL +return their respective values as integers of the same underlying ITYPE as +.Fa q . +.Pp +.Fn Q_SFVAL +returns the value of +.Fa q +post set. +.Sh SEE ALSO +.Xr errno 2 , +.Xr qmath 3 , +.Xr stdint 7 +.Sh HISTORY +The +.Xr qmath 3 +functions first appeared in +.Fx 13.0 . +.Sh AUTHORS +.An -nosplit +The +.Xr qmath 3 +functions and this manual page were written by +.An Lawrence Stewart Aq Mt lstewart@FreeBSD.org +and sponsored by Netflix, Inc. Property changes on: head/share/man/man3/Q_FRAWMASK.3 ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/share/man/man3/Q_IFRAWMASK.3 =================================================================== --- head/share/man/man3/Q_IFRAWMASK.3 (nonexistent) +++ head/share/man/man3/Q_IFRAWMASK.3 (revision 351544) @@ -0,0 +1,162 @@ +.\" +.\" 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. +.\" +.\" $FreeBSD$ +.\" +.Dd July 8, 2018 +.Dt Q_IFRAWMASK 3 +.Os +.Sh NAME +.Nm Q_IFRAWMASK , +.Nm Q_IFVALIMASK , +.Nm Q_IFVALFMASK , +.Nm Q_GIFRAW , +.Nm Q_GIFABSVAL , +.Nm Q_GIFVAL , +.Nm Q_SIFVAL , +.Nm Q_SIFVALS +.Nd fixed-point math functions which manipulate the combined integer/fractional +data bits +.Sh SYNOPSIS +.In sys/qmath.h +.Ft ITYPE +.Fn Q_IFRAWMASK "QTYPE q" +.Ft ITYPE +.Fn Q_IFVALIMASK "QTYPE q" +.Ft ITYPE +.Fn Q_IFVALFMASK "QTYPE q" +.Ft ITYPE +.Fn Q_GIFRAW "QTYPE q" +.Ft ITYPE +.Fn Q_GIFABSVAL "QTYPE q" +.Ft ITYPE +.Fn Q_GIFVAL "QTYPE q" +.Ft QTYPE +.Fn Q_SIFVAL "QTYPE q" "ITYPE ifv" +.Ft QTYPE +.Fn Q_SIFVALS "QTYPE q" "ITYPE iv" "ITYPE fv" +.Sh DESCRIPTION +.Fn Q_IFRAWMASK +returns a +.Fa q Ns -specific +bit mask for +.Fa q Ap s +combined integer and fractional data bits. +.Pp +.Fn Q_IFVALIMASK +and +.Fn Q_IFVALFMASK +return +.Fa q Ns -specific +bit masks for the integer and fractional bits of +.Fa q Ap s +combined integer and fractional data bits value, i.e., are applicable to the +values returned by +.Fn Q_GIFABSVAL +and +.Fn Q_GIFVAL . +.Pp +.Fn Q_GIFRAW +returns +.Fa q Ap s +raw masked integer/fractional data bits. +.Pp +.Fn Q_GIFABSVAL +and +.Fn Q_GIFVAL +return the absolute and real values of +.Fa q Ap s +integer/fractional data bits respectively. +.Pp +.Fn Q_SIFVAL +sets +.Fa q Ap s +combined integer/fractional data bits to the value +.Fa ifv , +whereas +.Fn Q_SIFVALS +independently sets +.Fa q Ap s +integer and fractional data bits to the separate values +.Fa iv +and +.Fa fv . +.Pp +All of those functions operate on +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 as +.Fa QTYPE . +The +.Fa ITYPE +refers to the +.Xr stdint 7 +integer types. +.Pp +For more details, see +.Xr qmath 3 . +.Sh RETURN VALUES +.Fn Q_IFRAWMASK , +.Fn Q_IFVALIMASK , +.Fn Q_IFVALFMASK , +.Fn Q_GIFABSVAL , +.Fn Q_GIFVAL , +.Fn Q_GIFRAW , +.Fn Q_GIFABSVAL +and +.Fn Q_GIFVAL +return their respective values as integers of the same underlying ITYPE as +.Fa q . +.Pp +.Fn Q_SIFVAL +and +.Fn Q_SIFVALS +return the value of +.Fa q +post change. +.Sh SEE ALSO +.Xr errno 2 , +.Xr qmath 3 , +.Xr stdint 7 +.Sh HISTORY +The +.Xr qmath 3 +functions first appeared in +.Fx 13.0 . +.Sh AUTHORS +.An -nosplit +The +.Xr qmath 3 +functions and this manual page were written by +.An Lawrence Stewart Aq Mt lstewart@FreeBSD.org +and sponsored by Netflix, Inc. Property changes on: head/share/man/man3/Q_IFRAWMASK.3 ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/share/man/man3/Q_INI.3 =================================================================== --- head/share/man/man3/Q_INI.3 (nonexistent) +++ head/share/man/man3/Q_INI.3 (revision 351544) @@ -0,0 +1,261 @@ +.\" +.\" 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. +.\" +.\" $FreeBSD$ +.\" +.Dd July 8, 2018 +.Dt Q_INI 3 +.Os +.Sh NAME +.Nm Q_INI , +.Nm Q_NCBITS , +.Nm Q_BT , +.Nm Q_TC , +.Nm Q_NTBITS , +.Nm Q_NFCBITS , +.Nm Q_MAXNFBITS , +.Nm Q_NFBITS , +.Nm Q_NIBITS , +.Nm Q_RPSHFT , +.Nm Q_ABS , +.Nm Q_MAXSTRLEN , +.Nm Q_TOSTR , +.Nm Q_SHL , +.Nm Q_SHR , +.Nm Q_DEBUG +.Nd fixed-point math miscellaneous functions/variables +.Sh SYNOPSIS +.In sys/qmath.h +.Ft QTYPE +.Fn Q_INI "QTYPE *q" "ITYPE iv" "ITYPE dfv" "int rpshft" +.Fd Q_NCBITS +.Ft __typeof(q) +.Fn Q_BT "QTYPE q" +.Ft ITYPE +.Fn Q_TC "QTYPE q" "ITYPE v" +.Ft uint32_t +.Fn Q_NTBITS "QTYPE q" +.Ft uint32_t +.Fn Q_NFCBITS "QTYPE q" +.Ft uint32_t +.Fn Q_MAXNFBITS "QTYPE q" +.Ft uint32_t +.Fn Q_NFBITS "QTYPE q" +.Ft uint32_t +.Fn Q_NIBITS "QTYPE q" +.Ft uint32_t +.Fn Q_RPSHFT "QTYPE q" +.Ft NTYPE +.Fn Q_ABS "NTYPE n" +.Ft uint32_t +.Fn Q_MAXSTRLEN "QTYPE q" "int base" +.Ft char * +.Fn Q_TOSTR "QTYPE q" "int prec" "int base" "char *s" "int slen" +.Ft ITYPE +.Fn Q_SHL "QTYPE q" "ITYPE iv" +.Ft ITYPE +.Fn Q_SHR "QTYPE q" "ITYPE iv" +.Ft char *, ... +.Fn Q_DEBUG "QTYPE q" "char *prefmt" "char *postfmt" "incfmt" +.Ft ITYPE +.Fn Q_DFV2BFV "ITYPE dfv" "int nfbits" +.Sh DESCRIPTION +.Fn Q_INI +initialises a Q number with the supplied integral value +.Fa iv +and decimal fractional value +.Fa dfv , +with appropriate control bits based on the requested radix shift point +.Fa rpshft . +.Fa dfv +must be passed as a preprocessor literal to preserve leading zeroes. +.Pp +The +.Dv Q_NCBITS +defined constant specifies the number of reserved control bits, currently 3. +.Pp +.Fn Q_NTBITS , +.Fn Q_NFCBITS , +.Fn Q_MAXNFBITS , +.Fn Q_NFBITS +and +.Fn Q_NIBITS +return the +.Fa q Ns -specific +count of total, control-encoded fractional, maximum fractional, effective +fractional, and integer bits applicable to +.Fa q +respectively. +.Pp +.Fn Q_BT +returns the C data type of +.Fa q , +while +.Fn Q_TC +returns +.Fa v +type casted to the C data type of +.Fa q . +.Pp +.Fn Q_RPSHFT +returns the bit position of +.Fa q Ap s +binary radix point relative to bit zero. +.Pp +.Fn Q_ABS +returns the absolute value of any standard numeric type +.Pq that uses the MSB as a sign bit, but not Q numbers +passed in as +.Fa n . +The function is signed/unsigned type safe. +.Pp +.Fn Q_SHL +and +.Fn Q_SHR +return the integral value +.Fa v +left or right shifted by the appropriate amount for +.Fa q . +.Pp +.Fn Q_MAXSTRLEN +calculates the maximum number of characters that may be required to render the +C-string representation of +.Fa q +with numeric base +.Fa base . +.Pp +.Fn Q_TOSTR +renders the C-string representation of +.Fa q +with numeric base +.Fa base +and fractional precision +.Fa prec +into +.Fa s +which has an available capacity of +.Fa slen +characters. +.Fa base +must be in range +.Bq 2,16 . +Specifying +.Fa prec +as -1 renders the number's fractional component with maximum precision. +If +.Fa slen +is greater than zero but insufficient to hold the complete C-string, the '\\0' +C-string terminator will be written to +.Fa *s , +thereby returning a zero length C-string. +.Pp +.Fn Q_DEBUG +returns a format string and associated data suitable for printf-like rendering +of debugging information pertaining to +.Fa q . +If either +.Fa prefmt +and/or +.Fa postfmt +are specified, they are prepended and appended to the resulting format string +respectively. +The +.Fa incfmt +boolean specifies whether to include +.Pq Vt true +or exclude +.Pq Vt false +the raw format string itself in the debugging output. +.Pp +.Fn Q_DFV2BFV +converts decimal fractional value +.Fa dfv +to its binary-encoded representation with +.Fa nfbits +of binary precision. +.Fa dfv +must be passed as a preprocessor literal to preserve leading zeroes. +The returned value can be used to set a Q number's fractional bits, for example +using +.Fn Q_SFVAL . +.Pp +All of those functions operate on +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 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 +For more details, see +.Xr qmath 3 . +.Sh RETURN VALUES +.Fn Q_INI +returns the initialised Q number which can be used to chain initialise +additional Q numbers. +.Pp +.Fn Q_TOSTR +returns a pointer to the '\\0' C-string terminator appended to +.Fa s +after the rendered numeric data, or NULL on buffer overflow. +.Pp +.Fn Q_DFV2BFV +returns the binary-encoded representation of decimal fractional value +.Fa dfv +with +.Fa nfbits +of binary precision. +.Sh SEE ALSO +.Xr errno 2 , +.Xr qmath 3 , +.Xr stdint 7 +.Sh HISTORY +The +.Xr qmath 3 +functions first appeared in +.Fx 13.0 . +.Sh AUTHORS +.An -nosplit +The +.Xr qmath 3 +functions and this manual page were written by +.An Lawrence Stewart Aq Mt lstewart@FreeBSD.org +and sponsored by Netflix, Inc. Property changes on: head/share/man/man3/Q_INI.3 ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/share/man/man3/Q_IRAWMASK.3 =================================================================== --- head/share/man/man3/Q_IRAWMASK.3 (nonexistent) +++ head/share/man/man3/Q_IRAWMASK.3 (revision 351544) @@ -0,0 +1,125 @@ +.\" +.\" 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. +.\" +.\" $FreeBSD$ +.\" +.Dd July 8, 2018 +.Dt Q_IRAWMASK 3 +.Os +.Sh NAME +.Nm Q_IRAWMASK , +.Nm Q_GIRAW , +.Nm Q_GIABSVAL , +.Nm Q_GIVAL , +.Nm Q_SIVAL +.Nd fixed-point math functions which manipulate the integer data bits +.Sh SYNOPSIS +.In sys/qmath.h +.Ft ITYPE +.Fn Q_IRAWMASK "QTYPE q" +.Ft ITYPE +.Fn Q_GIRAW "QTYPE q" +.Ft ITYPE +.Fn Q_GIABSVAL "QTYPE q" +.Ft ITYPE +.Fn Q_GIVAL "QTYPE q" +.Ft QTYPE +.Fn Q_SIVAL "QTYPE q" "ITYPE iv" +.Sh DESCRIPTION +.Fn Q_IRAWMASK +returns a +.Fa q Ns -specific +bit mask for +.Fa q Ap s +integer data bits. +.Pp +.Fn Q_GIRAW +returns +.Fa q Ap s +raw masked integer data bits. +.Pp +.Fn Q_GIABSVAL +and +.Fn Q_GIVAL +return the absolute and real values of +.Fa q Ap s +integer data bits respectively. +.Pp +.Fn Q_SIVAL +sets +.Fa q Ap s +integer data bits to the value +.Fa iv . +.Pp +All of those functions operate on +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 as +.Fa QTYPE . +The +.Fa ITYPE +refers to the +.Xr stdint 7 +integer types. +.Pp +For more details, see +.Xr qmath 3 . +.Sh RETURN VALUES +.Fn Q_IRAWMASK , +.Fn Q_GIRAW , +.Fn Q_GIABSVAL +and +.Fn Q_GIVAL +return their respective values as integers of the same underlying ITYPE as +.Fa q . +.Pp +.Fn Q_SIVAL +returns the value of +.Fa q +post change. +.Sh SEE ALSO +.Xr errno 2 , +.Xr qmath 3 , +.Xr stdint 7 +.Sh HISTORY +The +.Xr qmath 3 +functions first appeared in +.Fx 13.0 . +.Sh AUTHORS +.An -nosplit +The +.Xr qmath 3 +functions and this manual page were written by +.An Lawrence Stewart Aq Mt lstewart@FreeBSD.org +and sponsored by Netflix, Inc. Property changes on: head/share/man/man3/Q_IRAWMASK.3 ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/share/man/man3/Q_QABS.3 =================================================================== --- head/share/man/man3/Q_QABS.3 (nonexistent) +++ head/share/man/man3/Q_QABS.3 (revision 351544) @@ -0,0 +1,101 @@ +.\" +.\" 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. +.\" +.\" $FreeBSD$ +.\" +.Dd July 8, 2018 +.Dt Q_QABS 3 +.Os +.Sh NAME +.Nm Q_QABS , +.Nm Q_Q2S , +.Nm Q_Q2F +.Nd fixed-point math functions which operate on a single Q number +.Sh SYNOPSIS +.In sys/qmath.h +.Ft QTYPE +.Fn Q_QABS "QTYPE q" +.Ft double +.Fn Q_Q2D "QTYPE q" +.Ft float +.Fn Q_Q2F "QTYPE q" +.Sh DESCRIPTION +The +.Fn Q_QABS +function returns an absolute value representation of +.Fa q . +.Pp +The +.Fn Q_Q2D +and +.Fn Q_Q2F +functions return the double and float representations of +.Fa q +respectively. +.Pp +All of those functions operate on +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 as +.Fa QTYPE . +.Pp +For more details, see +.Xr qmath 3 . +.Sh RETURN VALUES +.Fn Q_QABS +function returns a QTYPE that is identical to that of +.Fa q . +.Pp +The +.Fn Q_Q2D +and +.Fn Q_Q2F +functions return the double and float representations of +.Fa q +respectively. +.Sh SEE ALSO +.Xr errno 2 , +.Xr qmath 3 , +.Xr stdint 7 +.Sh HISTORY +The +.Xr qmath 3 +functions first appeared in +.Fx 13.0 . +.Sh AUTHORS +.An -nosplit +The +.Xr qmath 3 +functions and this manual page were written by +.An Lawrence Stewart Aq Mt lstewart@FreeBSD.org +and sponsored by Netflix, Inc. Property changes on: head/share/man/man3/Q_QABS.3 ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/share/man/man3/Q_QADDI.3 =================================================================== --- head/share/man/man3/Q_QADDI.3 (nonexistent) +++ head/share/man/man3/Q_QADDI.3 (revision 351544) @@ -0,0 +1,134 @@ +.\" +.\" 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. +.\" +.\" $FreeBSD$ +.\" +.Dd July 8, 2018 +.Dt Q_QADDI 3 +.Os +.Sh NAME +.Nm Q_QADDI , +.Nm Q_QDIVI , +.Nm Q_QMULI , +.Nm Q_QSUBI , +.Nm Q_QFRACI , +.Nm Q_QCPYVALI +.Nd fixed-point math functions which apply integers to a Q number +.Sh SYNOPSIS +.In sys/qmath.h +.Ft int +.Fn Q_QADDI "QTYPE *a" "ITYPE b" +.Ft int +.Fn Q_QDIVI "QTYPE *a" "ITYPE b" +.Ft int +.Fn Q_QMULI "QTYPE *a" "ITYPE b" +.Ft int +.Fn Q_QSUBI "QTYPE *a" "ITYPE b" +.Ft int +.Fn Q_QFRACI "QTYPE *q" "ITYPE n" "ITYPE d" +.Ft int +.Fn Q_QCPYVALI "QTYPE *q" "ITYPE i" +.Sh DESCRIPTION +The +.Fn Q_QADDI , +.Fn Q_QDIVI , +.Fn Q_QMULI +and +.Fn Q_QSUBI +functions add, divide, multiply or subtract +.Fa b +to/by/from +.Fa a +respectively, storing the result in +.Fa a . +.Pp +The +.Fn Q_QFRACI +function computes the fraction +.Fa n +divided by +.Fa d +and stores the fixed-point result in +.Fa q . +.Pp +The +.Fn Q_QCPYVALI +function overwrites +.Fa q Ap s +integer and fractional bits with the Q representation of integer value +.Fa i . +.Pp +All of those functions operate on +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 as +.Fa QTYPE . +The +.Fa ITYPE +refers to the +.Xr stdint 7 +integer types. +.Pp +For more details, see +.Xr qmath 3 . +.Sh RETURN VALUES +.Fn Q_QADDI , +.Fn Q_QDIVI , +.Fn Q_QMULI , +.Fn Q_QSUBI , +.Fn Q_QFRACI +and +.Fn Q_QCPYVALI +functions return 0 on success, or an errno on failure. +.Er EINVAL +is returned for divide-by-zero. +.Er EOVERFLOW +and +.Er ERANGE +are returned for overflow and underflow respectively. +.Sh SEE ALSO +.Xr errno 2 , +.Xr qmath 3 , +.Xr stdint 7 +.Sh HISTORY +The +.Xr qmath 3 +functions first appeared in +.Fx 13.0 . +.Sh AUTHORS +.An -nosplit +The +.Xr qmath 3 +functions and this manual page were written by +.An Lawrence Stewart Aq Mt lstewart@FreeBSD.org +and sponsored by Netflix, Inc. Property changes on: head/share/man/man3/Q_QADDI.3 ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/share/man/man3/Q_QADDQ.3 =================================================================== --- head/share/man/man3/Q_QADDQ.3 (nonexistent) +++ head/share/man/man3/Q_QADDQ.3 (revision 351544) @@ -0,0 +1,175 @@ +.\" +.\" 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. +.\" +.\" $FreeBSD$ +.\" +.Dd July 8, 2018 +.Dt Q_QADDQ 3 +.Os +.Sh NAME +.Nm Q_QADDQ , +.Nm Q_QDIVQ , +.Nm Q_QMULQ , +.Nm Q_QSUBQ , +.Nm Q_NORMPREC , +.Nm Q_QMAXQ , +.Nm Q_QMINQ , +.Nm Q_QCLONEQ , +.Nm Q_CPYVALQ +.Nd fixed-point math functions which operate on two Q numbers +.Sh SYNOPSIS +.In sys/qmath.h +.Ft int +.Fn Q_QADDQ "QTYPE *a" "QTYPE b" +.Ft int +.Fn Q_QDIVQ "QTYPE *a" "QTYPE b" +.Ft int +.Fn Q_QMULQ "QTYPE *a" "QTYPE b" +.Ft int +.Fn Q_QSUBQ "QTYPE *a" "QTYPE b" +.Ft int +.Fn Q_NORMPREC "QTYPE *a" "QTYPE *b" +.Ft QTYPE +.Fn Q_QMAXQ "QTYPE a" "QTYPE b" +.Ft QTYPE +.Fn Q_QMINQ "QTYPE a" "QTYPE b" +.Ft int +.Fn Q_QCLONEQ "QTYPE *l" "QTYPE r" +.Ft int +.Fn Q_QCPYVALQ "QTYPE *l" "QTYPE r" +.Sh DESCRIPTION +The +.Fn Q_QADDQ , +.Fn Q_QDIVQ , +.Fn Q_QMULQ , +and +.Fn Q_QSUBQ +functions add, divide, multiply or subtract +.Fa b +to/by/from +.Fa a +respectively, storing the result in +.Fa a . +Both arguments must be initialized with the same fractional radix point. +.Pp +The +.Fn Q_NORMPREC +function attempts to normalise the precision of +.Fa a +and +.Fa b +if they differ. +The greater of the two precisions is preferred if possible, unless that would +truncate integer component data for the other operand, in which case the highest +precision that preserves the integer component of both +.Fa a +and +.Fa b +is selected. +.Pp +The +.Fn Q_QMAXQ +and +.Fn Q_QMINQ +functions return the larger or smaller of +.Fa a +and +.Fa b +respectively. +.Pp +The +.Fn Q_QCLONEQ +and +.Fn Q_QCPYVALQ +functions attempt to store identical or representational copies of +.Fa r , +in +.Fa l +respectively. +An identical Q number produced by cloning copies the control bits as well as the +verbatim integer/fractional bits. +A representational copy only copies the values of +.Fa r Ap s +integer and fractional bits, representing them in the bits available per +.Fa l Ap s +Q format. +.Pp +All of those functions operate on 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 as +.Fa QTYPE . +.Pp +For more details, see +.Xr qmath 3 . +.Sh RETURN VALUES +The +.Fn Q_QADDQ , +.Fn Q_QDIVQ , +.Fn Q_QMULQ , +.Fn Q_QSUBQ +.Fn Q_NORMPREC , +.Fn Q_QCLONEQ +and +.Fn Q_QCPYVALQ +functions return 0 on success, or an errno on failure. +.Er EINVAL +is returned for divide-by-zero. +.Er EOVERFLOW +and +.Er ERANGE +are returned for overflow and underflow respectively. +.Er ERANGE is also returned when the precision of arguments +does not match. +.Pp +The +.Fn Q_QMAXQ +and +.Fn Q_QMINQ +functions return the numerically larger or smaller of their two inputs +respectively. +.Sh SEE ALSO +.Xr errno 2 , +.Xr qmath 3 , +.Xr stdint 7 +.Sh HISTORY +The +.Xr qmath 3 +functions first appeared in +.Fx 13.0 . +.Sh AUTHORS +.An -nosplit +The +.Xr qmath 3 +functions and this manual page were written by +.An Lawrence Stewart Aq Mt lstewart@FreeBSD.org +and sponsored by Netflix, Inc. Property changes on: head/share/man/man3/Q_QADDQ.3 ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/share/man/man3/Q_SIGNED.3 =================================================================== --- head/share/man/man3/Q_SIGNED.3 (nonexistent) +++ head/share/man/man3/Q_SIGNED.3 (revision 351544) @@ -0,0 +1,210 @@ +.\" +.\" 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. +.\" +.\" $FreeBSD$ +.\" +.Dd July 8, 2018 +.Dt Q_SIGNED 3 +.Os +.Sh NAME +.Nm Q_SIGNED , +.Nm Q_LTZ , +.Nm Q_PRECEQ , +.Nm Q_QLTQ , +.Nm Q_QLEQ , +.Nm Q_QGTQ , +.Nm Q_QGEQ , +.Nm Q_QEQ , +.Nm Q_QNEQ , +.Nm Q_OFLOW , +.Nm Q_RELPREC +.Nd fixed-point math comparison and logic functions +.Sh SYNOPSIS +.In sys/qmath.h +.Ft bool +.Fn Q_SIGNED "NTYPE n" +.Ft bool +.Fn Q_LTZ "NTYPE n" +.Ft bool +.Fn Q_PRECEQ "QTYPE a" "QTYPE b" +.Ft bool +.Fn Q_QLTQ "QTYPE a" "QTYPE b" +.Ft bool +.Fn Q_QLEQ "QTYPE a" "QTYPE b" +.Ft bool +.Fn Q_QGTQ "QTYPE a" "QTYPE b" +.Ft bool +.Fn Q_QGEQ "QTYPE a" "QTYPE b" +.Ft bool +.Fn Q_QEQ "QTYPE a" "QTYPE b" +.Ft bool +.Fn Q_QNEQ "QTYPE a" "QTYPE b" +.Ft bool +.Fn Q_OFLOW "QTYPE q" "ITYPE iv" +.Ft int +.Fn Q_RELPREC "QTYPE a" "QTYPE b" +.Sh DESCRIPTION +.Fn Q_SIGNED +returns +.Ft true +if the numeric data type passed in as +.Fa n +is signed, or +.Ft false +otherwise. +.Pp +.Fn Q_LTZ +returns +.Ft true +if the numeric value +passed in as +.Fa n +is negative +.Pq requires types which use the MSB as the sign bit , +or +.Ft false +otherwise. +.Pp +.Fn Q_PRECEQ +returns +.Ft true +if the number of +.Fa a +and +.Fa b +fractional bits is the same, +.Ft false +otherwise. +.Pp +The +.Fn Q_QLTQ , +.Fn Q_QLEQ , +.Fn Q_QGTQ , +.Fn Q_QGEQ , +.Fn Q_QEQ +and +.Fn Q_QNEQ +functions compare two Q numbers, returning +.Ft true +if +.Fa a +is less than, less than or equal to, greater than, greater than or equal to, +equal to, or not equal to +.Fa b +respectively, or +.Ft false +otherwise. +The integral and fractional values are used to perform the comparison, without +explicit concern for the underlying number of integer versus fractional bits. +.Pp +.Fn Q_OFLOW +returns +.Ft true +if integer value +.Fa iv +cannot be stored in +.Fa q +without truncation, or false otherwise. +.Pp +.Fn Q_RELPREC +returns the relative precision of +.Fa a +versus +.Fa b . +In terms of +.Em Qm.n +notation, this function returns the difference between the +.Em n +values of +.Fa a +and +.Fa b . +For example, a return value of +4 means that +.Fa a +has an additional 4 bits of fractional precision compared to +.Fa b . +.Pp +All of those functions operate on +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 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 +For more details, see +.Xr qmath 3 . +.Sh RETURN VALUES +The +.Fn Q_SIGNED , +.Fn Q_LTZ , +.Fn Q_PRECEQ , +.Fn Q_QLTQ , +.Fn Q_QLEQ , +.Fn Q_QGTQ , +.Fn Q_QGEQ , +.Fn Q_QEQ , +.Fn Q_QNEQ +and +.Fn Q_OFLOW +functions return expressions that evaluate to boolean +.Vt true +or +.Vt false . +.Pp +.Fn Q_RELPREC +returns the relative precision difference as a signed integer. +.Sh SEE ALSO +.Xr errno 2 , +.Xr qmath 3 , +.Xr stdint 7 +.Sh HISTORY +The +.Xr qmath 3 +functions first appeared in +.Fx 13.0 . +.Sh AUTHORS +.An -nosplit +The +.Xr qmath 3 +functions and this manual page were written by +.An Lawrence Stewart Aq Mt lstewart@FreeBSD.org +and sponsored by Netflix, Inc. Property changes on: head/share/man/man3/Q_SIGNED.3 ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/share/man/man3/Q_SIGNSHFT.3 =================================================================== --- head/share/man/man3/Q_SIGNSHFT.3 (nonexistent) +++ head/share/man/man3/Q_SIGNSHFT.3 (revision 351544) @@ -0,0 +1,147 @@ +.\" +.\" 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. +.\" +.\" $FreeBSD$ +.\" +.Dd July 8, 2018 +.Dt Q_SIGNSHFT 3 +.Os +.Sh NAME +.Nm Q_SIGNSHFT , +.Nm Q_SSIGN , +.Nm Q_CRAWMASK , +.Nm Q_SRAWMASK , +.Nm Q_GCRAW , +.Nm Q_GCVAL , +.Nm Q_SCVAL +.Nd fixed-point math functions which manipulate the control/sign data bits +.Sh SYNOPSIS +.In sys/qmath.h +.Ft uint32_t +.Fn Q_SIGNSHFT "QTYPE q" +.Ft QTYPE +.Fn Q_SSIGN "QTYPE q" "bool isneg" +.Ft ITYPE +.Fn Q_CRAWMASK "QTYPE q" +.Ft ITYPE +.Fn Q_SRAWMASK "QTYPE q" +.Ft ITYPE +.Fn Q_GCRAW "QTYPE q" +.Ft ITYPE +.Fn Q_GCVAL "QTYPE q" +.Ft QTYPE +.Fn Q_SCVAL "QTYPE q" "ITYPE cv" +.Sh DESCRIPTION +.Fn Q_SIGNSHFT +gets the bit position of +.Fa q Ap s +sign bit relative to bit zero. +.Pp +.Fn Q_SSIGN +sets the sign bit of +.Fa q +based on the boolean +.Fa isneg . +.Pp +.Fn Q_CRAWMASK +and +.Fn Q_SRAWMASK +return +.Fa q Ns -specific +bit masks for +.Fa q Ap s +control bits and sign bit respectively. +.Pp +.Fn Q_GCRAW +and +.Fn Q_GCVAL +get the raw masked control bits and value of +.Fa q Ap s +control bits respectively. +.Pp +.Fn Q_SCVAL +sets +.Fa q Ap s +control bits to the value +.Fa cv . +.Pp +All of those functions operate on +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 as +.Fa QTYPE . +The +.Fa ITYPE +refers to the +.Xr stdint 7 +integer types. +.Pp +For more details, see +.Xr qmath 3 . +.Sh RETURN VALUES +.Fn Q_SIGNSHFT +returns the sign bit's position as an integer. +.Pp +.Fn Q_SSIGN +returns the value of +.Fa q +post change. +.Pp +.Fn Q_CRAWMASK , +.Fn Q_SRAWMASK , +.Fn Q_GCRAW +and +.Fn Q_GCVAL +return their respective values as integers of the same underlying ITYPE as +.Fa q . +.Pp +.Fn Q_SCVAL +returns the value of +.Fa q +post change. +.Sh SEE ALSO +.Xr errno 2 , +.Xr qmath 3 , +.Xr stdint 7 +.Sh HISTORY +The +.Xr qmath 3 +functions first appeared in +.Fx 13.0 . +.Sh AUTHORS +.An -nosplit +The +.Xr qmath 3 +functions and this manual page were written by +.An Lawrence Stewart Aq Mt lstewart@FreeBSD.org +and sponsored by Netflix, Inc. Property changes on: head/share/man/man3/Q_SIGNSHFT.3 ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/share/man/man3/qmath.3 =================================================================== --- head/share/man/man3/qmath.3 (nonexistent) +++ head/share/man/man3/qmath.3 (revision 351544) @@ -0,0 +1,389 @@ +.\" +.\" 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. +.\" +.\" $FreeBSD$ +.\" +.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. Property changes on: head/share/man/man3/qmath.3 ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/sys/sys/qmath.h =================================================================== --- head/sys/sys/qmath.h (nonexistent) +++ head/sys/sys/qmath.h (revision 351544) @@ -0,0 +1,632 @@ +/*- + * 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. + * 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 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. + * + * $FreeBSD$ + */ + +/* + * Data types and APIs for fixed-point math based on the "Q" number format. + * + * Author: Lawrence Stewart + * + * The 3 LSBs of all base data types are reserved for embedded control data: + * bits 1-2 specify the radix point shift index i.e. 00,01,10,11 == 1,2,3,4 + * bit 3 specifies the radix point shift index multiplier as 2 (0) or 16 (1) + * + * This scheme can therefore represent Q numbers with [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 depends on the underlying storage type chosen. + */ + +#ifndef _SYS_QMATH_H_ +#define _SYS_QMATH_H_ + +#include + +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; +/* typedef int128_t s128q_t; Not yet */ +/* typedef uint128_t u128q_t; Not yet */ +typedef s64q_t smaxq_t; +typedef u64q_t umaxq_t; + +/* The underlying base type of 'q'. */ +#define Q_BT(q) __typeof(q) + +/* Type-cast variable 'v' to the same underlying type as 'q'. */ +#define Q_TC(q, v) ((Q_BT(q))(v)) + +/* Number of total bits associated with the data type underlying 'q'. */ +#define Q_NTBITS(q) ((uint32_t)(sizeof(q) << 3)) + +/* Number of LSBs reserved for control data. */ +#define Q_NCBITS ((uint32_t)3) + +/* Number of control-encoded bits reserved for fractional component data. */ +#define Q_NFCBITS(q) \ + ((uint32_t)(((Q_GCRAW(q) & 0x3) + 1) << ((Q_GCRAW(q) & 0x4) ? 4 : 1))) + +/* Min/max number of bits that can be reserved for fractional component data. */ +#define Q_MINNFBITS(q) ((uint32_t)(2)) +#define Q_MAXNFBITS(q) ((uint32_t)(Q_NTBITS(q) - Q_SIGNED(q) - Q_NCBITS)) + +/* + * Number of bits actually reserved for fractional component data. This can be + * less than the value returned by Q_NFCBITS() as we treat any excess + * control-encoded number of bits for the underlying data type as meaning all + * available bits are reserved for fractional component data i.e. zero int bits. + */ +#define Q_NFBITS(q) \ + (Q_NFCBITS(q) > Q_MAXNFBITS(q) ? Q_MAXNFBITS(q) : Q_NFCBITS(q)) + +/* Number of bits available for integer component data. */ +#define Q_NIBITS(q) ((uint32_t)(Q_NTBITS(q) - Q_RPSHFT(q) - Q_SIGNED(q))) + +/* The radix point offset relative to the LSB. */ +#define Q_RPSHFT(q) (Q_NCBITS + Q_NFBITS(q)) + +/* The sign bit offset relative to the LSB. */ +#define Q_SIGNSHFT(q) (Q_NTBITS(q) - 1) + +/* Set the sign bit to 0 ('isneg' is F) or 1 ('isneg' is T). */ +#define Q_SSIGN(q, isneg) \ + ((q) = ((Q_SIGNED(q) && (isneg)) ? (q) | (1ULL << Q_SIGNSHFT(q)) : \ + (q) & ~(1ULL << Q_SIGNSHFT(q)))) + +/* Manipulate the 'q' bits holding control/sign data. */ +#define Q_CRAWMASK(q) 0x7ULL +#define Q_SRAWMASK(q) (1ULL << Q_SIGNSHFT(q)) +#define Q_GCRAW(q) ((q) & Q_CRAWMASK(q)) +#define Q_GCVAL(q) Q_GCRAW(q) +#define Q_SCVAL(q, cv) ((q) = ((q) & ~Q_CRAWMASK(q)) | (cv)) + +/* Manipulate the 'q' bits holding combined integer/fractional data. */ +#define Q_IFRAWMASK(q) \ + Q_TC(q, Q_SIGNED(q) ? ~(Q_SRAWMASK(q) | Q_CRAWMASK(q)) : ~Q_CRAWMASK(q)) +#define Q_IFMAXVAL(q) Q_TC(q, Q_IFRAWMASK(q) >> Q_NCBITS) +#define Q_IFMINVAL(q) Q_TC(q, Q_SIGNED(q) ? -Q_IFMAXVAL(q) : 0) +#define Q_IFVALIMASK(q) Q_TC(q, ~Q_IFVALFMASK(q)) +#define Q_IFVALFMASK(q) Q_TC(q, (1ULL << Q_NFBITS(q)) - 1) +#define Q_GIFRAW(q) Q_TC(q, (q) & Q_IFRAWMASK(q)) +#define Q_GIFABSVAL(q) Q_TC(q, Q_GIFRAW(q) >> Q_NCBITS) +#define Q_GIFVAL(q) Q_TC(q, Q_LTZ(q) ? -Q_GIFABSVAL(q) : Q_GIFABSVAL(q)) +#define Q_SIFVAL(q, ifv) \ + ((q) = ((q) & (~(Q_SRAWMASK(q) | Q_IFRAWMASK(q)))) | \ + (Q_TC(q, Q_ABS(ifv)) << Q_NCBITS) | \ + (Q_LTZ(ifv) ? 1ULL << Q_SIGNSHFT(q) : 0)) +#define Q_SIFVALS(q, iv, fv) \ + ((q) = ((q) & (~(Q_SRAWMASK(q) | Q_IFRAWMASK(q)))) | \ + (Q_TC(q, Q_ABS(iv)) << Q_RPSHFT(q)) | \ + (Q_TC(q, Q_ABS(fv)) << Q_NCBITS) | \ + (Q_LTZ(iv) || Q_LTZ(fv) ? 1ULL << Q_SIGNSHFT(q) : 0)) + +/* Manipulate the 'q' bits holding integer data. */ +#define Q_IRAWMASK(q) Q_TC(q, Q_IFRAWMASK(q) & ~Q_FRAWMASK(q)) +#define Q_IMAXVAL(q) Q_TC(q, Q_IRAWMASK(q) >> Q_RPSHFT(q)) +#define Q_IMINVAL(q) Q_TC(q, Q_SIGNED(q) ? -Q_IMAXVAL(q) : 0) +#define Q_GIRAW(q) Q_TC(q, (q) & Q_IRAWMASK(q)) +#define Q_GIABSVAL(q) Q_TC(q, Q_GIRAW(q) >> Q_RPSHFT(q)) +#define Q_GIVAL(q) Q_TC(q, Q_LTZ(q) ? -Q_GIABSVAL(q) : Q_GIABSVAL(q)) +#define Q_SIVAL(q, iv) \ + ((q) = ((q) & ~(Q_SRAWMASK(q) | Q_IRAWMASK(q))) | \ + (Q_TC(q, Q_ABS(iv)) << Q_RPSHFT(q)) | \ + (Q_LTZ(iv) ? 1ULL << Q_SIGNSHFT(q) : 0)) + +/* Manipulate the 'q' bits holding fractional data. */ +#define Q_FRAWMASK(q) Q_TC(q, ((1ULL << Q_NFBITS(q)) - 1) << Q_NCBITS) +#define Q_FMAXVAL(q) Q_TC(q, Q_FRAWMASK(q) >> Q_NCBITS) +#define Q_GFRAW(q) Q_TC(q, (q) & Q_FRAWMASK(q)) +#define Q_GFABSVAL(q) Q_TC(q, Q_GFRAW(q) >> Q_NCBITS) +#define Q_GFVAL(q) Q_TC(q, Q_LTZ(q) ? -Q_GFABSVAL(q) : Q_GFABSVAL(q)) +#define Q_SFVAL(q, fv) \ + ((q) = ((q) & ~(Q_SRAWMASK(q) | Q_FRAWMASK(q))) | \ + (Q_TC(q, Q_ABS(fv)) << Q_NCBITS) | \ + (Q_LTZ(fv) ? 1ULL << Q_SIGNSHFT(q) : 0)) + +/* + * Calculate the number of bits required per 'base' digit, rounding up or down + * for non power-of-two bases. + */ +#define Q_BITSPERBASEDOWN(base) (flsll(base) - 1) +#define Q_BITSPERBASEUP(base) (flsll(base) - (__builtin_popcountll(base) == 1)) +#define Q_BITSPERBASE(base, rnd) Q_BITSPERBASE##rnd(base) + +/* + * Upper bound number of digits required to render 'nbits' worth of integer + * component bits with numeric base 'base'. Overestimates for power-of-two + * bases. + */ +#define Q_NIBITS2NCHARS(nbits, base) \ +({ \ + int _bitsperbase = Q_BITSPERBASE(base, DOWN); \ + (((nbits) + _bitsperbase - 1) / _bitsperbase); \ +}) + +#define Q_NFBITS2NCHARS(nbits, base) (nbits) + +/* + * Maximum number of chars required to render 'q' as a C-string of base 'base'. + * Includes space for sign, radix point and NUL-terminator. + */ +#define Q_MAXSTRLEN(q, base) \ + (2 + Q_NIBITS2NCHARS(Q_NIBITS(q), base) + \ + Q_NFBITS2NCHARS(Q_NFBITS(q), base) + Q_SIGNED(q)) + +/* Yield the next char from integer bits. */ +#define Q_IBITS2CH(q, bits, base) \ +({ \ + __typeof(bits) _tmp = (bits) / (base); \ + int _idx = (bits) - (_tmp * (base)); \ + (bits) = _tmp; \ + "0123456789abcdef"[_idx]; \ +}) + +/* Yield the next char from fractional bits. */ +#define Q_FBITS2CH(q, bits, base) \ +({ \ + int _carry = 0, _idx, _nfbits = Q_NFBITS(q), _shift = 0; \ + /* \ + * Normalise enough MSBs to yield the next digit, multiply by the \ + * base, and truncate residual fractional bits post multiplication. \ + */ \ + if (_nfbits > Q_BITSPERBASEUP(base)) { \ + /* Break multiplication into two steps to ensure no overflow. */\ + _shift = _nfbits >> 1; \ + _carry = (((bits) & ((1ULL << _shift) - 1)) * (base)) >> _shift;\ + } \ + _idx = ((((bits) >> _shift) * (base)) + _carry) >> (_nfbits - _shift);\ + (bits) *= (base); /* With _idx computed, no overflow concern. */ \ + (bits) &= (1ULL << _nfbits) - 1; /* Exclude residual int bits. */ \ + "0123456789abcdef"[_idx]; \ +}) + +/* + * Render the C-string representation of 'q' into 's'. Returns a pointer to the + * final '\0' to allow for easy calculation of the rendered length and easy + * appending to the C-string. + */ +#define Q_TOSTR(q, prec, base, s, slen) \ +({ \ + char *_r, *_s = s; \ + int _i; \ + if (Q_LTZ(q) && ((ptrdiff_t)(slen)) > 0) \ + *_s++ = '-'; \ + Q_BT(q) _part = Q_GIABSVAL(q); \ + _r = _s; \ + do { \ + /* Render integer chars in reverse order. */ \ + if ((_s - (s)) < ((ptrdiff_t)(slen))) \ + *_s++ = Q_IBITS2CH(q, _part, base); \ + else \ + _r = NULL; \ + } while (_part > 0 && _r != NULL); \ + if (!((_s - (s)) < ((ptrdiff_t)(slen)))) \ + _r = NULL; \ + _i = (_s - _r) >> 1; /* N digits requires int(N/2) swaps. */ \ + while (_i-- > 0 && _r != NULL) { \ + /* Work from middle out to reverse integer chars. */ \ + *_s = *(_r + _i); /* Stash LHS char temporarily. */ \ + *(_r + _i) = *(_s - _i - 1); /* Copy RHS char to LHS. */\ + *(_s - _i - 1) = *_s; /* Copy LHS char to RHS. */ \ + } \ + _i = (prec); \ + if (_i != 0 && _r != NULL) { \ + if ((_s - (s)) < ((ptrdiff_t)(slen))) \ + *_s++ = '.'; \ + else \ + _r = NULL; \ + _part = Q_GFABSVAL(q); \ + if (_i < 0 || _i > (int)Q_NFBITS(q)) \ + _i = Q_NFBITS(q); \ + while (_i-- > 0 && _r != NULL) { \ + /* Render fraction chars in correct order. */ \ + if ((_s - (s)) < ((ptrdiff_t)(slen))) \ + *_s++ = Q_FBITS2CH(q, _part, base); \ + else \ + _r = NULL; \ + } \ + } \ + if ((_s - (s)) < ((ptrdiff_t)(slen)) && _r != NULL) \ + *_s = '\0'; \ + else { \ + _r = NULL; \ + if (((ptrdiff_t)(slen)) > 0) \ + *(s) = '\0'; \ + } \ + /* Return a pointer to the '\0' or NULL on overflow. */ \ + (_r != NULL ? _s : _r); \ +}) + +/* Left shift an integral value to align with the int bits of 'q'. */ +#define Q_SHL(q, iv) \ + (Q_LTZ(iv) ? -(Q_ABS(iv) << Q_NFBITS(q)) : \ + Q_TC(q, iv) << Q_NFBITS(q)) + +/* Calculate the relative fractional precision between 'a' and 'b' in bits. */ +#define Q_RELPREC(a, b) ((int)Q_NFBITS(a) - (int)Q_NFBITS(b)) + +/* + * Determine control bits for the desired 'rpshft' radix point shift. Rounds up + * to the nearest valid shift supported by the encoding scheme. + */ +#define Q_CTRLINI(rpshft) \ + (((rpshft) <= 8) ? (((rpshft) - 1) >> 1) : (0x4 | (((rpshft) - 1) >> 4))) + +/* + * Convert decimal fractional value 'dfv' to its binary-encoded representation + * with 'nfbits' of binary precision. 'dfv' must be passed as a preprocessor + * literal to preserve leading zeroes. The returned result can be used to set a + * Q number's fractional bits e.g. using Q_SFVAL(). + */ +#define Q_DFV2BFV(dfv, nfbits) \ +({ \ + uint64_t _bfv = 0, _thresh = 5, _tmp = dfv; \ + int _i = sizeof(""#dfv) - 1; \ + /* \ + * Compute decimal threshold to determine which \ + * conversion rounds will yield a binary 1. \ + */ \ + while (--_i > 0) {_thresh *= 10;} \ + _i = (nfbits) - 1; \ + while (_i >= 0) { \ + if (_thresh <= _tmp) { \ + _bfv |= 1ULL << _i; \ + _tmp = _tmp - _thresh; \ + } \ + _i--; _tmp <<= 1; \ + } \ + _bfv; \ +}) + +/* + * Initialise 'q' with raw integer value 'iv', decimal fractional value 'dfv', + * and radix point shift 'rpshft'. Must be done in two steps in case 'iv' + * depends on control bits being set e.g. when passing Q_INTMAX(q) as 'iv'. + */ +#define Q_INI(q, iv, dfv, rpshft) \ +({ \ + (*(q)) = Q_CTRLINI(rpshft); \ + Q_SIFVALS(*(q), iv, Q_DFV2BFV(dfv, Q_NFBITS(*(q)))); \ +}) + +/* Test if 'a' and 'b' fractional precision is the same (T) or not (F). */ +#define Q_PRECEQ(a, b) (Q_NFBITS(a) == Q_NFBITS(b)) + +/* Test if 'n' is a signed type (T) or not (F). Works with any numeric type. */ +#define Q_SIGNED(n) (Q_TC(n, -1) < 0) + +/* + * Test if 'n' is negative. Works with any numeric type that uses the MSB as the + * sign bit, and also works with Q numbers. + */ +#define Q_LTZ(n) (Q_SIGNED(n) && ((n) & Q_SRAWMASK(n))) + +/* + * Return absolute value of 'n'. Works with any standard numeric type that uses + * the MSB as the sign bit, and is signed/unsigned type safe. + * Does not work with Q numbers; use Q_QABS() instead. + */ +#define Q_ABS(n) (Q_LTZ(n) ? -(n) : (n)) + +/* + * Return an absolute value interpretation of 'q'. + */ +#define Q_QABS(q) (Q_SIGNED(q) ? (q) & ~Q_SRAWMASK(q) : (q)) + +/* Convert 'q' to float or double representation. */ +#define Q_Q2F(q) ((float)Q_GIFVAL(q) / (float)(1ULL << Q_NFBITS(q))) +#define Q_Q2D(q) ((double)Q_GIFVAL(q) / (double)(1ULL << Q_NFBITS(q))) + +/* Numerically compare 'a' and 'b' as whole numbers using provided operators. */ +#define Q_QCMPQ(a, b, intcmp, fraccmp) \ + ((Q_GIVAL(a) intcmp Q_GIVAL(b)) || \ + ((Q_GIVAL(a) == Q_GIVAL(b)) && (Q_GFVAL(a) fraccmp Q_GFVAL(b)))) + +/* Test if 'a' is numerically less than 'b' (T) or not (F). */ +#define Q_QLTQ(a, b) Q_QCMPQ(a, b, <, <) + +/* Test if 'a' is numerically less than or equal to 'b' (T) or not (F). */ +#define Q_QLEQ(a, b) Q_QCMPQ(a, b, <, <=) + +/* Test if 'a' is numerically greater than 'b' (T) or not (F). */ +#define Q_QGTQ(a, b) Q_QCMPQ(a, b, >, >) + +/* Test if 'a' is numerically greater than or equal to 'b' (T) or not (F). */ +#define Q_QGEQ(a, b) Q_QCMPQ(a, b, >, >=) + +/* Test if 'a' is numerically equal to 'b' (T) or not (F). */ +#define Q_QEQ(a, b) Q_QCMPQ(a, b, ==, ==) + +/* Test if 'a' is numerically not equal to 'b' (T) or not (F). */ +#define Q_QNEQ(a, b) Q_QCMPQ(a, b, !=, !=) + +/* Returns the numerically larger of 'a' and 'b'. */ +#define Q_QMAXQ(a, b) (Q_GT(a, b) ? (a) : (b)) + +/* Returns the numerically smaller of 'a' and 'b'. */ +#define Q_QMINQ(a, b) (Q_LT(a, b) ? (a) : (b)) + +/* + * Test if 'a' can be represented by 'b' with full accuracy (T) or not (F). + * The type casting has to be done to a's type so that any truncation caused by + * the casts will not affect the logic. + */ +#define Q_QCANREPQ(a, b) \ + ((((Q_LTZ(a) && Q_SIGNED(b)) || !Q_LTZ(a)) && \ + Q_GIABSVAL(a) <= Q_TC(a, Q_IMAXVAL(b)) && \ + Q_GFABSVAL(a) <= Q_TC(a, Q_FMAXVAL(b))) ? \ + 0 : EOVERFLOW) + +/* Test if raw integer value 'i' can be represented by 'q' (T) or not (F). */ +#define Q_QCANREPI(q, i) \ + ((((Q_LTZ(i) && Q_SIGNED(q)) || !Q_LTZ(i)) && \ + Q_ABS(i) <= Q_TC(i, Q_IMAXVAL(q))) ? 0 : EOVERFLOW) + +/* + * Returns a Q variable debug format string with appropriate modifiers and + * padding relevant to the underlying Q data type. + */ +#define Q_DEBUGFMT_(prefmt, postfmt, mod, hexpad) \ + prefmt \ + /* Var name + address. */ \ + "\"%s\"@%p" \ + /* Data type. */ \ + "\n\ttype=%c%dq_t, " \ + /* Qm.n notation; 'm' = # int bits, 'n' = # frac bits. */ \ + "Qm.n=Q%d.%d, " \ + /* Radix point shift relative to the underlying data type's LSB. */ \ + "rpshft=%d, " \ + /* Min/max integer values which can be represented. */ \ + "imin=0x%0" #mod "x, " \ + "imax=0x%0" #mod "x" \ + /* Raw hex dump of all bits. */ \ + "\n\tqraw=0x%0" #hexpad #mod "x" \ + /* Bit masks for int/frac/ctrl bits. */ \ + "\n\timask=0x%0" #hexpad #mod "x, " \ + "fmask=0x%0" #hexpad #mod "x, " \ + "cmask=0x%0" #hexpad #mod "x, " \ + "ifmask=0x%0" #hexpad #mod "x" \ + /* Hex dump of masked int bits; 'iraw' includes shift */ \ + "\n\tiraw=0x%0" #hexpad #mod "x, " \ + "iabsval=0x%" #mod "x, " \ + "ival=0x%" #mod "x" \ + /* Hex dump of masked frac bits; 'fraw' includes shift */ \ + "\n\tfraw=0x%0" #hexpad #mod "x, " \ + "fabsval=0x%" #mod "x, " \ + "fval=0x%" #mod "x" \ + "%s" \ + postfmt + +#define Q_DEBUGFMT(q, prefmt, postfmt) \ + sizeof(q) == 8 ? Q_DEBUGFMT_(prefmt, postfmt, j, 16) : \ + sizeof(q) == 4 ? Q_DEBUGFMT_(prefmt, postfmt, , 8) : \ + sizeof(q) == 2 ? Q_DEBUGFMT_(prefmt, postfmt, h, 4) : \ + sizeof(q) == 1 ? Q_DEBUGFMT_(prefmt, postfmt, hh, 2) : \ + prefmt "\"%s\"@%p: invalid" postfmt \ + +/* + * Returns a format string and data suitable for printf-like rendering + * e.g. Print to console with a trailing newline: printf(Q_DEBUG(q, "", "\n")); + */ +#define Q_DEBUG(q, prefmt, postfmt, incfmt) \ + Q_DEBUGFMT(q, prefmt, postfmt) \ + , #q \ + , &(q) \ + , Q_SIGNED(q) ? 's' : 'u' \ + , Q_NTBITS(q) \ + , Q_NIBITS(q) \ + , Q_NFBITS(q) \ + , Q_RPSHFT(q) \ + , Q_IMINVAL(q) \ + , Q_IMAXVAL(q) \ + , (q) \ + , Q_IRAWMASK(q) \ + , Q_FRAWMASK(q) \ + , Q_TC(q, Q_CRAWMASK(q)) \ + , Q_IFRAWMASK(q) \ + , Q_GIRAW(q) \ + , Q_GIABSVAL(q) \ + , Q_GIVAL(q) \ + , Q_GFRAW(q) \ + , Q_GFABSVAL(q) \ + , Q_GFVAL(q) \ + , (incfmt) ? Q_DEBUGFMT(q, "\nfmt:", "") : "" \ + +/* + * If precision differs, attempt to normalise to the greater precision that + * preserves the integer component of both 'a' and 'b'. + */ +#define Q_NORMPREC(a, b) \ +({ \ + int _perr = 0, _relprec = Q_RELPREC(*(a), b); \ + if (_relprec != 0) \ + _perr = ERANGE; /* XXXLAS: Do precision normalisation! */\ + _perr; \ +}) + +/* Clone r's control bits and int/frac value into 'l'. */ +#define Q_QCLONEQ(l, r) \ +({ \ + Q_BT(*(l)) _l = Q_GCVAL(r); \ + int _err = Q_QCANREPQ(r, _l); \ + if (!_err) { \ + *(l) = _l; \ + Q_SIFVAL(*(l), Q_GIFVAL(r)); \ + } \ + _err; \ +}) + +/* Copy r's int/frac vals into 'l', retaining 'l's precision and signedness. */ +#define Q_QCPYVALQ(l, r) \ +({ \ + int _err = Q_QCANREPQ(r, *(l)); \ + if (!_err) \ + Q_SIFVALS(*(l), Q_GIVAL(r), Q_GFVAL(r)); \ + _err; \ +}) + +#define Q_QADDSUBQ(a, b, eop) \ +({ \ + int _aserr; \ + if ((_aserr = Q_NORMPREC(a, b))) while(0); /* NOP */ \ + else if ((eop) == '+') { \ + if (Q_IFMAXVAL(*(a)) - Q_GIFABSVAL(b) < Q_GIFVAL(*(a))) \ + _aserr = EOVERFLOW; /* [+/-a + +b] > max(a) */ \ + else \ + Q_SIFVAL(*(a), Q_GIFVAL(*(a)) + Q_TC(*(a), \ + Q_GIFABSVAL(b))); \ + } else { /* eop == '-' */ \ + if (Q_IFMINVAL(*(a)) + Q_GIFABSVAL(b) > Q_GIFVAL(*(a))) \ + _aserr = EOVERFLOW; /* [+/-a - +b] < min(a) */ \ + else \ + Q_SIFVAL(*(a), Q_GIFVAL(*(a)) - Q_TC(*(a), \ + Q_GIFABSVAL(b))); \ + } \ + _aserr; \ +}) +#define Q_QADDQ(a, b) Q_QADDSUBQ(a, b, (Q_LTZ(b) ? '-' : '+')) +#define Q_QSUBQ(a, b) Q_QADDSUBQ(a, b, (Q_LTZ(b) ? '+' : '-')) + +#define Q_QDIVQ(a, b) \ +({ \ + int _err; \ + if ((_err = Q_NORMPREC(a, b))) while(0); /* NOP */ \ + else if (Q_GIFABSVAL(b) == 0 || (!Q_SIGNED(*(a)) && Q_LTZ(b))) \ + _err = EINVAL; /* Divide by zero or cannot represent. */\ + /* XXXLAS: Handle overflow. */ \ + else if (Q_GIFABSVAL(*(a)) != 0) { /* Result expected. */ \ + Q_SIFVAL(*(a), \ + ((Q_GIVAL(*(a)) << Q_NFBITS(*(a))) / Q_GIFVAL(b)) + \ + (Q_GFVAL(b) == 0 ? 0 : \ + ((Q_GFVAL(*(a)) << Q_NFBITS(*(a))) / Q_GFVAL(b)))); \ + } \ + _err; \ +}) + +#define Q_QMULQ(a, b) \ +({ \ + int _mulerr; \ + if ((_mulerr = Q_NORMPREC(a, b))) while(0); /* NOP */ \ + else if (!Q_SIGNED(*(a)) && Q_LTZ(b)) \ + _mulerr = EINVAL; \ + else if (Q_GIFABSVAL(b) != 0 && \ + Q_IFMAXVAL(*(a)) / Q_GIFABSVAL(b) < Q_GIFABSVAL(*(a))) \ + _mulerr = EOVERFLOW; \ + else \ + Q_SIFVAL(*(a), (Q_GIFVAL(*(a)) * Q_GIFVAL(b)) >> \ + Q_NFBITS(*(a))); \ + _mulerr; \ +}) + +#define Q_QCPYVALI(q, i) \ +({ \ + int _err = Q_QCANREPI(*(q), i); \ + if (!_err) \ + Q_SIFVAL(*(q), Q_SHL(*(q), i)); \ + _err; \ +}) + +#define Q_QADDSUBI(q, i, eop) \ +({ \ + int _aserr = 0; \ + if (Q_NTBITS(*(q)) < (uint32_t)flsll(Q_ABS(i))) \ + _aserr = EOVERFLOW; /* i cannot fit in q's type. */ \ + else if ((eop) == '+') { \ + if (Q_IMAXVAL(*(q)) - Q_TC(*(q), Q_ABS(i)) < \ + Q_GIVAL(*(q))) \ + _aserr = EOVERFLOW; /* [+/-q + +i] > max(q) */ \ + else \ + Q_SIFVAL(*(q), Q_GIFVAL(*(q)) + \ + Q_SHL(*(q), Q_ABS(i))); \ + } else { /* eop == '-' */ \ + if (Q_IMINVAL(*(q)) + Q_ABS(i) > Q_GIVAL(*(q))) \ + _aserr = EOVERFLOW; /* [+/-q - +i] < min(q) */ \ + else \ + Q_SIFVAL(*(q), Q_GIFVAL(*(q)) - \ + Q_SHL(*(q), Q_ABS(i))); \ + } \ + _aserr; \ +}) +#define Q_QADDI(q, i) Q_QADDSUBI(q, i, (Q_LTZ(i) ? '-' : '+')) +#define Q_QSUBI(q, i) Q_QADDSUBI(q, i, (Q_LTZ(i) ? '+' : '-')) + +#define Q_QDIVI(q, i) \ +({ \ + int _diverr = 0; \ + if ((i) == 0 || (!Q_SIGNED(*(q)) && Q_LTZ(i))) \ + _diverr = EINVAL; /* Divide by zero or cannot represent. */\ + else if (Q_GIFABSVAL(*(q)) != 0) { /* Result expected. */ \ + Q_SIFVAL(*(q), Q_GIFVAL(*(q)) / Q_TC(*(q), i)); \ + if (Q_GIFABSVAL(*(q)) == 0) \ + _diverr = ERANGE; /* q underflow. */ \ + } \ + _diverr; \ +}) + +#define Q_QMULI(q, i) \ +({ \ + int _mulerr = 0; \ + if (!Q_SIGNED(*(q)) && Q_LTZ(i)) \ + _mulerr = EINVAL; /* Cannot represent. */ \ + else if ((i) != 0 && Q_IFMAXVAL(*(q)) / Q_TC(*(q), Q_ABS(i)) < \ + Q_GIFABSVAL(*(q))) \ + _mulerr = EOVERFLOW; \ + else \ + Q_SIFVAL(*(q), Q_GIFVAL(*(q)) * Q_TC(*(q), i)); \ + _mulerr; \ +}) + +#define Q_QFRACI(q, in, id) \ +({ \ + uint64_t _tmp; \ + int _err = 0; \ + if ((id) == 0) \ + _err = EINVAL; /* Divide by zero. */ \ + else if ((in) == 0) \ + Q_SIFVAL(*(q), in); \ + else if ((_tmp = Q_ABS(in)) > (UINT64_MAX >> Q_RPSHFT(*(q)))) \ + _err = EOVERFLOW; /* _tmp overflow. */ \ + else { \ + _tmp = Q_SHL(*(q), _tmp) / Q_ABS(id); \ + if (Q_QCANREPI(*(q), _tmp & Q_IFVALIMASK(*(q)))) \ + _err = EOVERFLOW; /* q overflow. */ \ + else { \ + Q_SIFVAL(*(q), _tmp); \ + Q_SSIGN(*(q), (Q_LTZ(in) && !Q_LTZ(id)) || \ + (!Q_LTZ(in) && Q_LTZ(id))); \ + if (_tmp == 0) \ + _err = ERANGE; /* q underflow. */ \ + } \ + } \ + _err; \ +}) + +#endif /* _SYS_QMATH_H_ */ Property changes on: head/sys/sys/qmath.h ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/tests/sys/sys/Makefile =================================================================== --- head/tests/sys/sys/Makefile (revision 351543) +++ head/tests/sys/sys/Makefile (revision 351544) @@ -1,9 +1,9 @@ # $FreeBSD$ TESTSDIR= ${TESTSBASE}/sys/sys -ATF_TESTS_C= bitstring_test rb_test splay_test +ATF_TESTS_C= bitstring_test qmath_test rb_test splay_test WARNS?= 5 .include Index: head/tests/sys/sys/qmath_test.c =================================================================== --- head/tests/sys/sys/qmath_test.c (nonexistent) +++ head/tests/sys/sys/qmath_test.c (revision 351544) @@ -0,0 +1,653 @@ +/*- + * 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. + * 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 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. + * + * $FreeBSD$ + */ + +/* + * Author: Lawrence Stewart + */ + +#include +#include + +#include +#include +#include +#include + +#include + +#define QTEST_IV 3 +#define QTEST_IVSTR "3.00" +#define QTEST_RPSHFT 2 +#define QTEST_INTBITS(q) (Q_NTBITS(q) - Q_SIGNED(q) - Q_NFBITS(q) - Q_NCBITS) +#define QTEST_QITRUNC(q, iv) ((iv) >> Q_RPSHFT(q)) +#define QTEST_FFACTOR 32.0 + +#define bitsperrand 31 +#define GENRAND(a, lb, ub) \ +({ \ + int _rembits; \ + do { \ + _rembits = Q_BITSPERBASEUP(ub) + Q_LTZ(lb); \ + *(a) = (__typeof(*(a)))0; \ + while (_rembits > 0) { \ + *(a) |= (((uint64_t)random()) & \ + ((1ULL << (_rembits > bitsperrand ? \ + bitsperrand : _rembits)) - 1)); \ + *(a) <<= (_rembits - (_rembits > bitsperrand ? \ + bitsperrand : _rembits)); \ + _rembits -= bitsperrand; \ + } \ + *(a) += lb; \ + } while (*(a) < (lb) || (uint64_t)*(a) > (ub)); \ + *(a); \ +}) + +/* + * Smoke tests for basic qmath operations, such as initialization + * or string formatting. + */ +ATF_TC_WITHOUT_HEAD(basic_s8q); +ATF_TC_BODY(basic_s8q, tc) +{ + char buf[128]; + s8q_t s8; + + Q_INI(&s8, QTEST_IV, 0, QTEST_RPSHFT); + Q_TOSTR(s8, -1, 10, buf, sizeof(buf)); + ATF_CHECK_STREQ(QTEST_IVSTR, buf); + ATF_CHECK_EQ(sizeof(s8) << 3, Q_NTBITS(s8)); + ATF_CHECK_EQ(QTEST_RPSHFT, Q_NFBITS(s8)); + ATF_CHECK_EQ(QTEST_INTBITS(s8), Q_NIBITS(s8)); + ATF_CHECK_EQ(QTEST_QITRUNC(s8, INT8_MAX), Q_IMAXVAL(s8)); + ATF_CHECK_EQ(-Q_IMAXVAL(s8), Q_IMINVAL(s8)); +} + +ATF_TC_WITHOUT_HEAD(basic_s16q); +ATF_TC_BODY(basic_s16q, tc) +{ + char buf[128]; + s16q_t s16; + + Q_INI(&s16, QTEST_IV, 0, QTEST_RPSHFT); + Q_TOSTR(s16, -1, 10, buf, sizeof(buf)); + ATF_CHECK_STREQ(QTEST_IVSTR, buf); + ATF_CHECK_EQ(sizeof(s16) << 3, Q_NTBITS(s16)); + ATF_CHECK_EQ(QTEST_RPSHFT, Q_NFBITS(s16)); + ATF_CHECK_EQ(QTEST_INTBITS(s16), Q_NIBITS(s16)); + ATF_CHECK_EQ(QTEST_QITRUNC(s16, INT16_MAX), Q_IMAXVAL(s16)); + ATF_CHECK_EQ(-Q_IMAXVAL(s16), Q_IMINVAL(s16)); +} + +ATF_TC_WITHOUT_HEAD(basic_s32q); +ATF_TC_BODY(basic_s32q, tc) +{ + char buf[128]; + s32q_t s32; + + Q_INI(&s32, QTEST_IV, 0, QTEST_RPSHFT); + Q_TOSTR(s32, -1, 10, buf, sizeof(buf)); + ATF_CHECK_STREQ(QTEST_IVSTR, buf); + ATF_CHECK_EQ(sizeof(s32) << 3, Q_NTBITS(s32)); + ATF_CHECK_EQ(QTEST_RPSHFT, Q_NFBITS(s32)); + ATF_CHECK_EQ(QTEST_INTBITS(s32), Q_NIBITS(s32)); + ATF_CHECK_EQ(QTEST_QITRUNC(s32, INT32_MAX), Q_IMAXVAL(s32)); + ATF_CHECK_EQ(-Q_IMAXVAL(s32), Q_IMINVAL(s32)); +} + +ATF_TC_WITHOUT_HEAD(basic_s64q); +ATF_TC_BODY(basic_s64q, tc) +{ + char buf[128]; + s64q_t s64; + + Q_INI(&s64, QTEST_IV, 0, QTEST_RPSHFT); + Q_TOSTR(s64, -1, 10, buf, sizeof(buf)); + ATF_CHECK_STREQ(QTEST_IVSTR, buf); + ATF_CHECK_EQ(sizeof(s64) << 3, Q_NTBITS(s64)); + ATF_CHECK_EQ(QTEST_RPSHFT, Q_NFBITS(s64)); + ATF_CHECK_EQ(QTEST_INTBITS(s64), Q_NIBITS(s64)); + ATF_CHECK_EQ(QTEST_QITRUNC(s64, INT64_MAX), Q_IMAXVAL(s64)); + ATF_CHECK_EQ(-Q_IMAXVAL(s64), Q_IMINVAL(s64)); +} + +ATF_TC_WITHOUT_HEAD(basic_u8q); +ATF_TC_BODY(basic_u8q, tc) +{ + char buf[128]; + u8q_t u8; + + Q_INI(&u8, QTEST_IV, 0, QTEST_RPSHFT); + Q_TOSTR(u8, -1, 10, buf, sizeof(buf)); + ATF_CHECK_STREQ(QTEST_IVSTR, buf); + ATF_CHECK_EQ(sizeof(u8) << 3, Q_NTBITS(u8)); + ATF_CHECK_EQ(QTEST_RPSHFT, Q_NFBITS(u8)); + ATF_CHECK_EQ(QTEST_INTBITS(u8), Q_NIBITS(u8)); + ATF_CHECK_EQ(QTEST_QITRUNC(u8, UINT8_MAX), Q_IMAXVAL(u8)); + ATF_CHECK_EQ(0, Q_IMINVAL(u8)); +} + +ATF_TC_WITHOUT_HEAD(basic_u16q); +ATF_TC_BODY(basic_u16q, tc) +{ + char buf[128]; + u16q_t u16; + + Q_INI(&u16, QTEST_IV, 0, QTEST_RPSHFT); + Q_TOSTR(u16, -1, 10, buf, sizeof(buf)); + ATF_CHECK_STREQ(QTEST_IVSTR, buf); + ATF_CHECK_EQ(sizeof(u16) << 3, Q_NTBITS(u16)); + ATF_CHECK_EQ(QTEST_RPSHFT, Q_NFBITS(u16)); + ATF_CHECK_EQ(QTEST_INTBITS(u16), Q_NIBITS(u16)); + ATF_CHECK_EQ(QTEST_QITRUNC(u16, UINT16_MAX), Q_IMAXVAL(u16)); + ATF_CHECK_EQ(0, Q_IMINVAL(u16)); +} + +ATF_TC_WITHOUT_HEAD(basic_u32q); +ATF_TC_BODY(basic_u32q, tc) +{ + char buf[128]; + u32q_t u32; + + Q_INI(&u32, QTEST_IV, 0, QTEST_RPSHFT); + Q_TOSTR(u32, -1, 10, buf, sizeof(buf)); + ATF_CHECK_STREQ(QTEST_IVSTR, buf); + ATF_CHECK_EQ(sizeof(u32) << 3, Q_NTBITS(u32)); + ATF_CHECK_EQ(QTEST_RPSHFT, Q_NFBITS(u32)); + ATF_CHECK_EQ(QTEST_INTBITS(u32), Q_NIBITS(u32)); + ATF_CHECK_EQ(QTEST_QITRUNC(u32, UINT32_MAX), Q_IMAXVAL(u32)); + ATF_CHECK_EQ(0, Q_IMINVAL(u32)); +} + +ATF_TC_WITHOUT_HEAD(basic_u64q); +ATF_TC_BODY(basic_u64q, tc) +{ + char buf[128]; + u64q_t u64; + + Q_INI(&u64, QTEST_IV, 0, QTEST_RPSHFT); + Q_TOSTR(u64, -1, 10, buf, sizeof(buf)); + ATF_CHECK_STREQ(QTEST_IVSTR, buf); + ATF_CHECK_EQ(sizeof(u64) << 3, Q_NTBITS(u64)); + ATF_CHECK_EQ(QTEST_RPSHFT, Q_NFBITS(u64)); + ATF_CHECK_EQ(QTEST_INTBITS(u64), Q_NIBITS(u64)); + ATF_CHECK_EQ(QTEST_QITRUNC(u64, UINT64_MAX), Q_IMAXVAL(u64)); + ATF_CHECK_EQ(0, Q_IMINVAL(u64)); +} + +/* + * Test Q_QMULQ(3) by applying it to two random Q numbers and comparing + * the result with its floating-point counterpart. + */ +ATF_TC_WITHOUT_HEAD(qmulq_s64q); +ATF_TC_BODY(qmulq_s64q, tc) +{ + s64q_t a_s64q, b_s64q, r_s64q; + double a_dbl, b_dbl, r_dbl, maxe_dbl, delta_dbl; + int64_t a_int, b_int; + int error; + + srandomdev(); + + for (int i = 0; i < 10;) { + GENRAND(&a_s64q, INT64_MIN, UINT64_MAX); + GENRAND(&b_s64q, INT64_MIN, UINT64_MAX); + + /* + * XXX: We cheat a bit, to stand any chance of multiplying + * without overflow. + */ + error = Q_QDIVQ(&a_s64q, b_s64q); + if (error == EOVERFLOW || error == ERANGE) + continue; + ATF_CHECK_EQ(0, error); + + /* + * XXXLAS: Until Qmath handles precision normalisation, only + * test with equal precision. + */ + Q_SCVAL(b_s64q, Q_GCVAL(a_s64q)); + a_int = Q_GIVAL(a_s64q); + b_int = Q_GIVAL(b_s64q); + + /* QQ testing. */ + a_dbl = Q_Q2D(a_s64q); + b_dbl = Q_Q2D(b_s64q); + + r_s64q = a_s64q; + error = Q_QMULQ(&r_s64q, b_s64q); + if (error == EOVERFLOW || error == ERANGE) + continue; + i++; + ATF_CHECK_EQ(0, error); + + r_dbl = a_dbl * b_dbl; +#ifdef notyet + maxe_dbl = fabs(((1.0 / Q_NFBITS(a_s64q)) * (double)b_int) + + ((1.0 / Q_NFBITS(b_s64q)) * (double)a_int)); +#else + maxe_dbl = QTEST_FFACTOR; +#endif + delta_dbl = fabs(r_dbl - Q_Q2D(r_s64q)); + ATF_CHECK_MSG(delta_dbl <= maxe_dbl, + "\tQMULQ(%10f * %10f): |%10f - %10f| = %10f " + "(max err %f)\n", + Q_Q2D(a_s64q), Q_Q2D(b_s64q), Q_Q2D(r_s64q), r_dbl, + delta_dbl, maxe_dbl); + } +} + +/* + * Test Q_QDIVQ(3) by applying it to two random Q numbers and comparing + * the result with its floating-point counterpart. + */ +ATF_TC_WITHOUT_HEAD(qdivq_s64q); +ATF_TC_BODY(qdivq_s64q, tc) +{ + s64q_t a_s64q, b_s64q, r_s64q; + double a_dbl, b_dbl, r_dbl, maxe_dbl, delta_dbl; + int64_t a_int, b_int; + int error; + + srandomdev(); + + for (int i = 0; i < 10; i++) { + GENRAND(&a_s64q, INT64_MIN, UINT64_MAX); + GENRAND(&b_s64q, INT64_MIN, UINT64_MAX); + /* + * XXXLAS: Until Qmath handles precision normalisation, only + * test with equal precision. + */ + Q_SCVAL(b_s64q, Q_GCVAL(a_s64q)); + a_int = Q_GIVAL(a_s64q); + b_int = Q_GIVAL(b_s64q); + + /* QQ testing. */ + a_dbl = Q_Q2D(a_s64q); + b_dbl = Q_Q2D(b_s64q); + + r_s64q = a_s64q; + error = Q_QDIVQ(&r_s64q, b_s64q); + ATF_CHECK_EQ(0, error); + + r_dbl = a_dbl / b_dbl; +#ifdef notyet + maxe_dbl = fabs(1.0 / (1ULL << Q_NFBITS(a_s64q))); +#else + maxe_dbl = QTEST_FFACTOR * 2; +#endif + delta_dbl = fabs(r_dbl - Q_Q2D(r_s64q)); + ATF_CHECK_MSG(delta_dbl <= maxe_dbl, + "\tQDIVQ(%10f / %10f): |%10f - %10f| = %10f " + "(max err %f)\n", + Q_Q2D(a_s64q), Q_Q2D(b_s64q), Q_Q2D(r_s64q), r_dbl, + delta_dbl, maxe_dbl); + } +} + +/* + * Test Q_QADDQ(3) by applying it to two random Q numbers and comparing + * the result with its floating-point counterpart. + */ +ATF_TC_WITHOUT_HEAD(qaddq_s64q); +ATF_TC_BODY(qaddq_s64q, tc) +{ + s64q_t a_s64q, b_s64q, r_s64q; + double a_dbl, b_dbl, r_dbl, maxe_dbl, delta_dbl; + int64_t a_int, b_int; + int error; + + srandomdev(); + + for (int i = 0; i < 10;) { + GENRAND(&a_s64q, INT64_MIN, UINT64_MAX); + GENRAND(&b_s64q, INT64_MIN, UINT64_MAX); + /* + * XXXLAS: Until Qmath handles precision normalisation, only + * test with equal precision. + */ + Q_SCVAL(b_s64q, Q_GCVAL(a_s64q)); + a_int = Q_GIVAL(a_s64q); + b_int = Q_GIVAL(b_s64q); + + /* QQ testing. */ + a_dbl = Q_Q2D(a_s64q); + b_dbl = Q_Q2D(b_s64q); + + r_s64q = a_s64q; + error = Q_QADDQ(&r_s64q, b_s64q); + if (error == EOVERFLOW || error == ERANGE) + continue; + i++; + ATF_CHECK_EQ(0, error); + + r_dbl = a_dbl + b_dbl; +#ifdef notyet + maxe_dbl = 0.5; +#else + maxe_dbl = QTEST_FFACTOR; +#endif + delta_dbl = fabs(r_dbl - Q_Q2D(r_s64q)); + ATF_CHECK_MSG(delta_dbl <= maxe_dbl, + "\tQADDQ(%10f + %10f): |%10f - %10f| = %10f " + "(max err %f)\n", + Q_Q2D(a_s64q), Q_Q2D(b_s64q), Q_Q2D(r_s64q), r_dbl, + delta_dbl, maxe_dbl); + } +} + +/* + * Test Q_QSUBQ(3) by applying it to two random Q numbers and comparing + * the result with its floating-point counterpart. + */ +ATF_TC_WITHOUT_HEAD(qsubq_s64q); +ATF_TC_BODY(qsubq_s64q, tc) +{ + s64q_t a_s64q, b_s64q, r_s64q; + double a_dbl, b_dbl, r_dbl, maxe_dbl, delta_dbl; + int64_t a_int, b_int; + int error; + + srandomdev(); + + for (int i = 0; i < 10; i++) { + GENRAND(&a_s64q, INT64_MIN, UINT64_MAX); + GENRAND(&b_s64q, INT64_MIN, UINT64_MAX); + /* + * XXXLAS: Until Qmath handles precision normalisation, only + * test with equal precision. + */ + Q_SCVAL(b_s64q, Q_GCVAL(a_s64q)); + a_int = Q_GIVAL(a_s64q); + b_int = Q_GIVAL(b_s64q); + + /* QQ testing. */ + a_dbl = Q_Q2D(a_s64q); + b_dbl = Q_Q2D(b_s64q); + + r_s64q = a_s64q; + error = Q_QSUBQ(&r_s64q, b_s64q); + ATF_CHECK_EQ(0, error); + + r_dbl = a_dbl - b_dbl; +#ifdef notyet + maxe_dbl = 0.5; +#else + maxe_dbl = QTEST_FFACTOR; +#endif + delta_dbl = fabs(r_dbl - Q_Q2D(r_s64q)); + ATF_CHECK_MSG(delta_dbl <= maxe_dbl, + "\tQSUBQ(%10f - %10f): |%10f - %10f| = %10f " + "(max err %f)\n", + Q_Q2D(a_s64q), Q_Q2D(b_s64q), Q_Q2D(r_s64q), r_dbl, + delta_dbl, maxe_dbl); + } +} + +/* + * Test Q_QFRACI(3) by applying it to two random integers and comparing + * the result with its floating-point counterpart. + */ +ATF_TC_WITHOUT_HEAD(qfraci_s64q); +ATF_TC_BODY(qfraci_s64q, tc) +{ + s64q_t a_s64q, b_s64q, r_s64q; + double a_dbl, b_dbl, r_dbl, maxe_dbl, delta_dbl; + int64_t a_int, b_int; + int error; + + srandomdev(); + + for (int i = 0; i < 10;) { + GENRAND(&a_s64q, INT64_MIN, UINT64_MAX); + GENRAND(&b_s64q, INT64_MIN, UINT64_MAX); + /* + * XXXLAS: Until Qmath handles precision normalisation, only + * test with equal precision. + */ + Q_SCVAL(b_s64q, Q_GCVAL(a_s64q)); + a_int = Q_GIVAL(a_s64q); + b_int = Q_GIVAL(b_s64q); + + /* QI testing. */ + a_dbl = a_int; + b_dbl = b_int; + + Q_INI(&r_s64q, 0, 0, Q_NFBITS(a_s64q)); + error = Q_QFRACI(&r_s64q, a_int, b_int); + if (error == EOVERFLOW || error == ERANGE || error == EINVAL) + continue; + i++; + ATF_CHECK_EQ(0, error); + + r_dbl = a_dbl / b_dbl; + maxe_dbl = fabs(1.0 / Q_NFBITS(a_s64q)); + delta_dbl = fabs(r_dbl - Q_Q2D(r_s64q)); + ATF_CHECK_MSG(delta_dbl <= maxe_dbl, + "\tQFRACI(%ld / %ld): |%10f - %10f| = %10f " + "(max err %f)\n", + a_int, b_int, Q_Q2D(r_s64q), r_dbl, delta_dbl, + maxe_dbl); + } +} + +/* + * Test Q_QMULI(3) by applying it to a random Q number and a random integer + * and comparing the result with its floating-point counterpart. + */ +ATF_TC_WITHOUT_HEAD(qmuli_s64q); +ATF_TC_BODY(qmuli_s64q, tc) +{ + s64q_t a_s64q, b_s64q, r_s64q; + double a_dbl, b_dbl, r_dbl, maxe_dbl, delta_dbl; + int64_t a_int, b_int; + int error; + + srandomdev(); + + for (int i = 0; i < 10;) { + GENRAND(&a_s64q, INT64_MIN, UINT64_MAX); + GENRAND(&b_s64q, INT64_MIN, UINT64_MAX); + /* + * XXXLAS: Until Qmath handles precision normalisation, only + * test with equal precision. + */ + Q_SCVAL(b_s64q, Q_GCVAL(a_s64q)); + a_int = Q_GIVAL(a_s64q); + b_int = Q_GIVAL(b_s64q); + + /* QI testing. */ + a_dbl = a_int; + b_dbl = b_int; + + Q_INI(&r_s64q, a_int, 0, Q_NFBITS(a_s64q)); + error = Q_QMULI(&r_s64q, b_int); + if (error == EOVERFLOW || error == ERANGE) + continue; + i++; + ATF_CHECK_EQ(0, error); + + r_dbl = a_dbl * b_dbl; + maxe_dbl = fabs((1.0 / Q_NFBITS(a_s64q)) * (double)b_int); + delta_dbl = fabs(r_dbl - Q_Q2D(r_s64q)); + ATF_CHECK_MSG(delta_dbl <= maxe_dbl, + "\tQMULI(%ld * %ld): |%10f - %10f| = %10f " + "(max err %f)\n", + a_int, b_int, Q_Q2D(r_s64q), r_dbl, delta_dbl, + maxe_dbl); + } +} + +/* + * Test Q_QADDI(3) by applying it to a random Q number and a random integer + * and comparing the result with its floating-point counterpart. + */ +ATF_TC_WITHOUT_HEAD(qaddi_s64q); +ATF_TC_BODY(qaddi_s64q, tc) +{ + s64q_t a_s64q, b_s64q, r_s64q; + double a_dbl, b_dbl, r_dbl, maxe_dbl, delta_dbl; + int64_t a_int, b_int; + int error; + + srandomdev(); + + for (int i = 0; i < 10;) { + GENRAND(&a_s64q, INT64_MIN, UINT64_MAX); + GENRAND(&b_s64q, INT64_MIN, UINT64_MAX); + /* + * XXXLAS: Until Qmath handles precision normalisation, only + * test with equal precision. + */ + Q_SCVAL(b_s64q, Q_GCVAL(a_s64q)); + a_int = Q_GIVAL(a_s64q); + b_int = Q_GIVAL(b_s64q); + + /* QI testing. */ + a_dbl = a_int; + b_dbl = b_int; + + Q_INI(&r_s64q, a_int, 0, Q_NFBITS(a_s64q)); + error = Q_QADDI(&r_s64q, b_int); + if (error == EOVERFLOW || error == ERANGE) + continue; + i++; + ATF_CHECK_EQ(0, error); + + r_dbl = a_dbl + b_dbl; +#ifdef notyet + maxe_dbl = 0.5; +#else + maxe_dbl = QTEST_FFACTOR; +#endif + delta_dbl = fabs(r_dbl - Q_Q2D(r_s64q)); + ATF_CHECK_MSG(delta_dbl <= maxe_dbl, + "\tQADDI(%ld + %ld): |%10f - %10f| = %10f " + "(max err %f)\n", + a_int, b_int, Q_Q2D(r_s64q), r_dbl, delta_dbl, + maxe_dbl); + } +} + +/* + * Test Q_QSUBI(3) by applying it to a random Q number and a random integer + * and comparing the result with its floating-point counterpart. + */ +ATF_TC_WITHOUT_HEAD(qsubi_s64q); +ATF_TC_BODY(qsubi_s64q, tc) +{ + s64q_t a_s64q, b_s64q, r_s64q; + double a_dbl, b_dbl, r_dbl, maxe_dbl, delta_dbl; + int64_t a_int, b_int; + int error; + + srandomdev(); + + for (int i = 0; i < 10; i++) { + GENRAND(&a_s64q, INT64_MIN, UINT64_MAX); + GENRAND(&b_s64q, INT64_MIN, UINT64_MAX); + /* + * XXXLAS: Until Qmath handles precision normalisation, only + * test with equal precision. + */ + Q_SCVAL(b_s64q, Q_GCVAL(a_s64q)); + a_int = Q_GIVAL(a_s64q); + b_int = Q_GIVAL(b_s64q); + + /* QI testing. */ + a_dbl = a_int; + b_dbl = b_int; + + Q_INI(&r_s64q, a_int, 0, Q_NFBITS(a_s64q)); + error = Q_QSUBI(&r_s64q, b_int); + ATF_CHECK_EQ(0, error); + + r_dbl = a_dbl - b_dbl; +#ifdef notyet + maxe_dbl = 0.5; +#else + maxe_dbl = QTEST_FFACTOR; +#endif + delta_dbl = fabs(r_dbl - Q_Q2D(r_s64q)); + ATF_CHECK_MSG(delta_dbl <= maxe_dbl, + "\tQSUBI(%ld - %ld): |%10f - %10f| = %10f " + "(max err %f)\n", + a_int, b_int, Q_Q2D(r_s64q), r_dbl, delta_dbl, + maxe_dbl); + } +} + +/* + * Calculate area of a circle with r=42. + */ +ATF_TC_WITHOUT_HEAD(circle_u64q); +ATF_TC_BODY(circle_u64q, tc) +{ + char buf[128]; + u64q_t a, pi, r; + int error; + + Q_INI(&a, 0, 0, 16); + Q_INI(&pi, 3, 14159, 16); + Q_INI(&r, 4, 2, 16); + + error = Q_QCLONEQ(&a, r); + ATF_CHECK_EQ(0, error); + error = Q_QMULQ(&a, r); + ATF_CHECK_EQ(0, error); + error = Q_QMULQ(&a, pi); + ATF_CHECK_EQ(0, error); + + Q_TOSTR(a, -1, 10, buf, sizeof(buf)); + ATF_CHECK_STREQ("55.4174804687500000", buf); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, basic_s8q); + ATF_TP_ADD_TC(tp, basic_s16q); + ATF_TP_ADD_TC(tp, basic_s32q); + ATF_TP_ADD_TC(tp, basic_s64q); + ATF_TP_ADD_TC(tp, basic_u8q); + ATF_TP_ADD_TC(tp, basic_u16q); + ATF_TP_ADD_TC(tp, basic_u32q); + ATF_TP_ADD_TC(tp, basic_u64q); + + ATF_TP_ADD_TC(tp, qmulq_s64q); + ATF_TP_ADD_TC(tp, qdivq_s64q); + ATF_TP_ADD_TC(tp, qaddq_s64q); + ATF_TP_ADD_TC(tp, qsubq_s64q); + ATF_TP_ADD_TC(tp, qfraci_s64q); + ATF_TP_ADD_TC(tp, qmuli_s64q); + ATF_TP_ADD_TC(tp, qaddi_s64q); + ATF_TP_ADD_TC(tp, qsubi_s64q); + + ATF_TP_ADD_TC(tp, circle_u64q); + + return (atf_no_error()); +} Property changes on: head/tests/sys/sys/qmath_test.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property