842
* get_bit_ops --- get the numeric operands of a binary function.
843
* Returns a copy of the operand if either is inf or nan. Otherwise
844
* each operand is converted to an integer if necessary, and
845
* the results are placed in the variables mpz1 and mpz2.
849
get_bit_ops(const char *op)
827
/* get_intval --- get the (converted) integral operand of a binary function. */
830
get_intval(NODE *t1, int argnum, const char *op)
855
if ((_tz1->flags & (NUMCUR|NUMBER)) == 0)
856
lintwarn(_("%s: received non-numeric first argument"), op);
857
if ((_tz2->flags & (NUMCUR|NUMBER)) == 0)
858
lintwarn(_("%s: received non-numeric second argument"), op);
864
if (is_mpg_float(_tz1)) {
865
mpfr_ptr left = _tz1->mpg_numbr;
834
if (do_lint && (t1->flags & (NUMCUR|NUMBER)) == 0)
835
lintwarn(_("%s: received non-numeric argument #%d"), op, argnum);
837
(void) force_number(t1);
839
if (is_mpg_float(t1)) {
840
mpfr_ptr left = t1->mpg_numbr;
866
841
if (! mpfr_number_p(left)) {
870
mpfr_set(res->mpg_numbr, _tz1->mpg_numbr, ROUND_MODE);
845
mpg_fmt(_("%s: argument #%d has invalid value %Rg, using 0"),
849
emalloc(pz, mpz_ptr, sizeof (mpz_t), "get_intval");
851
return pz; /* should be freed */
875
855
if (mpfr_sgn(left) < 0)
877
mpg_fmt(_("%s(%Rg, ..): negative values will give strange results"),
857
mpg_fmt(_("%s: argument #%d negative value %Rg will give strange results"),
880
861
if (! mpfr_integer_p(left))
882
mpg_fmt(_("%s(%Rg, ..): fractional values will be truncated"),
887
mpfr_get_z(_mpz1, left, MPFR_RNDZ); /* float to integer conversion */
890
/* (_tz1->flags & MPZN) != 0 */
893
if (mpz_sgn(mpz1) < 0)
895
mpg_fmt(_("%s(%Zd, ..): negative values will give strange results"),
901
if (is_mpg_float(_tz2)) {
902
mpfr_ptr right = _tz2->mpg_numbr;
903
if (! mpfr_number_p(right)) {
907
mpfr_set(res->mpg_numbr, _tz2->mpg_numbr, ROUND_MODE);
912
if (mpfr_sgn(right) < 0)
914
mpg_fmt(_("%s(.., %Rg): negative values will give strange results"),
917
if (! mpfr_integer_p(right))
919
mpg_fmt(_("%s(.., %Rg): fractional values will be truncated"),
924
mpfr_get_z(_mpz2, right, MPFR_RNDZ); /* float to integer conversion */
927
/* (_tz2->flags & MPZN) != 0 */
930
if (mpz_sgn(mpz2) < 0)
932
mpg_fmt(_("%s(.., %Zd): negative values will give strange results"),
863
mpg_fmt(_("%s: argument #%d fractional value %Rg will be truncated"),
868
emalloc(pz, mpz_ptr, sizeof (mpz_t), "get_intval");
870
mpfr_get_z(pz, left, MPFR_RNDZ); /* float to integer conversion */
871
return pz; /* should be freed */
873
/* (t1->flags & MPZN) != 0 */
878
mpg_fmt(_("%s: argument #%d negative value %Zd will give strange results"),
882
return pz; /* must not be freed */
886
/* free_intval --- free the converted integer value returned by get_intval() */
889
free_intval(NODE *t, mpz_ptr pz)
891
if ((t->flags & MPZN) == 0) {
941
898
/* do_mpfr_lshift --- perform a << operation */
944
901
do_mpfr_lshift(int nargs)
947
904
unsigned long shift;
949
if ((res = get_bit_ops("lshift")) == NULL) {
952
* mpz_get_ui: If op is too big to fit an unsigned long then just
953
* the least significant bits that do fit are returned.
954
* The sign of op is ignored, only the absolute value is used.
957
shift = mpz_get_ui(mpz2); /* GMP integer => unsigned long conversion */
959
mpz_mul_2exp(res->mpg_i, mpz1, shift); /* res = mpz1 * 2^shift */
910
pz1 = get_intval(t1, 1, "lshift");
911
pz2 = get_intval(t2, 2, "lshift");
914
* mpz_get_ui: If op is too big to fit an unsigned long then just
915
* the least significant bits that do fit are returned.
916
* The sign of op is ignored, only the absolute value is used.
919
shift = mpz_get_ui(pz2); /* GMP integer => unsigned long conversion */
921
mpz_mul_2exp(res->mpg_i, pz1, shift); /* res = pz1 * 2^shift */
923
free_intval(t1, pz1);
924
free_intval(t2, pz2);
965
930
/* do_mpfr_rshift --- perform a >> operation */
968
do_mpfr_rhift(int nargs)
933
do_mpfr_rshift(int nargs)
971
936
unsigned long shift;
973
if ((res = get_bit_ops("rshift")) == NULL) {
975
* mpz_get_ui: If op is too big to fit an unsigned long then just
976
* the least significant bits that do fit are returned.
977
* The sign of op is ignored, only the absolute value is used.
980
shift = mpz_get_ui(mpz2); /* GMP integer => unsigned long conversion */
982
mpz_fdiv_q_2exp(res->mpg_i, mpz1, shift); /* res = mpz1 / 2^shift, round towards −inf */
942
pz1 = get_intval(t1, 1, "rshift");
943
pz2 = get_intval(t2, 2, "rshift");
945
/* N.B: See do_mpfp_lshift. */
946
shift = mpz_get_ui(pz2); /* GMP integer => unsigned long conversion */
948
mpz_fdiv_q_2exp(res->mpg_i, pz1, shift); /* res = pz1 / 2^shift, round towards −inf */
950
free_intval(t1, pz1);
951
free_intval(t2, pz2);
988
958
/* do_mpfr_and --- perform an & operation */
991
961
do_mpfr_and(int nargs)
995
if ((res = get_bit_ops("and")) == NULL) {
997
mpz_and(res->mpg_i, mpz1, mpz2);
968
fatal(_("and: called with less than two arguments"));
971
pz2 = get_intval(t2, nargs, "and");
974
for (i = 1; i < nargs; i++) {
976
pz1 = get_intval(t1, nargs - i, "and");
977
mpz_and(res->mpg_i, pz1, pz2);
978
free_intval(t1, pz1);
981
free_intval(t2, pz2);
1003
990
/* do_mpfr_or --- perform an | operation */
1006
993
do_mpfr_or(int nargs)
1010
if ((res = get_bit_ops("or")) == NULL) {
1011
res = mpg_integer();
1012
mpz_ior(res->mpg_i, mpz1, mpz2);
1000
fatal(_("or: called with less than two arguments"));
1003
pz2 = get_intval(t2, nargs, "or");
1005
res = mpg_integer();
1006
for (i = 1; i < nargs; i++) {
1008
pz1 = get_intval(t1, nargs - i, "or");
1009
mpz_ior(res->mpg_i, pz1, pz2);
1010
free_intval(t1, pz1);
1013
free_intval(t2, pz2);
1021
/* do_mpfr_xor --- perform an ^ operation */
1024
do_mpfr_xor(int nargs)
1026
NODE *t1, *t2, *res;
1031
fatal(_("xor: called with less than two arguments"));
1034
pz2 = get_intval(t2, nargs, "xor");
1036
res = mpg_integer();
1037
for (i = 1; i < nargs; i++) {
1039
pz1 = get_intval(t1, nargs - i, "xor");
1040
mpz_xor(res->mpg_i, pz1, pz2);
1041
free_intval(t1, pz1);
1044
free_intval(t2, pz2);