/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (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
* 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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include "lint.h"
#include "base_conversion.h"
#include <malloc.h>
#include <memory.h>
#include <stdlib.h>
#include <errno.h>
/*
* Multiply a _big_float by a power of two or ten
*/
/* see comment in double_decim.c */
static unsigned int
{
*pr = x % 10000;
return (x / 10000);
}
/*
* Multiply a base-2**16 significand by multiplier. Extend length as
* necessary to accommodate carries.
*/
static void
{
unsigned int p, carry;
carry = 0;
for (j = 0; j < length; j++) {
carry = p >> 16;
}
if (carry != 0)
}
/*
* Multiply a base-10**4 significand by multiplier. Extend length as
* necessary to accommodate carries.
*/
static void
{
unsigned int p, carry;
carry = 0;
for (j = 0; j < length; j++) {
}
while (carry != 0) {
j++;
}
}
/*
* Multiply a base-10**4 significand by 2**multiplier. Extend length
* as necessary to accommodate carries.
*/
static void
{
unsigned int p, carry;
carry = 0;
for (j = 0; j < length; j++) {
}
while (carry != 0) {
j++;
}
}
/*
* Propagate carries in a base-2**16 significand.
*/
static void
{
unsigned int p;
int j;
j = 0;
while (carry != 0) {
p = psignificand[j] + carry;
psignificand[j++] = p & 0xffff;
carry = p >> 16;
}
}
/*
* Propagate carries in a base-10**4 significand.
*/
static void
{
unsigned int p;
int j;
j = 0;
while (carry != 0) {
p = psignificand[j] + carry;
j++;
}
}
/*
* Given x[] and y[], base-2**16 vectors of length n, compute the
* dot product
*
* sum (i=0,n-1) of x[i]*y[n-1-i]
*
* The product may fill as many as three base-2**16 digits; product[0]
* is the least significant, product[2] the most.
*/
static void
{
unsigned int acc, p;
unsigned short carry;
int i;
acc = 0;
carry = 0;
for (i = 0; i < (int)n; i++) {
if (p < acc)
carry++;
acc = p;
}
}
/*
* Given x[] and y[], base-10**4 vectors of length n, compute the
* dot product
*
* sum (i=0,n-1) of x[i]*y[n-1-i]
*
* The product may fill as many as three base-10**4 digits; product[0]
* is the least significant, product[2] the most.
*/
static void
{
unsigned int acc;
unsigned short carry;
int i;
acc = 0;
carry = 0;
for (i = 0; i < (int)n; i++) {
carry++;
}
}
}
/*
* Multiply *pbf by the n-th power of mult, which must be two or
* ten. If mult is two, *pbf is assumed to be base 10**4; if mult
* is ten, *pbf is assumed to be base 2**16. precision specifies
* the number of significant bits or decimal digits required in the
* result. (The product may have more or fewer digits than this,
* but it will be accurate to at least this many.)
*
* On exit, if the product is small enough, it overwrites *pbf, and
* *pnewbf is set to pbf. If the product is too large to fit in *pbf,
* this routine calls malloc(3M) to allocate storage and sets *pnewbf
* to point to this area; it is the caller's responsibility to free
* this storage when it is no longer needed. Note that *pbf may be
* modified even when the routine allocates new storage.
*
* If n is too large, we set errno to ERANGE and call abort(3C).
* If an attempted malloc fails, we set errno to ENOMEM and call
* abort(3C).
*/
void
_big_float **pnewbf)
{
int excess_check;
return;
}
if (mult == 2) {
/*
* Handle small n cases that don't require extra
* storage quickly.
*/
return;
}
/* *pbf is base 10**4 */
base = 10;
/*
* Convert precision (base ten digits) to needed_precision
* (base 10**4 digits), allowing an additional digit at
* each end.
*/
/*
* Set up pointers to the table entries and compute their
* lengths.
*/
if (n < __TBL_2_SMALL_SIZE) {
itlast = 0;
tablepower[0] = n;
} else if (n < (__TBL_2_SMALL_SIZE * __TBL_2_BIG_SIZE)) {
itlast = 1;
tablepower[0] = n % __TBL_2_SMALL_SIZE;
tablepower[2] = 0;
} else if (n < (__TBL_2_SMALL_SIZE * __TBL_2_BIG_SIZE *
itlast = 2;
tablepower[0] = n % __TBL_2_SMALL_SIZE;
n /= __TBL_2_SMALL_SIZE;
} else {
abort();
}
} else {
return;
}
/* *pbf is base 2**16 */
base = 2;
if (n < __TBL_10_SMALL_SIZE) {
itlast = 0;
tablepower[0] = n;
} else if (n < (__TBL_10_SMALL_SIZE * __TBL_10_BIG_SIZE)) {
itlast = 1;
tablepower[0] = n % __TBL_10_SMALL_SIZE;
tablepower[2] = 0;
} else if (n < (__TBL_10_SMALL_SIZE * __TBL_10_BIG_SIZE *
itlast = 2;
tablepower[0] = n % __TBL_10_SMALL_SIZE;
n /= __TBL_10_SMALL_SIZE;
} else {
abort();
}
}
/* compute an upper bound on the size of the product */
for (i = 0; i <= itlast; i++)
productsize += length[i];
if (productsize < needed_precision)
} else {
i = sizeof (_big_float) + sizeof (unsigned short) *
abort();
}
}
/*
* Now pbf points to the input and the output. Step through
* each level of the tables.
*/
for (i = 0; i <= itlast; i++) {
if (tablepower[i] == 0)
continue;
if (lengthp == 1) {
/* short multiplier (<= 10**4 or 2**13) */
if (base == 10) {
/* left shift by tablepower[i] */
} else {
}
continue;
}
if (lengthx == 1) {
/* short multiplicand */
lengthp * sizeof (unsigned short));
if (base == 10)
else
continue;
}
/* keep track of trailing zeroes */
/* initialize for carry propagation */
/*
* General case - the result will be accumulated in *pbf
* from most significant digit to least significant.
*/
if (istart < 0)
istart = 0;
if (istop > j)
istop = j;
if (base == 2) {
if (product[2] != 0)
(unsigned int)product[2],
if (product[1] != 0)
(unsigned int)product[1],
} else {
if (product[2] != 0)
(unsigned int)product[2],
if (product[1] != 0)
(unsigned int)product[1],
}
continue;
/*
* On the last multiplication, it's not necessary
* to develop the entire product if further digits
* can't possibly affect significant digits. But
* note that further digits can affect the product
* in one of two ways: (i) the sum of digits beyond
* the significant ones can cause a carry that would
* propagate into the significant digits, or (ii) no
* carry will occur, but there may be more nonzero
* digits that will need to be recorded in a sticky
* bit.
*/
excess_check--;
/*
* If j <= excess_check, then we have all the
* significant digits. If the (j + 1)-st digit
* is no larger than canquit, then the sum of the
* digits not yet computed can't carry into the
* significant digits. If the j-th and (j + 1)-st
* digits are not both zero, then we know we are
* discarding nonzero digits. (If both of these
* digits are zero, we need to keep forming more
* of the product to see whether or not there are
* any more nonzero digits.)
*/
if (j <= excess_check &&
!= 0) {
/* can discard j+1, j, ... 0 */
trailing_zeros_to_delete = j + 2;
/* set sticky bit */
break;
}
}
/* if the product didn't carry, delete the leading zero */
/* look for additional trailing zeros to delete */
continue;
if (trailing_zeros_to_delete > 0) {
trailing_zeros_to_delete; j++) {
}
}
}
}