after multiple objections of libtom users [1], we decided to change licensing
[libtomfloat.git] / mpf_normalize.c
blob0b7dab232b98ffedb69bbb673978355df5e8eb82
1 /* LibTomFloat, multiple-precision floating-point library
3 * LibTomFloat is a library that provides multiple-precision
4 * floating-point artihmetic as well as trigonometric functionality.
6 * This library requires the public domain LibTomMath to be installed.
7 *
8 * This library is free for all purposes without any express
9 * gurantee it works
11 * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org
13 #include <tomfloat.h>
15 int mpf_normalize(mp_float *a)
17 long cb, diff;
18 int err;
19 mp_digit c;
21 /* sanity */
22 if (a->radix < 2) {
23 return MP_VAL;
26 cb = mp_count_bits(&(a->mantissa));
27 if (cb > a->radix) {
28 diff = cb - a->radix;
29 a->exp += diff;
31 /* round it, add 1 after shift if diff-1'th bit is 1 */
32 c = a->mantissa.dp[diff/DIGIT_BIT] & (1U<<(diff%DIGIT_BIT));
33 if ((err = mp_div_2d(&(a->mantissa), diff, &(a->mantissa), NULL)) != MP_OKAY) {
34 return err;
37 if (c != 0) {
38 return mp_add_d(&(a->mantissa), 1, &(a->mantissa));
39 } else {
40 return MP_OKAY;
42 } else if (cb < a->radix) {
43 if (mp_iszero(&(a->mantissa)) == MP_YES) {
44 return mpf_const_0(a);
45 } else {
46 diff = a->radix - cb;
47 a->exp -= diff;
48 return mp_mul_2d(&(a->mantissa), diff, &(a->mantissa));
51 return MP_OKAY;