1 /* 2 * CDDL HEADER START 3 * 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 7 * with the License. 8 * 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. 13 * 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] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1988 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include "base_conversion.h" 30 31 /* 32 * Fundamental utilities of base conversion required for sprintf - but too 33 * complex or too seldom used to be worth assembly language coding. 34 */ 35 36 /* p = x * y + c ; return (p/10000 << 16 | p%10000) */ 37 unsigned long 38 _prodc_b10000(_BIG_FLOAT_DIGIT x, _BIG_FLOAT_DIGIT y, unsigned long c) 39 { 40 unsigned long p = x * (unsigned long) y + c; 41 42 return ((p / 10000) << 16) | (p % 10000); 43 } 44 45 /* p = x * y ; return p */ 46 unsigned long 47 _prod_b65536(_BIG_FLOAT_DIGIT x, _BIG_FLOAT_DIGIT y) 48 { 49 return (x * (unsigned long)y); 50 } 51 52 /* p = x * y ; return (p/10000 << 16 | p%10000) */ 53 unsigned long 54 _prod_b10000(_BIG_FLOAT_DIGIT x, _BIG_FLOAT_DIGIT y) 55 { 56 unsigned long p = x * (unsigned long) y; 57 58 return ((p / 10000) << 16) | (p % 10000); 59 } 60 61 /* p = x << n + c ; return (p/10000 << 16 | p%10000) */ 62 unsigned long 63 _lshift_b10000(_BIG_FLOAT_DIGIT x, short unsigned n, long unsigned c) 64 { 65 unsigned long p = (((unsigned long) x) << n) + c; 66 67 return ((p / 10000) << 16) | (p % 10000); 68 } 69 70 /* p = x * 10000 + c ; return p */ 71 unsigned long 72 _prod_10000_b65536(_BIG_FLOAT_DIGIT x, long unsigned c) 73 { 74 return (x * (unsigned long) 10000 + c); 75 } 76 77 /* p = x << 16 + c ; return (p/10000 << 16 | p%10000) */ 78 unsigned long 79 _prod_65536_b10000(_BIG_FLOAT_DIGIT x, long unsigned c) 80 { 81 unsigned long p = (((unsigned long) x) << 16) + c; 82 83 return ((p / 10000) << 16) | (p % 10000); 84 } 85 86 /* p = c ; return (p/10000 << 16 | p%10000) */ 87 unsigned long 88 _carry_out_b10000(unsigned long c) 89 { 90 return ((c / 10000) << 16) | (c % 10000); 91 } 92 93 void 94 _left_shift_base_ten(_big_float *pbf, short unsigned multiplier) 95 { 96 /* 97 * Multiply a base-10**4 significand by 2<<multiplier. Extend length 98 * as necessary to accommodate carries. 99 */ 100 101 short unsigned length = pbf->blength; 102 int j; 103 unsigned long carry; 104 long p; 105 106 carry = 0; 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); 110 carry = p >> 16; 111 } 112 while (carry != 0) { 113 p = _carry_out_b10000(carry); 114 pbf->bsignificand[j++] = (_BIG_FLOAT_DIGIT) (p & 0xffff); 115 carry = p >> 16; 116 } 117 pbf->blength = j; 118 } 119 120 void 121 _left_shift_base_two(_big_float *pbf, short unsigned multiplier) 122 { 123 /* 124 * Multiply a base-2**16 significand by 2<<multiplier. Extend length 125 * as necessary to accommodate carries. 126 */ 127 128 short unsigned length = pbf->blength; 129 long unsigned p; 130 int j; 131 unsigned long carry; 132 133 carry = 0; 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); 137 carry = p >> 16; 138 } 139 if (carry != 0) { 140 pbf->bsignificand[j++] = (_BIG_FLOAT_DIGIT) (_carry_out_b65536(carry) & 0xffff); 141 } 142 pbf->blength = j; 143 } 144 145 void 146 _right_shift_base_two(_big_float *pbf, short unsigned multiplier, 147 _BIG_FLOAT_DIGIT *sticky) 148 { 149 /* *pb = *pb / 2**multiplier to normalize. 15 <= multiplier <= 1 */ 150 /* Any bits shifted out got to *sticky. */ 151 152 long unsigned p; 153 int j; 154 unsigned long carry; 155 156 carry = 0; 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); 160 carry = p & 0xffff; 161 } 162 *sticky = (_BIG_FLOAT_DIGIT) carry; 163 } 164 165 void 166 _multiply_base_ten(_big_float *pbf, _BIG_FLOAT_DIGIT multiplier) 167 { 168 /* 169 * Multiply a base-10**4 significand by multiplier. Extend length as 170 * necessary to accommodate carries. 171 */ 172 173 int j; 174 unsigned long carry; 175 long p; 176 177 carry = 0; 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); 181 carry = p >> 16; 182 } 183 while (carry != 0) { 184 p = _carry_out_b10000(carry); 185 pbf->bsignificand[j++] = (_BIG_FLOAT_DIGIT) (p & 0xffff); 186 carry = p >> 16; 187 } 188 pbf->blength = j; 189 } 190 191 void 192 _multiply_base_two(_big_float *pbf, _BIG_FLOAT_DIGIT multiplier, 193 long unsigned carry) 194 { 195 /* 196 * Multiply a base-2**16 significand by multiplier. Extend length as 197 * necessary to accommodate carries. 198 */ 199 200 short unsigned length = pbf->blength; 201 long unsigned p; 202 int j; 203 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); 207 carry = p >> 16; 208 } 209 if (carry != 0) { 210 pbf->bsignificand[j++] = (_BIG_FLOAT_DIGIT) (_carry_out_b65536(carry) & 0xffff); 211 } 212 pbf->blength = j; 213 } 214 215 void 216 _multiply_base_ten_by_two(_big_float *pbf, short unsigned multiplier) 217 { 218 /* 219 * Multiply a base-10**4 significand by 2**multiplier. Extend length 220 * as necessary to accommodate carries. 221 */ 222 223 short unsigned length = pbf->blength; 224 int j; 225 long unsigned carry, p; 226 227 carry = 0; 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); 231 carry = p >> 16; 232 } 233 while (carry != 0) { 234 p = _carry_out_b10000(carry); 235 pbf->bsignificand[j++] = (_BIG_FLOAT_DIGIT) (p & 0xffff); 236 carry = p >> 16; 237 } 238 pbf->blength = j; 239 } 240 241 void 242 _unpacked_to_big_float(unpacked *pu, _big_float *pb, int *pe) 243 { 244 /* 245 * Converts pu into a bigfloat *pb of minimal length; exponent *pe 246 * such that pu = *pb * 2 ** *pe 247 */ 248 249 int iz, it; 250 251 for (iz = (UNPACKED_SIZE - 2); pu->significand[iz] == 0; iz--); /* Find lsw. */ 252 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; 256 } 257 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]; 262 pb->blength--; 263 } 264 *pe = pu->exponent + 1 - 16 * pb->blength; 265 pb->bexponent = 0; 266 267 #ifdef DEBUG 268 printf(" unpacked to big float 2**%d * ", *pe); 269 _display_big_float(pb, 2); 270 #endif 271 } 272 273 void 274 _mul_65536short(_big_float *pbf, unsigned long carry) 275 { 276 /* *pbf *= 65536 ; += carry ; */ 277 278 long unsigned p; 279 int j; 280 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); 284 carry = p >> 16; 285 } 286 while (carry != 0) { 287 p = _carry_out_b10000(carry); 288 pbf->bsignificand[j++] = (_BIG_FLOAT_DIGIT) (p & 0xffff); 289 carry = p >> 16; 290 } 291 pbf->blength = j; 292 } 293 294 void 295 _big_binary_to_big_decimal(_big_float *pb, _big_float *pd) 296 { 297 /* Convert _big_float from binary form to decimal form. */ 298 299 int i; 300 301 pd->bsignificand[0] = pb->bsignificand[pb->blength - 1] % 10000; 302 if (pd->bsignificand[0] == pb->bsignificand[pb->blength - 1]) { 303 pd->blength = 1; 304 } else { 305 pd->blength = 2; 306 pd->bsignificand[1] = pb->bsignificand[pb->blength - 1] / 10000; 307 } 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]); 311 } 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); 315 } 316 if (pb->bexponent > i) 317 _left_shift_base_ten(pd, (short unsigned) (pb->bexponent - i)); 318 pd->bexponent = 0; 319 320 #ifdef DEBUG 321 printf(" _big_binary_to_big_decimal "); 322 _display_big_float(pd, 10); 323 #endif 324 } 325