_base_S.c revision 5d54f3d8999eac1762fe0a8c7177d20f1f201fae
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1988 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include "base_conversion.h"
/* Fundamental utilities for base conversion that should be recoded as assembly language subprograms or as inline expansion templates. */
/* Converts t < 10000 into four ascii digits at *pc. */
void
_fourdigitsquick(short unsigned t, char *d)
{
short i;
i = 3;
do {
d[i] = '0' + t % 10;
t = t / 10;
}
while (--i != -1);
}
void
_multiply_base_two_vector(short unsigned n, _BIG_FLOAT_DIGIT *px,
short unsigned *py, _BIG_FLOAT_DIGIT product[3])
{
/*
* Given xi and yi, base 2**16 vectors of length n, computes dot
* product
*
* sum (i=0,n-1) of x[i]*y[n-1-i]
*
* Product may fill as many as three short-unsigned buckets. Product[0]
* is least significant, product[2] most.
*/
unsigned long acc, p;
short unsigned carry;
int i;
acc = 0;
carry = 0;
for (i = 0; i < n; i++) {
p=_umac(px[i],py[n - 1 - i],acc);
if (p < acc)
carry++;
acc = p;
}
product[0] = (_BIG_FLOAT_DIGIT) (acc & 0xffff);
product[1] = (_BIG_FLOAT_DIGIT) (acc >> 16);
product[2] = (_BIG_FLOAT_DIGIT) (carry);
}
void
_multiply_base_ten_vector(short unsigned n, _BIG_FLOAT_DIGIT *px,
short unsigned *py, _BIG_FLOAT_DIGIT product[3])
{
/*
* Given xi and yi, base 10**4 vectors of length n, computes dot
* product
*
* sum (i=0,n-1) of x[i]*y[n-1-i]
*
* Product may fill as many as three short-unsigned buckets. Product[0]
* is least significant, product[2] most.
*/
#define ABASE 3000000000U /* Base of accumulator. */
unsigned long acc;
short unsigned carry;
int i;
acc = 0;
carry = 0;
for (i = 0; i < n; i++) {
acc=_umac(px[i],py[n - 1 - i],acc);
if (acc >= (unsigned long) ABASE) {
carry++;
acc -= ABASE;
}
}
/*
NOTE: because
acc * <= ABASE-1,
acc/10000 <= 299999
which would overflow a short unsigned
*/
product[0] = (_BIG_FLOAT_DIGIT) (acc % 10000);
acc /= 10000;
product[1] = (_BIG_FLOAT_DIGIT) (acc % 10000);
acc /= 10000;
product[2] = (_BIG_FLOAT_DIGIT) (acc + (ABASE / 100000000) * carry);
}