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