xref: /plan9-contrib/sys/src/cmd/gs/src/gxarith.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
17dd7cddfSDavid du Colombier /* Copyright (C) 1990, 1993, 1994, 1996, 1998 Aladdin Enterprises.  All rights reserved.
27dd7cddfSDavid du Colombier 
3*593dc095SDavid du Colombier   This software is provided AS-IS with no warranty, either express or
4*593dc095SDavid du Colombier   implied.
57dd7cddfSDavid du Colombier 
6*593dc095SDavid du Colombier   This software is distributed under license and may not be copied,
7*593dc095SDavid du Colombier   modified or distributed except as expressly authorized under the terms
8*593dc095SDavid du Colombier   of the license contained in the file LICENSE in this distribution.
97dd7cddfSDavid du Colombier 
10*593dc095SDavid du Colombier   For more information about licensing, please refer to
11*593dc095SDavid du Colombier   http://www.ghostscript.com/licensing/. For information on
12*593dc095SDavid du Colombier   commercial licensing, go to http://www.artifex.com/licensing/ or
13*593dc095SDavid du Colombier   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14*593dc095SDavid du Colombier   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
157dd7cddfSDavid du Colombier */
167dd7cddfSDavid du Colombier 
177dd7cddfSDavid du Colombier #ifndef gxarith_INCLUDED
187dd7cddfSDavid du Colombier #  define gxarith_INCLUDED
197dd7cddfSDavid du Colombier 
20*593dc095SDavid du Colombier /* $Id: gxarith.h,v 1.5 2002/06/16 08:45:43 lpd Exp $ */
217dd7cddfSDavid du Colombier /* Arithmetic macros for Ghostscript library */
227dd7cddfSDavid du Colombier 
237dd7cddfSDavid du Colombier /* Define an in-line abs function, good for any signed numeric type. */
247dd7cddfSDavid du Colombier #define any_abs(x) ((x) < 0 ? -(x) : (x))
257dd7cddfSDavid du Colombier 
267dd7cddfSDavid du Colombier /* Compute M modulo N.  Requires N > 0; guarantees 0 <= imod(M,N) < N, */
277dd7cddfSDavid du Colombier /* regardless of the whims of the % operator for negative operands. */
28*593dc095SDavid du Colombier int imod(int m, int n);
297dd7cddfSDavid du Colombier 
307dd7cddfSDavid du Colombier /* Compute the GCD of two integers. */
31*593dc095SDavid du Colombier int igcd(int x, int y);
327dd7cddfSDavid du Colombier 
337dd7cddfSDavid du Colombier /*
347dd7cddfSDavid du Colombier  * Given A, B, and M, compute X such that A*X = B mod M, 0 < X < M.
357dd7cddfSDavid du Colombier  * Requires: M > 0, 0 < A < M, 0 < B < M, gcd(A, M) | gcd(A, B).
367dd7cddfSDavid du Colombier  */
37*593dc095SDavid du Colombier int idivmod(int a, int b, int m);
387dd7cddfSDavid du Colombier 
397dd7cddfSDavid du Colombier /*
407dd7cddfSDavid du Colombier  * Compute floor(log2(N)).  Requires N > 0.
417dd7cddfSDavid du Colombier  */
42*593dc095SDavid du Colombier int ilog2(int n);
437dd7cddfSDavid du Colombier 
447dd7cddfSDavid du Colombier /* Test whether an integral value fits in a given number of bits. */
457dd7cddfSDavid du Colombier /* This works for all integral types. */
467dd7cddfSDavid du Colombier #define fits_in_bits(i, n)\
477dd7cddfSDavid du Colombier   (sizeof(i) <= sizeof(int) ? fits_in_ubits((i) + (1 << ((n) - 1)), (n) + 1) :\
487dd7cddfSDavid du Colombier    fits_in_ubits((i) + (1L << ((n) - 1)), (n) + 1))
497dd7cddfSDavid du Colombier #define fits_in_ubits(i, n) (((i) >> (n)) == 0)
507dd7cddfSDavid du Colombier 
517dd7cddfSDavid du Colombier /*
527dd7cddfSDavid du Colombier  * There are some floating point operations that can be implemented
537dd7cddfSDavid du Colombier  * very efficiently on machines that have no floating point hardware,
547dd7cddfSDavid du Colombier  * assuming IEEE representation and no range overflows.
557dd7cddfSDavid du Colombier  * We define straightforward versions of them here, and alternate versions
567dd7cddfSDavid du Colombier  * for no-floating-point machines in gxfarith.h.
577dd7cddfSDavid du Colombier  */
587dd7cddfSDavid du Colombier /* Test floating point values against constants. */
597dd7cddfSDavid du Colombier #define is_fzero(f) ((f) == 0.0)
607dd7cddfSDavid du Colombier #define is_fzero2(f1,f2) ((f1) == 0.0 && (f2) == 0.0)
617dd7cddfSDavid du Colombier #define is_fneg(f) ((f) < 0.0)
627dd7cddfSDavid du Colombier #define is_fge1(f) ((f) >= 1.0)
637dd7cddfSDavid du Colombier /* Test whether a floating point value fits in a given number of bits. */
647dd7cddfSDavid du Colombier #define f_fits_in_bits(f, n)\
657dd7cddfSDavid du Colombier   ((f) >= -2.0 * (1L << ((n) - 2)) && (f) < 2.0 * (1L << ((n) - 2)))
667dd7cddfSDavid du Colombier #define f_fits_in_ubits(f, n)\
677dd7cddfSDavid du Colombier   ((f) >= 0 && (f) < 4.0 * (1L << ((n) - 2)))
687dd7cddfSDavid du Colombier 
697dd7cddfSDavid du Colombier /*
707dd7cddfSDavid du Colombier  * Define a macro for computing log2(n), where n=1,2,4,...,128.
717dd7cddfSDavid du Colombier  * Because some compilers limit the total size of a statement,
727dd7cddfSDavid du Colombier  * this macro must only mention n once.  The macro should really
737dd7cddfSDavid du Colombier  * only be used with compile-time constant arguments, but it will work
747dd7cddfSDavid du Colombier  * even if n is an expression computed at run-time.
757dd7cddfSDavid du Colombier  */
767dd7cddfSDavid du Colombier #define small_exact_log2(n)\
777dd7cddfSDavid du Colombier  ((uint)(05637042010L >> ((((n) % 11) - 1) * 3)) & 7)
787dd7cddfSDavid du Colombier 
797dd7cddfSDavid du Colombier /*
807dd7cddfSDavid du Colombier  * The following doesn't give rise to a macro, but is used in several
817dd7cddfSDavid du Colombier  * places in Ghostscript.  We observe that if M = 2^n-1 and V < M^2,
827dd7cddfSDavid du Colombier  * then the quotient Q and remainder R can be computed as:
837dd7cddfSDavid du Colombier  *              Q = V / M = (V + (V >> n) + 1) >> n;
847dd7cddfSDavid du Colombier  *              R = V % M = (V + (V / M)) & M = V - (Q << n) + Q.
857dd7cddfSDavid du Colombier  */
867dd7cddfSDavid du Colombier 
877dd7cddfSDavid du Colombier #endif /* gxarith_INCLUDED */
88