I know this is a very noob-ish question,but how do I define an integer's interval?
If I want an integer X to be 56<= X <=1234 , how do I declare X ?
The best way would be to create your own integer class with bounds on it and overloaded operators like +, * and == basically all the ops a normal integer can have. You will have to decide the behavior when the number gets too high or too low, I'll give you a start on the class.
struct mynum {
int value;
static const int upper = 100000;
static const int lower = -100000;
operator int() {
return value;
}
explicit mynum(int v) {
value=v;
if (value > upper)value=upper;
if (value < lower)value=lower;
}
};
mynum operator +(const mynum & first, const mynum & second) {
return mynum(first.value + second.value);
}
There is a question on stackoverflow already like your question. It has a more complete version of what I was doing, it may be a little hard to digest for a beginner but it seems to be exactly what you want.
Related
I am sure this question has been asked already but I couldn't find the answer.
If I have a function, let's say:
int Power(int number, int degree){
if(degree==0){
return 1;
}
return number*Power(number, degree-1);
}
It works only when the degree is a non-negative int. How can I prevent this function from being called with wrong parameters?
For example, if the programmer writes cout<<Power(2, -1);, I want the compiler to refuse to compile the code and return some kind of an error message (e.g. "function Power accepts only non-negative integers").
Another alternative would be for the function to not return any value in this case. For example:
int Power(int number, unsigned int degree){
if(degree<0){
//return nothing
}
if(degree==0){
return 1;
}
return number*Power(number, degree-1);
}
There is an alternative to returning a value: Throw a value. A typical example:
if(degree<0){
throw std::invalid_argument("degree may not be negative!");
}
I want the compiler to refuse to compilate the code
In general, arguments are unknown until runtime, so this is not typically possible.
Your answer does the job for menicely. But I am curious: 'throw' terminates the program and prevents anything after Power() to be executed.
If you catch the thrown object, then you can continue immediately after the function from which the object was thrown.
The mere fact, that C++ does implicit type conversions, leaves you no way out of the predicament, that if you write unsigned int x = -1;, no matter which warnings you turn on with your compiler, you won't see any problem with that.
The only rule coming to mind, which might help you with that, is the notorious "max zero or one implicit conversions" rule. But I doubt it can be exploited in this case. (-1 would need to be converted to unsigned int, then to another type, implicitly). But I think from what I read on the page I linked above, numeric implicit conversions do not really count under some circumstances.
This leaves you but one other, also imperfect option. In the code below, I outline the basic idea. But there is endless room to refine the idea (more on that, later). This option is to resort to optional types in combination with your own integer type. The code below also only hints to what is possible. All that could be done in some fancy monadic framework or whatnot...
Obviously, in the code, posted in the question, it is a bad idea to have argument degree as an unsigned int, because then, a negative value gets implicitly converted and the function cannot protect itself from the hostile degree 0xFFFFFFFF (max value of unsigned int). If it wanted to check, it had better chosen int. Then it could check for negative values.
The code in the question also calls for a stack overflow, given it does not implement power in a tail recursive way. But this is just an aside and not subject to the question at hand. Let's get that one quickly out of the way.
// This version at least has a chance to benefit from tail call optimizations.
int internalPower_1 (int acc, int number, int degree) {
if (1 == degree)
return acc * number;
return internalPower_1(acc*number, number, degree - 1);
}
int Power_1 (int number, int degree) {
if (degree < 0)
throw std::invalid_argument("degree < 0");
return internalPower_1( 1, number, degree);
}
Now, would it not be nice if we could have integer types, which depended on the valid value range? Other languages have it (e.g. Common Lisp). Unless there is already something in boost (I did not check), we have to roll such a thing ourselves.
Code first, excuses later:
#include <iostream>
#include <stdexcept>
#include <limits>
#include <optional>
#include <string>
template <int MINVAL= std::numeric_limits<int>::min(),
int MAXVAL = std::numeric_limits<int>::max()>
struct Integer
{
int value;
static constexpr int MinValue() {
return MINVAL; }
static constexpr int MaxValue() {
return MAXVAL; }
using Class_t = Integer<MINVAL,MAXVAL>;
using Maybe_t = std::optional<Class_t>;
// Values passed in during run time get handled
// and punished at run time.
// No way to work around this, because we are
// feeding our thing of beauty from the nasty
// outside world.
explicit Integer (int v)
: value{v}
{
if (v < MINVAL || v > MAXVAL)
throw std::invalid_argument("Value out of range.");
}
static Maybe_t Init (int v) {
if (v < MINVAL || v > MAXVAL) {
return std::nullopt;
}
return Maybe_t(v);
}
};
using UInt = Integer<0>;
using Int = Integer<>;
std::ostream& operator<< (std::ostream& os,
const typename Int::Maybe_t & v) {
if (v) {
os << v->value;
} else {
os << std::string("NIL");
}
return os;
}
template <class T>
auto operator* (const T& x,
const T& y)
-> T {
if (x && y)
return T::value_type::Init(x->value * y->value);
return std::nullopt;
}
Int::Maybe_t internalPower_3 (const Int::Maybe_t& acc,
const Int::Maybe_t& number,
const UInt::Maybe_t& degree) {
if (!acc) return std::nullopt;
if (!degree) return std::nullopt;
if (1 == degree->value) {
return Int::Init(acc->value * number->value);
}
return internalPower_3(acc * number,
number,
UInt::Init(degree->value - 1));
}
Int::Maybe_t Power_3 (const Int::Maybe_t& number,
const UInt::Maybe_t& degree) {
if (!number) return std::nullopt;
return internalPower_3 (Int::Init(1),
number,
degree);
}
int main (int argc, const char* argv[]) {
std::cout << Power_1 (2, 3) << std::endl;
std::cout << Power_3 (Int::Init(2),
UInt::Init(3)) << std::endl;
std::cout << Power_3 (Int::Init(2),
UInt::Init(-2)) << std::endl;
std::cout << "UInt min value = "
<< UInt::MinValue() << std::endl
<< "Uint max value = "
<< UInt::MaxValue() << std::endl;
return 0;
}
The key here is, that the function Int::Init() returns Int::Maybe_t. Thus, before the error can propagate, the user gets a std::nullopt very early, if they try to init with a value which is out of range. Using the constructor of Int, instead would result in an exception.
In order for the code to be able to check, both signed and unsigned instances of the template (e.g. Integer<-10,10> or Integer<0,20>) use a signed int as storage, thus being able to check for invalid values, sneaking in via implicit type conversions. At the expense, that our unsigned on a 32 bit system would be only 31 bit...
What this code does not show, but which could be nice, is the idea, that the resulting type of an operation with two (different instances of) Integers, could be yet another different instance of Integer. Example: auto x = Integer<0,5>::Init(3) - Integer<0,5>::Init(5) In our current implementation, this would result in a nullopt, preserving the type Integer<0,5>. In a maybe better world, though it would as well be possible, that the result would be an Integer<-2,5>.
Anyway, as it is, some might find my little Integer<,> experiment interesting. After all, using types to be more expressive is good, right? If you write a function like typename Integer<-10,0>::Maybe_t foo(Integer<0,5>::Maybe_t x) is quite self explaining as to which range of values are valid for x.
Do datatypes exist in C++ with range
1 <= N <= 1018
0 <= K <= 1018
If not, is there anyway to restrict a variables input range?
Since 1018 < 264, unsigned long long will be big enough to hold values in your requested ranges.
Regarding "restricting a variable's input range", it's not clear what kind of restrictions you have in mind:
Do you want functionality such that values declared outside the range fail to compile?
Do you want functionality such that if value is computed that falls outside that range, some special action (such as crashing the program, or throwing an exception, or printing an error message) occurs?
Or are you looking for a datatype that clamps "out of range" values to the nearest value in the range?
Or are you looking for a datatype that acts like C++'s build-in unsigned datatypes, where overflow (and underflow) cause a modulo-style "wrap-around" in the represented value?
Some of those handling strategies could be implemented via a custom class (at the cost of a certain amount of efficiency). If you don't need any particular error-checking for out-of-range values, OTOH, then plain old unsigned long long will work fine and be most efficient as it maps directly to the underlying CPU hardware.
If you need to limit the range you can wrap the variable in a class. You can overload the operators so that you can do arithmetic with the value as you would normally do.
Usually I would resort to templates to implement such functionality but I think the example below is easier to understand.
class MyInt
{
public:
MyInt(int minval, int maxval);
MyInt& operator=(MyInt const& rhs);
MyInt& operator=(int rhs);
private:
int _val;
int _minval;
int _maxval;
bool _is_inrange(int val);
};
Whenever you perform an operation on the class it needs to check whether the result is in the correct range. Of course the data type you base your class on needs to be able to accomodate the desired value range. I used int as an example. If you use templates you could set select the base data type when instantiating the class.
MyInt::MyInt(int minval, int maxval)
{
_minval = minval;
_maxval = maxval;
}
bool MyInt::_is_inrange(int val)
{
return _minval <= val && val < _maxval;
}
You can overload the operators to work with the values in the same way you are working with primitive datatypes. I have implemented the assignment operator as an example but you can also overload the arithmetic operators.
MyInt& MyInt::operator=(int rhs)
{
if (_is_inrange(rhs))
{
_val = rhs;
}
else
{
// throw an error or do something else.
cout << "Error: Invalid value" << endl;
}
return *this;
}
MyInt& MyInt::operator=(MyInt const& rhs)
{
if (_is_inrange(rhs._val))
{
_val = rhs._val;
}
else
{
// throw an error or do something else.
cout << "Error: Invalid value" << endl;
}
return *this;
}
And finally here is how you would use that class in a program.
int main()
{
MyInt custom_int(0, 10);
cout << "Assigning valid value..." << endl;
custom_int = 9;
cout << "Assigning invalid value..." << endl;
custom_int = 10;
return 0;
}
I've been writing C++ a long time and maybe it's because I don't need to do this very often, but I seem to be lacking with regard to operator overloading. I use it from time to time, but never needed to do what I wanted to do recently and found it somewhat problematic.
class foo
{
public:
static const size_t ARRAY_SIZE = 100000;
uint8_t& operator[](const size_t& index) { return my_array[index >> 3]; }
// problematic equality operator
bool operator==(const size_t& index) const { return my_array[index >> 3] & (1 << (index & 7)); }
//
// Need an assignment operator to do:
// my_array[index >> 3] |= 1 << (index & 7);
// ^------------------^ might not needed as it's returned from [] operator
private:
std::array<uint8_t, (ARRAY_SIZE >> 3) + ((ARRAY_SIZE & 7) ? 1 : 0)> my_array;
};
Now as you can see from the above, what is being done here is to take a size_t number and store it in it's relative bit position. So, 5 for instance would be stored in bit 4 of byte 0 and 9 would be stored in bit 1 of byte 1 in the array etc.
Now the subscript operator works fine and returns the correct byte from the array, but that left the problem of things like this:
if (foo[n]) // where n is a size_t integer representing a bit position
It then dawned on me that the above is an abbreviated form of:
if (foo[n] == true)
and so that led to me writing the above equality operator, but for some reason I don't understand, the operator isn't called. I thought it would have been called following the subscript operator, or is it not called because it's not an object of type foo anymore? What's the best way to fix this? Is it to write an external operator== and make it a friend of foo?
Oh and some pointers regarding the construction of the assignment operator would be appreciated too. Thanks very much...
EDIT:
Thanks for all the help people. I do think it's incredibly harsh to get downvoted for asking a question about something I didn't quite understand. It's not like it was a stupid question or anything and if you re-read my original question properly, I did actually question that foo might not be the correct type after the subscript operator, that a few of you have pointed out. Anyway, here's a bit more context. I haven't had chance to properly study all the great replies...
I did originally write the operator like this, which did actually return the correct bit from the array. Something someone has already pointed out.
bool operator[](const size_t index) const { return my_array[index >> 3] & (1 << (index & 7)); }
What I then had a problem with was setting the bits in the array:
foo f;
if (f[3]) // this is fine
But doing something like:
f[6] = true;
I guess what I was hoping for was a more elegant way of doing this than writing the following:-
class Foo
{
public:
static const size_t MAX_LIST_SIZE = 100000;
bool get(const size_t index) const { return my_array[index >> 3] & (1 << (index & 7)); }
void set(const size_t index) { my_array[index >> 3] |= 1 << (index & 7); }
private:
std::array<uint8_t, ((MAX_LIST_SIZE >> 3) + ((MAX_LIST_SIZE & 7) ? 1 : 0))> my_array;
}
and then using the class like this:
Foo f
f.set(10);
if (f.get(10))
...
I just thought it would be easier to overload the operators, but from the look of it, it seems more cumbersome. (Oh and someone asked why I used uint8_t rather than bool, well this is because on this particular platform, bool is actually 32bits!)
Here we have several deep-ish misunderstandings.
Now the subscript operator works fine and returns the correct byte
from the array, but that left the problem of things like this:
if (foo[n]) // where n is a size_t integer representing a bit position
Your problem here is not the if per se; it's that you are returning the wrong thing. If you are building a packed bit set, your operator[] should just return the value of the bit at the requested position. So:
bool operator[](size_t index) { return (my_array[index >> 3]) & (1<<(index&7)); }
and here your if, as well as any other operation involving your operator[], will work as expected.
It then dawned on me that the above is an abbreviated form of:
if (foo[n] == true)
It is not. if evaluates the expression insides the parentheses, and (essentially) casts it to a boolean; if the result is true, it executes the branch, otherwise it does not.
and so that led to me writing the above equality operator, but for some reason I don't understand, the operator isn't called.
The operator isn't called because:
as explained above, the operator== is never involved in if (foo[n]);
even if you explicitly wrote if (foo[n]==true), your operator wouldn't be invoked, because once your operator[] returns, foo is no longer involved.
Think about it: even in your "original" operator[] you return a reference to uint8_t. The statement:
if (a[n] == true)
(with a being of type foo)
is effectively the same as:
uint8_t &temp = a[n];
if (temp == true)
Now, in the expression temp == true the type of a is never mentioned - there's only temp, which is an uint8_t&, independently of how it was ever obtained, and true, a bool literal. Your operator== would be considered if you were comparing a with a size_t, but that would make no sense.
Finally, about your comment:
// Need an assignment operator to do:
// my_array[index >> 3] |= 1 << (index & 7);
// ^------------------^ might not needed as it's returned from [] operator
this, again, won't work for the exact same reason - you need an operator overload to work on the return value of operator[], not on the foo class itself.
This is generally accomplished by having operator[] return not the value itself, but a proxy object, which remembers its parent and the requested index, and provides its own operator== and operator= that perform what you were trying to put straight in the foo class (along with extra operators that make it possible to it to pass for a reference to a boolean).
Something like:
struct PackedBitVector {
static const size_t ARRAY_SIZE = 100000;
struct ElementProxy {
PackedBitVector &parent;
size_t idx;
operator bool() const { return parent.data[idx>>3] & (1<<(idx&7)) }
bool operator==(bool other) const { return bool(*this) == other; }
bool operator!=(bool other) const { return !(*this == other); }
ElementProxy &operator=(bool other) {
if(other) parent.data[idx>>3] |= 1<<(idx&7);
else parent.data[idx>>3] &= ~(1<<(idx&7));
return *this;
}
}:
ElementProxy operator[](size_t index) { return ElementProxy{*this, index}; }
private:
std::array<uint8_t, (ARRAY_SIZE >> 3) + ((ARRAY_SIZE & 7) ? 1 : 0)> data;
};
To make this work in general you'd have to add a full bucket of other operators, so that this proxy object could credibly pass as a reference to a bool, which is what std::vector<bool> does.
About this, from your remark about bool being 32 bit wide on your platform you seem not to know that std::vector<bool> already sports this "packed bit array" space optimization, so you could directly use it, without reimplementing a broken version of the real thing.
Disclaimer - this is a school assignment, however the problem is still interesting I hope!
I have implemented a custom class called Vector<bool>, which stores the bool entries as bits in an array of numbers.
Everything has gone fine except for implementing this:
bool& operator[](std::size_t index) {
validate_bounds(index);
???
}
The const implementation is quite straight forward, just reading out the value. Here however I can't really understand what to do, and the course is a specialization course on C++ so I'm guessing I should do some type-deffing or something. The data is represented by an array of type unsigned int and should be dynamic (e.g. push_back(bool value) should be implemented).
I solved this implementing a proxy class:
class BoolVectorProxy {
public:
explicit BoolVectorProxy(unsigned int& reference, unsigned char index) {
this->reference = &reference;
this->index = index;
}
void operator=(const bool v) {
if (v) *reference |= 1 << index;
else *reference &= ~(1 << index);
}
operator bool() const {
return (*reference >> index) & 1;
}
private:
unsigned int* reference;
unsigned char index;
};
And inside the main class:
BoolVectorProxy operator[](std::size_t index) {
validate_bound(index);
return BoolVectorProxy(array[index / BLOCK_CAPACITY], index % BLOCK_CAPACITY);
}
I also use Catch as a testing library, the code passes this test:
TEST_CASE("access and assignment with brackets", "[Vector]") {
Vector<bool> a(10);
a[0] = true;
a[0] = false;
REQUIRE(!a[0]);
a[1] = true;
REQUIRE(a[1]);
const Vector<bool> &b = a;
REQUIRE(!b[0]);
REQUIRE(b[1]);
a[0] = true;
REQUIRE(a[0]);
REQUIRE(b[0]);
REQUIRE(b.size() == 10);
REQUIRE_THROWS(a[-1]);
REQUIRE_THROWS(a[10]);
REQUIRE_THROWS(b[-1]);
REQUIRE_THROWS(b[10]);
}
If anyone finds any issues or improvements that can be made, please comment, thanks!
Basically implementing operator[] is the same as implementing const operator[] as you might expect, it's just that one is writable (lvalue) and the other is read only (rvalue).
I think you've got a understanding of the problem : you can convert an unsigned int into a bool using bitwise operations, and you can also say "if the nth bool is modified in X, do a bitwise operation with X and it's done !". But this operator means : I want a lvalue of the bool so I can modify it whenever I want and have an impact on the integer associated. It means that you want a reference of a bool, or in your case a reference of a single bit, so you can modify that bit on the fly. Unfortunately you can't reference a single bit, the smallest you can do is a whole byte (with char), so you would have to take a chunk of at least 7 other booleans with you. That's not what you want.
That being said, I understand that it might be for your assignment, but converting bools into multiple unsigned int is more like useless C optimization to me. You would be better with having a single array of bools (C-style), and doing the memory handling manually, because that is almost what you are doing. Plus with that method, you would actually be able to reference one single boolean (and be able to modify it) without touching the others. Is it mandatory that you have to use an array of unsigned int for this assignment ?
So I'm in a summer OO class and we have a test tomorrow based around this project. Basically we need to create an array that holds an unspecified amount of bits and write four functions that perform operations on this array- Set() //set bit with given index to 1, Unset() //set bit with given index to 0, Flip() // change bit (with given index) and Query() // return true if the given bit is set to 1, false otherwise.
Here's a complete description if anyone is interested: http://pastebin.com/v7BCCYjh and some sample runs: http://pastebin.com/1ijh5p7p
The problem I'm having is with the high level concept. I'm pretty sure we're meant to store byte representations of the bits in each index of the array. If that is true, then I'm completely at a loss for how to implement the functions. If anyone can give me some pointers on how to approach this (I need to have a good understanding of it by tonight because I have to write out some pseudo code for it tomorrow for a midterm) I would be much, much appreciative.
Here's my .h if it helps
// bitarray.h
//
// BitArray class declaration
#ifndef _BITARRAY_H
#define _BITARRAY_H
#include <iostream>
using namespace std;
class BitArray
{
friend ostream& operator<< (ostream& os, const BitArray& a);
friend bool operator== (const BitArray&, const BitArray&);
friend bool operator!= (const BitArray&, const BitArray&);
public:
BitArray(unsigned int n); // Construct an array that can handle n bits
BitArray(const BitArray&); // copy constructor
~BitArray(); // destructor
BitArray& operator= (const BitArray& a); // assignment operator
unsigned int Length() const; // return number of bits in bitarray
void Set (unsigned int index); // set bit with given index to 1
void Unset (unsigned int index); // set bit with given index to 0
void Flip (unsigned int index); // change bit (with given index)
bool Query (unsigned int index) const; // return true if the given bit
// is set to 1, false otherwise
private:
unsigned char* barray; // pointer to the bit array
int arraySize;
};
#endif
And my constructor:
BitArray::BitArray(unsigned int n){
int size = sizeof(char);
if(n%(8*size) != 0)
arraySize = ((n/(8*size))+1);
else
arraySize = n/(8*size);
barray = new unsigned char[arraySize];
for(int i = 0; i < arraySize; i++)
barray[i] = 0;
}
For Set() and Query(), find the position of the word that holds the bit you are interested in. (Your code seems to use char as words.) Then, find the position of the bit within this word. Create a bitmask that addresses the specific bit, you will need a shifting operator for this. Recall the bitwise operators which will finally help you do the job. Sometimes the bitwise assignment operators will be more elegant.
Do you remember the bitwise XOR operator in C++? Use this with the concept learned from Set() to implement Flip(). Use the bitwise negation operator to finally implement Unset().
Note that your way of determining the array size is overly complicated. Recall that ceil(a/b) == floor((a+b-1)/b) in the cases that can happen here.
Consider using std::vector instead of a plain array if you are allowed to. SPOILER BELOW!
There is also an interesting specialization of this class.
Impress your teacher by turning your class into a template where you can specify the actual storage unit (char, uint16_t, ...) as parameter. For starters, say typedef char WORD_TYPE and see if your code later compiles when you change the definition of WORD_TYPE.
You could treat array of integers as an array of bits.
Say, you have an array A = [0xC30FF0C3, 0xC20FF0C3], and you want to access the 53. bit.
You could find the index of an int that holds the 53. bit doing floor(53 / 32) which is 1 and the bit position within that int doing 53 % 32, which is 21.
As for the Flip function...
Well, you already have Query(), Set(), Unset().
Simple
Flip(i) {
Query(i) ? Unset(i) : Set(i)
}
would do the job.