add cal/splitbits.cal

This commit is contained in:
Landon Curt Noll
2023-07-21 23:02:51 -07:00
parent ccd579ecda
commit e05d904821
4 changed files with 177 additions and 15 deletions

24
CHANGES
View File

@@ -2,6 +2,30 @@ The following are the changes from calc version 2.14.2.0 to date:
Ported calc to the s390x IBM Mainframe running RHEL9.1. Ported calc to the s390x IBM Mainframe running RHEL9.1.
Added cal/splitbits.cal:
splitbits(x, b)
Given an integer x, split the value into a list of integers,
each of which is at most b bits long.
The value b must be an integer > 0.
The number of elements in the returned list is:
ceil((highbit(x) + 1) / b)
If x == 0, then a list of 1 element containing 0 is returned.
If x < 0, then the two's compliment of abs(x) is returned.
Even though calc represents negative integers as positive values
with sign bit, the bits returned by this function are as if
the integer converted as if the integer was a two's compliment value.
See also the help command:
; help resource
The following are the changes from calc version 2.14.1.5 to 2.14.1.6: The following are the changes from calc version 2.14.1.5 to 2.14.1.6:

View File

@@ -267,21 +267,22 @@ TRUE= true
# to keep this list in nice sorted order. # to keep this list in nice sorted order.
# #
CALC_FILES= README alg_config.cal beer.cal bernoulli.cal \ CALC_FILES= README alg_config.cal beer.cal bernoulli.cal \
bernpoly.cal bigprime.cal bindings brentsolve.cal chi.cal chrem.cal \ bernpoly.cal bigprime.cal bindings brentsolve.cal chi.cal \
comma.cal constants.cal deg.cal dms.cal dotest.cal ellip.cal \ chrem.cal comma.cal constants.cal deg.cal dms.cal dotest.cal \
factorial.cal factorial2.cal gvec.cal hello.cal hms.cal infinities.cal \ ellip.cal factorial.cal factorial2.cal gvec.cal hello.cal hms.cal \
intfile.cal intnum.cal lambertw.cal linear.cal lnseries.cal lucas.cal \ infinities.cal intfile.cal intnum.cal lambertw.cal linear.cal \
lucas_chk.cal mersenne.cal mfactor.cal mod.cal natnumset.cal \ lnseries.cal lucas.cal lucas_chk.cal mersenne.cal mfactor.cal mod.cal \
palindrome.cal pell.cal pi.cal pix.cal pollard.cal poly.cal prompt.cal \ natnumset.cal palindrome.cal pell.cal pi.cal pix.cal pollard.cal \
psqrt.cal qtime.cal quat.cal randbitrun.cal randmprime.cal \ poly.cal prompt.cal psqrt.cal qtime.cal quat.cal randbitrun.cal \
randombitrun.cal randomrun.cal randrun.cal regress.cal repeat.cal \ randmprime.cal randombitrun.cal randomrun.cal randrun.cal regress.cal \
screen.cal seedrandom.cal set8700.cal set8700.line smallfactors.cal \ repeat.cal screen.cal seedrandom.cal set8700.cal set8700.line \
solve.cal specialfunctions.cal statistics.cal strings.cal sumsq.cal \ smallfactors.cal solve.cal specialfunctions.cal splitbits.cal \
sumtimes.cal surd.cal test1700.cal test2300.cal test2600.cal \ statistics.cal strings.cal sumsq.cal sumtimes.cal surd.cal \
test2700.cal test3100.cal test3300.cal test3400.cal test3500.cal \ test1700.cal test2300.cal test2600.cal test2700.cal test3100.cal \
test4000.cal test4100.cal test4600.cal test5100.cal test5200.cal \ test3300.cal test3400.cal test3500.cal test4000.cal test4100.cal \
test8400.cal test8500.cal test8600.cal test8900.cal toomcook.cal \ test4600.cal test5100.cal test5200.cal test8400.cal test8500.cal \
unitfrac.cal varargs.cal xx_print.cal zeta2.cal test8600.cal test8900.cal toomcook.cal unitfrac.cal varargs.cal \
xx_print.cal zeta2.cal
# These calc files are now obsolete and are removed by the install rule. # These calc files are now obsolete and are removed by the install rule.
# #

View File

@@ -1433,6 +1433,60 @@ specialfunctions.cal
on the script zeta2.cal. on the script zeta2.cal.
splitbits.cal
splitbits(x, b)
Given an integer x, split the value into a list of integers,
each of which is at most b bits long.
The value b must be an integer > 0.
The number of elements in the returned list is:
ceil((highbit(x) + 1) / b)
If x == 0, then a list of 1 element containing 0 is returned.
If x < 0, then the two's compliment of abs(x) is returned.
Even though calc represents negative integers as positive values
with sign bit, the bits returned by this function are as if
the integer converted as if the integer was a two's compliment
value. For example:
; L = splitbits(-1, 8);
; print L[[0]]
255
; L = splitbits(-2, 8);
; print L[[0]]
254
; L = splitbits(-3, 8);
; print L[[0]]
253
The first element of the list contains the lowest order bits
of x. The last element of the list contains the highest number
bits of x.
For example:
; x = 2^23209-1
; L = splitbits(x, 16);
; print size(L), L[[0]]
; print istype(2, 3i), istype(2, "2"), istype(2, null())
0 0 0
; mat a[2]
; b = list(1,2,3)
; c = assoc()
; obj chongo {was, here} d;
; print istype(a,b), istype(b,c), istype(c,d)
0 0 0
statistics.cal statistics.cal
gammaincoctave(z,a) gammaincoctave(z,a)

83
cal/splitbits.cal Normal file
View File

@@ -0,0 +1,83 @@
/*
* splitbits - split an integer into list on bit boundardies of a fixed size
*
* Copyright (C) 2018,2023 Landon Curt Noll
*
* Calc is open software; you can redistribute it and/or modify it under
* the terms of the version 2.1 of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* Calc is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
* Public License for more details.
*
* A copy of version 2.1 of the GNU Lesser General Public License is
* distributed with calc under the filename COPYING-LGPL. You should have
* received a copy with calc; if not, write to Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Under source code control: 2006/06/07 14:10:11
* File existed as early as: 2006
*
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
* setup splitbits errors
*/
static E_SPLITBITS_1, E_SPLITBITS_2, E_SPLITBITS_3;
if (! iserror(E_SPLITBITS_1)) E_SPLITBITS_1 = newerror("1st argument to splitbits must be an integer");
if (! iserror(E_SPLITBITS_2)) E_SPLITBITS_2 = newerror("2nd argument to splitbits must be an integer");
if (! iserror(E_SPLITBITS_3)) E_SPLITBITS_3 = newerror("2nd argument must be an integer > 0");
/*
* define splitbits function
*/
define splitbits(x, b)
{
local ret; /* list to return */
local mask; /* 2^b-1 */
local x_is_reg = 0; /* true if x < 0 */
/* firewall */
if (! isint(x)) {
return error(E_SPLITBITS_1);
}
if (! isint(b)) {
return error(E_SPLITBITS_2);
}
if (b <= 0) {
return error(E_SPLITBITS_3);
}
/* special case: x == 0 */
if (x == 0) {
return list(0);
}
/* setup for splitting x */
ret = list();
mask = 2^b-1;
if (x < 0) {
x_is_reg = 1;
x = abs(x);
}
/* split x */
while (x > 0) {
printf("%d %x\n", size(ret), x);
if (x_is_reg) {
append(ret, xor(x & mask, mask));
} else {
append(ret, x & mask);
}
x >>= b;
}
/* return list */
return ret;
}