4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 1988 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include "base_conversion.h"
32 * Fundamental utilities of base conversion required for sprintf - but too
33 * complex or too seldom used to be worth assembly language coding.
36 /* p = x * y + c ; return (p/10000 << 16 | p%10000) */
38 _prodc_b10000(_BIG_FLOAT_DIGIT x
, _BIG_FLOAT_DIGIT y
, unsigned long c
)
40 unsigned long p
= x
* (unsigned long) y
+ c
;
42 return ((p
/ 10000) << 16) | (p
% 10000);
45 /* p = x * y ; return p */
47 _prod_b65536(_BIG_FLOAT_DIGIT x
, _BIG_FLOAT_DIGIT y
)
49 return (x
* (unsigned long)y
);
52 /* p = x * y ; return (p/10000 << 16 | p%10000) */
54 _prod_b10000(_BIG_FLOAT_DIGIT x
, _BIG_FLOAT_DIGIT y
)
56 unsigned long p
= x
* (unsigned long) y
;
58 return ((p
/ 10000) << 16) | (p
% 10000);
61 /* p = x << n + c ; return (p/10000 << 16 | p%10000) */
63 _lshift_b10000(_BIG_FLOAT_DIGIT x
, short unsigned n
, long unsigned c
)
65 unsigned long p
= (((unsigned long) x
) << n
) + c
;
67 return ((p
/ 10000) << 16) | (p
% 10000);
70 /* p = x * 10000 + c ; return p */
72 _prod_10000_b65536(_BIG_FLOAT_DIGIT x
, long unsigned c
)
74 return (x
* (unsigned long) 10000 + c
);
77 /* p = x << 16 + c ; return (p/10000 << 16 | p%10000) */
79 _prod_65536_b10000(_BIG_FLOAT_DIGIT x
, long unsigned c
)
81 unsigned long p
= (((unsigned long) x
) << 16) + c
;
83 return ((p
/ 10000) << 16) | (p
% 10000);
86 /* p = c ; return (p/10000 << 16 | p%10000) */
88 _carry_out_b10000(unsigned long c
)
90 return ((c
/ 10000) << 16) | (c
% 10000);
94 _left_shift_base_ten(_big_float
*pbf
, short unsigned multiplier
)
97 * Multiply a base-10**4 significand by 2<<multiplier. Extend length
98 * as necessary to accommodate carries.
101 short unsigned length
= pbf
->blength
;
107 for (j
= 0; j
< length
; j
++) {
108 p
= _lshift_b10000((_BIG_FLOAT_DIGIT
) pbf
->bsignificand
[j
], multiplier
, carry
);
109 pbf
->bsignificand
[j
] = (_BIG_FLOAT_DIGIT
) (p
& 0xffff);
113 p
= _carry_out_b10000(carry
);
114 pbf
->bsignificand
[j
++] = (_BIG_FLOAT_DIGIT
) (p
& 0xffff);
121 _left_shift_base_two(_big_float
*pbf
, short unsigned multiplier
)
124 * Multiply a base-2**16 significand by 2<<multiplier. Extend length
125 * as necessary to accommodate carries.
128 short unsigned length
= pbf
->blength
;
134 for (j
= 0; j
< length
; j
++) {
135 p
= _lshift_b65536(pbf
->bsignificand
[j
], multiplier
, carry
);
136 pbf
->bsignificand
[j
] = (_BIG_FLOAT_DIGIT
) (p
& 0xffff);
140 pbf
->bsignificand
[j
++] = (_BIG_FLOAT_DIGIT
) (_carry_out_b65536(carry
) & 0xffff);
146 _right_shift_base_two(_big_float
*pbf
, short unsigned multiplier
,
147 _BIG_FLOAT_DIGIT
*sticky
)
149 /* *pb = *pb / 2**multiplier to normalize. 15 <= multiplier <= 1 */
150 /* Any bits shifted out got to *sticky. */
157 for (j
= pbf
->blength
- 1; j
>= 0; j
--) {
158 p
= _rshift_b65536(pbf
->bsignificand
[j
], multiplier
, carry
);
159 pbf
->bsignificand
[j
] = (_BIG_FLOAT_DIGIT
) (p
>> 16);
162 *sticky
= (_BIG_FLOAT_DIGIT
) carry
;
166 _multiply_base_ten(_big_float
*pbf
, _BIG_FLOAT_DIGIT multiplier
)
169 * Multiply a base-10**4 significand by multiplier. Extend length as
170 * necessary to accommodate carries.
178 for (j
= 0; j
< pbf
->blength
; j
++) {
179 p
= _prodc_b10000((_BIG_FLOAT_DIGIT
) pbf
->bsignificand
[j
], multiplier
, carry
);
180 pbf
->bsignificand
[j
] = (_BIG_FLOAT_DIGIT
) (p
& 0xffff);
184 p
= _carry_out_b10000(carry
);
185 pbf
->bsignificand
[j
++] = (_BIG_FLOAT_DIGIT
) (p
& 0xffff);
192 _multiply_base_two(_big_float
*pbf
, _BIG_FLOAT_DIGIT multiplier
,
196 * Multiply a base-2**16 significand by multiplier. Extend length as
197 * necessary to accommodate carries.
200 short unsigned length
= pbf
->blength
;
204 for (j
= 0; j
< length
; j
++) {
205 p
= _prodc_b65536(pbf
->bsignificand
[j
], multiplier
, carry
);
206 pbf
->bsignificand
[j
] = (_BIG_FLOAT_DIGIT
) (p
& 0xffff);
210 pbf
->bsignificand
[j
++] = (_BIG_FLOAT_DIGIT
) (_carry_out_b65536(carry
) & 0xffff);
216 _multiply_base_ten_by_two(_big_float
*pbf
, short unsigned multiplier
)
219 * Multiply a base-10**4 significand by 2**multiplier. Extend length
220 * as necessary to accommodate carries.
223 short unsigned length
= pbf
->blength
;
225 long unsigned carry
, p
;
228 for (j
= 0; j
< length
; j
++) {
229 p
= _lshift_b10000(pbf
->bsignificand
[j
], multiplier
, carry
);
230 pbf
->bsignificand
[j
] = (_BIG_FLOAT_DIGIT
) (p
& 0xffff);
234 p
= _carry_out_b10000(carry
);
235 pbf
->bsignificand
[j
++] = (_BIG_FLOAT_DIGIT
) (p
& 0xffff);
242 _unpacked_to_big_float(unpacked
*pu
, _big_float
*pb
, int *pe
)
245 * Converts pu into a bigfloat *pb of minimal length; exponent *pe
246 * such that pu = *pb * 2 ** *pe
251 for (iz
= (UNPACKED_SIZE
- 2); pu
->significand
[iz
] == 0; iz
--); /* Find lsw. */
253 for (it
= 0; it
<= iz
; it
++) {
254 pb
->bsignificand
[2 * (iz
- it
)] = pu
->significand
[it
] & 0xffff;
255 pb
->bsignificand
[2 * (iz
- it
) + 1] = pu
->significand
[it
] >> 16;
258 pb
->blength
= 2 * iz
+ 2;
259 if (pb
->bsignificand
[0] == 0) {
260 for (it
= 1; it
< pb
->blength
; it
++)
261 pb
->bsignificand
[it
- 1] = pb
->bsignificand
[it
];
264 *pe
= pu
->exponent
+ 1 - 16 * pb
->blength
;
268 printf(" unpacked to big float 2**%d * ", *pe
);
269 _display_big_float(pb
, 2);
274 _mul_65536short(_big_float
*pbf
, unsigned long carry
)
276 /* *pbf *= 65536 ; += carry ; */
281 for (j
= 0; j
< pbf
->blength
; j
++) {
282 p
= _prod_65536_b10000(pbf
->bsignificand
[j
], carry
);
283 pbf
->bsignificand
[j
] = (_BIG_FLOAT_DIGIT
) (p
& 0xffff);
287 p
= _carry_out_b10000(carry
);
288 pbf
->bsignificand
[j
++] = (_BIG_FLOAT_DIGIT
) (p
& 0xffff);
295 _big_binary_to_big_decimal(_big_float
*pb
, _big_float
*pd
)
297 /* Convert _big_float from binary form to decimal form. */
301 pd
->bsignificand
[0] = pb
->bsignificand
[pb
->blength
- 1] % 10000;
302 if (pd
->bsignificand
[0] == pb
->bsignificand
[pb
->blength
- 1]) {
306 pd
->bsignificand
[1] = pb
->bsignificand
[pb
->blength
- 1] / 10000;
308 for (i
= pb
->blength
- 2; i
>= 0; i
--) { /* Multiply by 2**16 and
309 * add next significand. */
310 _mul_65536short(pd
, (unsigned long) pb
->bsignificand
[i
]);
312 for (i
= 0; i
<= (pb
->bexponent
- 16); i
+= 16) { /* Multiply by 2**16 for
313 * each trailing zero. */
314 _mul_65536short(pd
, (unsigned long) 0);
316 if (pb
->bexponent
> i
)
317 _left_shift_base_ten(pd
, (short unsigned) (pb
->bexponent
- i
));
321 printf(" _big_binary_to_big_decimal ");
322 _display_big_float(pd
, 10);