num.c (aa339f1d5df9e38f36a34eb522355c4eebcae6c4) num.c (f4fbc49d201f81c481a33fac6ba28e19faf96260)
1/*
2 * *****************************************************************************
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 *
6 * Copyright (c) 2018-2023 Gavin D. Howard and contributors.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 3193 unchanged lines hidden (view full) ---

3202 // Go through the stack backwards and print each digit.
3203 for (i = 0; i < stack.len; ++i)
3204 {
3205 ptr = bc_vec_item_rev(&stack, i);
3206
3207 assert(ptr != NULL);
3208
3209 // While the first three arguments should be self-explanatory, the last
1/*
2 * *****************************************************************************
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 *
6 * Copyright (c) 2018-2023 Gavin D. Howard and contributors.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 3193 unchanged lines hidden (view full) ---

3202 // Go through the stack backwards and print each digit.
3203 for (i = 0; i < stack.len; ++i)
3204 {
3205 ptr = bc_vec_item_rev(&stack, i);
3206
3207 assert(ptr != NULL);
3208
3209 // While the first three arguments should be self-explanatory, the last
3210 // needs explaining. I don't want to print a newline when the last digit
3211 // to be printed could take the place of the backslash rather than being
3212 // pushed, as a single character, to the next line. That's what that
3213 // last argument does for bc.
3210 // needs explaining. I don't want to print a backslash+newline when the
3211 // last digit to be printed could take the place of the backslash rather
3212 // than being pushed, as a single character, to the next line. That's
3213 // what that last argument does for bc.
3214 //
3215 // First, it needs to check if newlines are completely disabled. If they
3216 // are not disabled, it needs to check the next part.
3217 //
3218 // If the number has a scale, then because we are printing just the
3219 // integer part, there will be at least two more characters (a radix
3220 // point plus at least one digit). So if there is a scale, a backslash
3221 // is necessary.
3222 //
3223 // Finally, the last condition checks to see if we are at the end of the
3224 // stack. If we are *not* (i.e., the index is not one less than the
3225 // stack length), then a backslash is necessary because there is at
3226 // least one more character for at least one more digit). Otherwise, if
3227 // the index is equal to one less than the stack length, we want to
3228 // disable backslash printing.
3229 //
3230 // The function that prints bases 17 and above will take care of not
3231 // printing a backslash in the right case.
3214 print(*ptr, len, false,
3232 print(*ptr, len, false,
3215 !newline || (n->scale != 0 || i == stack.len - 1));
3233 !newline || (n->scale != 0 || i < stack.len - 1));
3216 }
3217
3218 // We are done if there is no fractional part.
3219 if (!n->scale) goto err;
3220
3221 BC_SIG_LOCK;
3222
3223 // Reset the jump because some locals are changing.

--- 862 unchanged lines hidden (view full) ---

4086 else realscale = scale;
4087
4088 // Set parameters for the result.
4089 len = bc_vm_growSize(bc_num_intDigits(a), 1);
4090 rdx = BC_NUM_RDX(realscale);
4091
4092 // Square root needs half of the length of the parameter.
4093 req = bc_vm_growSize(BC_MAX(rdx, BC_NUM_RDX_VAL(a)), len >> 1);
3234 }
3235
3236 // We are done if there is no fractional part.
3237 if (!n->scale) goto err;
3238
3239 BC_SIG_LOCK;
3240
3241 // Reset the jump because some locals are changing.

--- 862 unchanged lines hidden (view full) ---

4104 else realscale = scale;
4105
4106 // Set parameters for the result.
4107 len = bc_vm_growSize(bc_num_intDigits(a), 1);
4108 rdx = BC_NUM_RDX(realscale);
4109
4110 // Square root needs half of the length of the parameter.
4111 req = bc_vm_growSize(BC_MAX(rdx, BC_NUM_RDX_VAL(a)), len >> 1);
4112 req = bc_vm_growSize(req, 1);
4094
4095 BC_SIG_LOCK;
4096
4097 // Unlike the binary operators, this function is the only single parameter
4098 // function and is expected to initialize the result. This means that it
4099 // expects that b is *NOT* preallocated. We allocate it here.
4113
4114 BC_SIG_LOCK;
4115
4116 // Unlike the binary operators, this function is the only single parameter
4117 // function and is expected to initialize the result. This means that it
4118 // expects that b is *NOT* preallocated. We allocate it here.
4100 bc_num_init(b, bc_vm_growSize(req, 1));
4119 bc_num_init(b, req);
4101
4102 BC_SIG_UNLOCK;
4103
4104 assert(a != NULL && b != NULL && a != b);
4105 assert(a->num != NULL && b->num != NULL);
4106
4107 // Easy case.
4108 if (BC_NUM_ZERO(a))

--- 16 unchanged lines hidden (view full) ---

4125 len = bc_vm_growSize(a->len, rdx);
4126
4127 BC_SIG_LOCK;
4128
4129 bc_num_init(&num1, len);
4130 bc_num_init(&num2, len);
4131 bc_num_setup(&half, half_digs, sizeof(half_digs) / sizeof(BcDig));
4132
4120
4121 BC_SIG_UNLOCK;
4122
4123 assert(a != NULL && b != NULL && a != b);
4124 assert(a->num != NULL && b->num != NULL);
4125
4126 // Easy case.
4127 if (BC_NUM_ZERO(a))

--- 16 unchanged lines hidden (view full) ---

4144 len = bc_vm_growSize(a->len, rdx);
4145
4146 BC_SIG_LOCK;
4147
4148 bc_num_init(&num1, len);
4149 bc_num_init(&num2, len);
4150 bc_num_setup(&half, half_digs, sizeof(half_digs) / sizeof(BcDig));
4151
4133 // There is a division by two in the formula. We setup a number that's 1/2
4152 // There is a division by two in the formula. We set up a number that's 1/2
4134 // so that we can use multiplication instead of heavy division.
4153 // so that we can use multiplication instead of heavy division.
4135 bc_num_one(&half);
4154 bc_num_setToZero(&half, 1);
4136 half.num[0] = BC_BASE_POW / 2;
4137 half.len = 1;
4138 BC_NUM_RDX_SET_NP(half, 1);
4155 half.num[0] = BC_BASE_POW / 2;
4156 half.len = 1;
4157 BC_NUM_RDX_SET_NP(half, 1);
4139 half.scale = 1;
4140
4141 bc_num_init(&f, len);
4142 bc_num_init(&fprime, len);
4143
4144 BC_SETJMP_LOCKED(vm, err);
4145
4146 BC_SIG_UNLOCK;
4147
4148 // Pointers for easy switching.
4149 x0 = &num1;
4150 x1 = &num2;
4151
4152 // Start with 1.
4153 bc_num_one(x0);
4154
4155 // The power of the operand is needed for the estimate.
4156 pow = bc_num_intDigits(a);
4157
4158 // The code in this if statement calculates the initial estimate. First, if
4158
4159 bc_num_init(&f, len);
4160 bc_num_init(&fprime, len);
4161
4162 BC_SETJMP_LOCKED(vm, err);
4163
4164 BC_SIG_UNLOCK;
4165
4166 // Pointers for easy switching.
4167 x0 = &num1;
4168 x1 = &num2;
4169
4170 // Start with 1.
4171 bc_num_one(x0);
4172
4173 // The power of the operand is needed for the estimate.
4174 pow = bc_num_intDigits(a);
4175
4176 // The code in this if statement calculates the initial estimate. First, if
4159 // a is less than 0, then 0 is a good estimate. Otherwise, we want something
4160 // in the same ballpark. That ballpark is pow.
4177 // a is less than 1, then 0 is a good estimate. Otherwise, we want something
4178 // in the same ballpark. That ballpark is half of pow because the result
4179 // will have half the digits.
4161 if (pow)
4162 {
4163 // An odd number is served by starting with 2^((pow-1)/2), and an even
4164 // number is served by starting with 6^((pow-2)/2). Why? Because math.
4165 if (pow & 1) x0->num[0] = 2;
4166 else x0->num[0] = 6;
4167
4168 pow -= 2 - (pow & 1);

--- 291 unchanged lines hidden ---
4180 if (pow)
4181 {
4182 // An odd number is served by starting with 2^((pow-1)/2), and an even
4183 // number is served by starting with 6^((pow-2)/2). Why? Because math.
4184 if (pow & 1) x0->num[0] = 2;
4185 else x0->num[0] = 6;
4186
4187 pow -= 2 - (pow & 1);

--- 291 unchanged lines hidden ---