Canola  0.8.D001
lib/number/z/set.cc
Go to the documentation of this file.
00001 //
00002 // canola - canon canola 1614p emulator
00003 // Copyright (C) 2012 Peter Miller
00004 //
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License, version 3, as
00007 // published by the Free Software Foundation.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License along
00015 // with this program. If not, see <http://www.gnu.org/licenses/>.
00016 //
00017 
00018 #include <lib/ac/assert.h>
00019 #include <lib/ac/limits.h>
00020 #include <lib/ac/string.h>
00021 
00022 #include <lib/number/z.h>
00023 
00024 
00025 void
00026 number_z::set(size_t n, unsigned value)
00027 {
00028     assert(is_valid());
00029     assert(value < 10);
00030     assert(n < INT_MAX);
00031     if (value == 0 && n >= digits_used)
00032         return;
00033     if (n + 1 > digits_allocated)
00034     {
00035         size_t new_digits_allocated =
00036             (digits_allocated ? (digits_allocated * 2) : 16);
00037         for (;;)
00038         {
00039             if (n + 1 <= new_digits_allocated)
00040                 break;
00041             new_digits_allocated *= 2;
00042         }
00043         digit_t *new_digits = new digit_t [new_digits_allocated];
00044         memcpy(new_digits, digits, digits_used);
00045         memset(new_digits + digits_used, 0, new_digits_allocated - digits_used);
00046         delete [] digits;
00047         digits = new_digits;
00048         digits_allocated = new_digits_allocated;
00049     }
00050     assert(n + 1 <= digits_allocated);
00051     digits[n] = value;
00052     if (n >= digits_used)
00053         digits_used = n + 1;
00054 
00055     // If they set the most significant digit to zero, we must normalize.
00056     // (The assert right at the start of this method ensured that the most
00057     // significant digit was not zero when we entered this method, so the loop
00058     // body should be the uncommon case.)
00059     while (digits_used > 0 && digits[digits_used - 1] == 0)
00060         --digits_used;
00061 
00062     assert(is_valid());
00063 }
00064 
00065 
00066 // vim: set ts=8 sw=4 et :