cs440-final/integer.cpp

158 lines
4.7 KiB
C++

#include <algorithm>
#include <cassert>
#include <cstddef>
#include <iostream>
#define todo(msg) \
std::cerr << msg << std::endl; \
assert(false);
// TODO: try to maximize rvalue usage to reuse resources
// "Use rvalue references to reuse the resources of temporaries when possible,
// particularly for binary operands."
// [50 pts, 10 commits] Write a class named Integer that can hold
// arbitrary-length, signed integers. Use unsigned chars (i.e., bytes) for the
// internal storage. Put one decimal digit per byte. The ones digit should be
// first in the array, etc. You must use a pointer to unsigned char internally
// to point to the data. The internal array must grow as needed, but you do not
// need to shrink it. The constructor should take a single argument of a long
// type, used to initialize the number. Use a default argument so that a
// constructor with no arguments will initialize the integer to 0. Use rvalue
// references to reuse the resources of temporaries when possible, particularly
// for binary operands. Support the plus, minus, unary minus, multiplication,
// equality, greater/less, copy/move assignment/constructor Support outputting
// to a std::ostream via the << operator. Where it makes sense, allow operands
// to be of class Integer, or any integer type. In particular, you need to
// support operations like 1234 + Integer_obj. You should also support
// conversion of Integer to an unsigned long, so that operations like bitwise
// AND will work: Integer_object^123.
class Integer {
using byte = unsigned char;
// bytes are litle endian
byte *bytes;
bool isNegative;
std::size_t size;
public:
Integer(long long num = 0)
: bytes{new byte[sizeof(long long)]}, isNegative{num < 0},
size{sizeof(long long)} {
for (std::size_t i = 0; i < size; i++) {
bytes[i] = num % 256;
num /= 256;
}
}
Integer(Integer const &rhs)
: bytes{new byte[rhs.size]}, isNegative{rhs.isNegative}, size{rhs.size} {
for (std::size_t i = 0; i < size; i++) {
bytes[i] = rhs.bytes[i];
}
}
Integer(Integer &&rhs)
: bytes{rhs.bytes}, isNegative{rhs.isNegative}, size{rhs.size} {
rhs.bytes = nullptr;
}
~Integer() {
delete[] bytes;
bytes = nullptr;
}
Integer &operator=(Integer const &rhs) {
delete[] bytes;
bytes = new byte[rhs.size];
size = rhs.size;
isNegative = rhs.isNegative;
for (std::size_t i = 0; i < size; i++) {
bytes[i] = rhs.bytes[i];
}
return *this;
}
Integer &operator=(Integer &&rhs) {
bytes = rhs.bytes;
rhs.bytes = nullptr;
size = rhs.size;
isNegative = rhs.isNegative;
return *this;
}
friend Integer &operator+=(Integer &lhs, Integer const &rhs) {
todo("+=");
return lhs;
}
friend Integer &operator-=(Integer &lhs, Integer const &rhs) {
todo("-=");
return lhs;
}
friend Integer &operator*=(Integer &lhs, Integer const &rhs) {
Integer tmp = std::move(lhs);
Integer tmp_r = rhs;
lhs = 0;
while (tmp_r > 0) {
lhs += tmp;
tmp_r -= 1;
}
return lhs;
}
friend Integer &operator/=(Integer &lhs, Integer const &rhs) {
Integer tmp = std::move(lhs);
lhs = 0;
while (tmp > rhs) {
tmp -= rhs;
lhs += 1;
}
return lhs;
}
friend Integer operator+(Integer const &lhs, Integer const &rhs) {
Integer ret{lhs};
ret += rhs;
return ret;
}
friend Integer operator-(Integer const &lhs, Integer const &rhs) {
Integer ret{lhs};
ret -= rhs;
return ret;
}
friend Integer operator*(Integer const &lhs, Integer const &rhs) {
Integer ret{lhs};
ret *= rhs;
return ret;
}
friend Integer operator/(Integer const &lhs, Integer const &rhs) {
Integer ret{lhs};
ret /= rhs;
return ret;
}
friend Integer operator-(Integer const &val) {
Integer ret = val;
ret.isNegative = !ret.isNegative;
return ret;
}
friend bool operator<(Integer const &lhs, Integer const &rhs) {
todo("operator<");
}
friend bool operator>(Integer const &lhs, Integer const &rhs) {
todo("operator>");
}
friend bool operator==(Integer const &lhs, Integer const &rhs) {
todo("operator==");
}
friend std::ostream &operator<<(std::ostream &lhs, Integer const &rhs) {
todo("ostream impl");
return lhs;
}
explicit operator unsigned long() {
unsigned long ret = 0;
for (std::size_t i = 0; i < std::min(size, sizeof(unsigned long)); i++) {
ret += (static_cast<unsigned long>(this->bytes[i]) << (i * 8));
}
return ret;
}
};
int main(void) {
for (std::size_t i = 0; i <= 8584148901; i++) {
unsigned long n = i * i;
n = i + i;
n = i - i;
n = i / i;
}
}