cannam@85: /* cannam@85: * libmad - MPEG audio decoder library cannam@85: * Copyright (C) 2000-2004 Underbit Technologies, Inc. cannam@85: * cannam@85: * This program is free software; you can redistribute it and/or modify cannam@85: * it under the terms of the GNU General Public License as published by cannam@85: * the Free Software Foundation; either version 2 of the License, or cannam@85: * (at your option) any later version. cannam@85: * cannam@85: * This program is distributed in the hope that it will be useful, cannam@85: * but WITHOUT ANY WARRANTY; without even the implied warranty of cannam@85: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the cannam@85: * GNU General Public License for more details. cannam@85: * cannam@85: * You should have received a copy of the GNU General Public License cannam@85: * along with this program; if not, write to the Free Software cannam@85: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA cannam@85: * cannam@85: * $Id: fixed.c,v 1.13 2004/01/23 09:41:32 rob Exp $ cannam@85: */ cannam@85: cannam@85: # ifdef HAVE_CONFIG_H cannam@85: # include "config.h" cannam@85: # endif cannam@85: cannam@85: # include "global.h" cannam@85: cannam@85: # include "fixed.h" cannam@85: cannam@85: /* cannam@85: * NAME: fixed->abs() cannam@85: * DESCRIPTION: return absolute value of a fixed-point number cannam@85: */ cannam@85: mad_fixed_t mad_f_abs(mad_fixed_t x) cannam@85: { cannam@85: return x < 0 ? -x : x; cannam@85: } cannam@85: cannam@85: /* cannam@85: * NAME: fixed->div() cannam@85: * DESCRIPTION: perform division using fixed-point math cannam@85: */ cannam@85: mad_fixed_t mad_f_div(mad_fixed_t x, mad_fixed_t y) cannam@85: { cannam@85: mad_fixed_t q, r; cannam@85: unsigned int bits; cannam@85: cannam@85: q = mad_f_abs(x / y); cannam@85: cannam@85: if (x < 0) { cannam@85: x = -x; cannam@85: y = -y; cannam@85: } cannam@85: cannam@85: r = x % y; cannam@85: cannam@85: if (y < 0) { cannam@85: x = -x; cannam@85: y = -y; cannam@85: } cannam@85: cannam@85: if (q > mad_f_intpart(MAD_F_MAX) && cannam@85: !(q == -mad_f_intpart(MAD_F_MIN) && r == 0 && (x < 0) != (y < 0))) cannam@85: return 0; cannam@85: cannam@85: for (bits = MAD_F_FRACBITS; bits && r; --bits) { cannam@85: q <<= 1, r <<= 1; cannam@85: if (r >= y) cannam@85: r -= y, ++q; cannam@85: } cannam@85: cannam@85: /* round */ cannam@85: if (2 * r >= y) cannam@85: ++q; cannam@85: cannam@85: /* fix sign */ cannam@85: if ((x < 0) != (y < 0)) cannam@85: q = -q; cannam@85: cannam@85: return q << bits; cannam@85: }