/*
* /src/NTP/ntp4-dev/libparse/mfp_mul.c,v 4.9 2005/07/17 20:34:40 kardel RELEASE_20050717_A
*
* mfp_mul.c,v 4.9 2005/07/17 20:34:40 kardel RELEASE_20050717_A
*
* $Created: Sat Aug 16 20:35:08 1997 $
*
* Copyright (c) 1997-2005 by Frank Kardel <kardel <AT> ntp.org>
*
* 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 author 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 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.
*
*/
#include <config.h>
#include <stdio.h>
#include "ntp_stdlib.h"
#include "ntp_types.h"
#include "ntp_fp.h"
/*
* for those who worry about overflows (possibly triggered by static analysis tools):
*
* Largest value of a 2^n bit number is 2^n-1.
* Thus the result is: (2^n-1)*(2^n-1) = 2^2n - 2^n - 2^n + 1 < 2^2n
* Here overflow can not happen for 2 reasons:
* 1) the code actually multiplies the absolute values of two signed
* 64bit quantities.thus effectively multiplying 2 63bit quantities.
* 2) Carry propagation is from low to high, building principle is
* addition, so no storage for the 2^2n term from above is needed.
*/
void
mfp_mul(
int32 *o_i,
u_int32 *o_f,
int32 a_i,
u_int32 a_f,
int32 b_i,
u_int32 b_f
)
{
int32 i, j;
u_int32 f;
u_long a[4]; /* operand a */
u_long b[4]; /* operand b */
u_long c[5]; /* result c - 5 items for performance - see below */
u_long carry;
for (i = 0; i < 4; i++) /* we do assume 32 * 32 = 64 bit multiplication */
for (j = 0; j < 4; j++)
{
u_long result_low, result_high;
int low_index = (i+j)/2; /* formal [0..3] - index for low long word */
int mid_index = 1+low_index; /* formal [1..4]! - index for high long word
will generate unecessary add of 0 to c[4]
but save 15 'if (result_high) expressions' */
int high_index = 1+mid_index; /* formal [2..5]! - index for high word overflow
- only assigned on overflow (limits range to 2..3) */
if (c[3]) /* overflow */
{
i = ((unsigned)1 << (FRACTION_PREC-1)) - 1;
f = ~(unsigned)0;
}
else
{ /* take produkt - discarding extra precision */
i = c[2];
f = c[1];
}