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 --- |