num.c (103d7cdfb7435591049413e1bc39482cb316efb7) | num.c (76238846ad3e9e271a3d1f792f72beab727fd153) |
---|---|
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 --- 3501 unchanged lines hidden (view full) --- 3510 { 3511#if BC_ENABLE_LIBRARY 3512 BcVm* vm = bcl_getspecific(); 3513#endif // BC_ENABLE_LIBRARY 3514 3515 // Print the sign. 3516 if (BC_NUM_NEG(n)) bc_num_putchar('-', true); 3517 | 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 --- 3501 unchanged lines hidden (view full) --- 3510 { 3511#if BC_ENABLE_LIBRARY 3512 BcVm* vm = bcl_getspecific(); 3513#endif // BC_ENABLE_LIBRARY 3514 3515 // Print the sign. 3516 if (BC_NUM_NEG(n)) bc_num_putchar('-', true); 3517 |
3518 // Print the leading zero if necessary. 3519 if (BC_Z && BC_NUM_RDX_VAL(n) == n->len) | 3518 // Print the leading zero if necessary. We don't print when using 3519 // scientific or engineering modes. 3520 if (BC_Z && BC_NUM_RDX_VAL(n) == n->len && base != 0 && base != 1) |
3520 { 3521 bc_num_printHex(0, 1, false, !newline); 3522 } 3523 } 3524 3525 // Short-circuit 0. 3526 if (BC_NUM_ZERO(n)) bc_num_printHex(0, 1, false, !newline); 3527 else if (base == BC_BASE) bc_num_printDecimal(n, newline); --- 282 unchanged lines hidden (view full) --- 3810 bc_num_free(&temp3); 3811 BC_LONGJMP_CONT(vm); 3812} 3813 3814void 3815bc_num_irand(BcNum* restrict a, BcNum* restrict b, BcRNG* restrict rng) 3816{ 3817 BcNum atemp; | 3521 { 3522 bc_num_printHex(0, 1, false, !newline); 3523 } 3524 } 3525 3526 // Short-circuit 0. 3527 if (BC_NUM_ZERO(n)) bc_num_printHex(0, 1, false, !newline); 3528 else if (base == BC_BASE) bc_num_printDecimal(n, newline); --- 282 unchanged lines hidden (view full) --- 3811 bc_num_free(&temp3); 3812 BC_LONGJMP_CONT(vm); 3813} 3814 3815void 3816bc_num_irand(BcNum* restrict a, BcNum* restrict b, BcRNG* restrict rng) 3817{ 3818 BcNum atemp; |
3818 size_t i, len; | 3819 size_t i; |
3819 3820 assert(a != b); 3821 3822 if (BC_ERR(BC_NUM_NEG(a))) bc_err(BC_ERR_MATH_NEGATIVE); 3823 3824 // If either of these are true, then the numbers are integers. 3825 if (BC_NUM_ZERO(a) || BC_NUM_ONE(a)) return; 3826 3827#if BC_GCC 3828 // This is here in GCC to quiet the "maybe-uninitialized" warning. 3829 atemp.num = NULL; 3830 atemp.len = 0; 3831#endif // BC_GCC 3832 3833 if (BC_ERR(bc_num_nonInt(a, &atemp))) bc_err(BC_ERR_MATH_NON_INTEGER); 3834 3835 assert(atemp.num != NULL); 3836 assert(atemp.len); 3837 | 3820 3821 assert(a != b); 3822 3823 if (BC_ERR(BC_NUM_NEG(a))) bc_err(BC_ERR_MATH_NEGATIVE); 3824 3825 // If either of these are true, then the numbers are integers. 3826 if (BC_NUM_ZERO(a) || BC_NUM_ONE(a)) return; 3827 3828#if BC_GCC 3829 // This is here in GCC to quiet the "maybe-uninitialized" warning. 3830 atemp.num = NULL; 3831 atemp.len = 0; 3832#endif // BC_GCC 3833 3834 if (BC_ERR(bc_num_nonInt(a, &atemp))) bc_err(BC_ERR_MATH_NON_INTEGER); 3835 3836 assert(atemp.num != NULL); 3837 assert(atemp.len); 3838 |
3838 len = atemp.len - 1; | 3839 if (atemp.len > 2) 3840 { 3841 size_t len; |
3839 | 3842 |
3840 // Just generate a random number for each limb. 3841 for (i = 0; i < len; ++i) | 3843 len = atemp.len - 2; 3844 3845 // Just generate a random number for each limb. 3846 for (i = 0; i < len; i += 2) 3847 { 3848 BcRand dig; 3849 3850 dig = bc_rand_bounded(rng, BC_BASE_RAND_POW); 3851 3852 b->num[i] = (BcDig) (dig % BC_BASE_POW); 3853 b->num[i + 1] = (BcDig) (dig / BC_BASE_POW); 3854 } 3855 } 3856 else |
3842 { | 3857 { |
3843 b->num[i] = (BcDig) bc_rand_bounded(rng, BC_BASE_POW); | 3858 // We need this set. 3859 i = 0; |
3844 } 3845 | 3860 } 3861 |
3846 // Do the last digit explicitly because the bound must be right. But only 3847 // do it if the limb does not equal 1. If it does, we have already hit the 3848 // limit. 3849 if (atemp.num[i] != 1) | 3862 // This will be true if there's one full limb after the two limb groups. 3863 if (i == atemp.len - 2) |
3850 { | 3864 { |
3851 b->num[i] = (BcDig) bc_rand_bounded(rng, (BcRand) atemp.num[i]); 3852 b->len = atemp.len; | 3865 // Increment this for easy use. 3866 i += 1; 3867 3868 // If the last digit is not one, we need to set a bound for it 3869 // explicitly. Since there's still an empty limb, we need to fill that. 3870 if (atemp.num[i] != 1) 3871 { 3872 BcRand dig; 3873 BcRand bound; 3874 3875 // Set the bound to the bound of the last limb times the amount 3876 // needed to fill the second-to-last limb as well. 3877 bound = ((BcRand) atemp.num[i]) * BC_BASE_POW; 3878 3879 dig = bc_rand_bounded(rng, bound); 3880 3881 // Fill the last two. 3882 b->num[i - 1] = (BcDig) (dig % BC_BASE_POW); 3883 b->num[i] = (BcDig) (dig / BC_BASE_POW); 3884 3885 // Ensure that the length will be correct. If the last limb is zero, 3886 // then the length needs to be one less than the bound. 3887 b->len = atemp.len - (b->num[i] == 0); 3888 } 3889 // Here the last limb *is* one, which means the last limb does *not* 3890 // need to be filled. Also, the length needs to be one less because the 3891 // last limb is 0. 3892 else 3893 { 3894 b->num[i - 1] = (BcDig) bc_rand_bounded(rng, BC_BASE_POW); 3895 b->len = atemp.len - 1; 3896 } |
3853 } | 3897 } |
3854 // We want 1 less len in the case where we skip the last limb. 3855 else b->len = len; | 3898 // Here, there is only one limb to fill. 3899 else 3900 { 3901 // See above for how this works. 3902 if (atemp.num[i] != 1) 3903 { 3904 b->num[i] = (BcDig) bc_rand_bounded(rng, (BcRand) atemp.num[i]); 3905 b->len = atemp.len - (b->num[i] == 0); 3906 } 3907 else b->len = atemp.len - 1; 3908 } |
3856 3857 bc_num_clean(b); 3858 3859 assert(BC_NUM_RDX_VALID(b)); 3860} 3861#endif // BC_ENABLE_EXTRA_MATH 3862 3863size_t --- 543 unchanged lines hidden --- | 3909 3910 bc_num_clean(b); 3911 3912 assert(BC_NUM_RDX_VALID(b)); 3913} 3914#endif // BC_ENABLE_EXTRA_MATH 3915 3916size_t --- 543 unchanged lines hidden --- |