/* * 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 /\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; }