1. Trang chủ
  2. » Công Nghệ Thông Tin

C++ for Mathematicians An Introduction for Students and Professionals phần 6 doc

52 326 1

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Polynomials and Templates in C++
Chuyên ngành Mathematics
Thể loại Introduction
Định dạng
Số trang 52
Dung lượng 4,01 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

For better readability, you may preferthis: vector< complex > zlist; The pair class template takes two type arguments.. To create an ordered pairwhere the first entry is a real number an

Trang 1

One may think of a template as a procedure schema When the C++ compiler countersmax_of_threein a program, it uses the template to create the appropriateversion.

en-For example, here is amainthat utilizes the adaptable nature ofmax_of_three

The output of thismainis as we expect

The max of 3.4, -4.1, 11.2 is 11.2

The max of 14, 17, 0 is 17

Themax_of_threetemplate works for any typeTfor which<is defined If<

is not defined for the type, the compiler generates an error message For example,consider the followingmain

Trang 2

When we attempt to compile this program, we get the following error messages (yourcomputer might produce different error messages).

max_of_three.h: In function ‘T max_of_three(T, T, T) [with T =

std::complex<double>]’:

main.cc:12: instantiated from here

max_of_three.h:6: error: no match for ‘std::complex<double>& <

argu-It is possible to create templates with multiple type parameters Such templateslook like this:

template <class A, class B>

void do_something(A arg1, B arg2) { }

When the compiler encounters code such as

long alpha = 4;

double beta = 4.5;

do_something(alpha, beta);

it creates and uses a version ofdo_somethingin whichAstands forlongandB

stands fordouble

12.2.1 Using class templates

In Section 2.7 we showed how to declare C++ variables to hold complex numbers.After the directive#include <complex>, we have statements such as these:

complex<double> w(-3.4, 5.1);

complex<long> z(4, -7);

The first declares a complex variablew in which the real and imaginary parts are

double real numbers and the second declares zto be a Gaussian integer (long

integer real and imaginary parts)

The class complex is, in fact, a class template By specifying different typesbetween the<and>delimiters, we create different classes For example, we coulduse theModtype (see Chapter 9):

Trang 3

Likewise,vectoris a class template To create avectorthat contains integers,

we usevector<long> To create avectorcontaining complex numbers with realcoefficients, the following mildly baroque construction is required,

vector<complex<double> > zlist;

Note the space between the two closing>delimiters; the space is mandatory here

If it were omitted, the>>would look like the operator we use in expressions such

ascin >> xcausing angst for the compiler For better readability, you may preferthis:

vector< complex<double> > zlist;

The pair class template takes two type arguments To create an ordered pairwhere the first entry is a real number and the second is a Boolean, we write this:pair<double,bool> P;

Using class templates is straightforward The template is transformed into a cific class by adding the needed type argument(s) between the<and>delimiters.The main pitfall to avoid is supplying a type that is incompatible with the tem-plate For example, it would not make sense to declare a variable to be of type

spe-complex<PTriple>

By the way: The use of<and>delimiters in#include <iostream>is unrelated

to their use in templates

12.2.2 Creating class templates

Now that we have examined how to use class templates we are led to the issue:How do we create class templates? The technique is similar to that of creating pro-cedure templates To demonstrate the process, we create our own, extremely limitedversion of thecomplextemplate that we callmycomplex The template resides in

a file namedmycomplex.h; there is nomycomplex.ccfile Here is the header filecontaining the template

Trang 4

Program 12.2: The template for the mycomplex classes.

30 T re() const { return real_part; }

31 T im() const { return imag_part; }

32

33 };

34

35 template<class T>

36 ostream& operator<<(ostream& os, const mycomplex<T>& z) {

37 os << "(" << z.re() << ") + (" << z.im() << ")i";

Let’s examine this code

• The initial template <class T> serves the same purpose as in the case

of template procedures This establishes Tas a parameter specifying a type.When we declare a variable with a statement like this

Trang 5

mycomplex<double> w;

theTstands for the typedouble See lines 7–8

• The class template has two private data fields: real_partandimag_part.These are declared as typeT Thus ifwis declared typemycomplex<double>

thenw.real_partandw.imag_partare both typedouble See lines 10–12

• Three constructors are given The same name is used for these constructors:

mycomplex<T> (The<T>is optional here; the constructors could be namedsimplymycomplexwith the<T>implicitly added.)

The zero-argument constructor creates the complex number 0 + 0i Note thatthe value 0 is explicitly converted to type T This requires that type T beable to convert a zero into type T If some_typeis a class that does nothave a single-argument numerical constructor, then declaring a variable to be

amycomplex<some_type>causes a compiler error See lines 15–18.The single- and double-argument constructors follow (lines 20–28) They areself-explanatory

• We provide the methodsre()andim()to retrieve amycomplexvariable’sreal and imaginary parts Note that the return type of these methods isT Seelines 30–31

• The last part of the filemycomplex.his theoperator<<procedure for ing mycomplexvariables to the computer’s screen This procedure is not amember of themycomplexclass template, so it needs a separate introductory

writ-template <class T>in front of the procedure’s definition See line 35.The next line looks like the usual declaration of the<<operator The secondargument’s type is a reference to a variable of typemycomplex<T>

After this comes the inline code for the procedure The keywordinlineisoptional because all templates must be defined inline (If we want to includethe keyword inline, it would follow template <class T> and precede

Trang 6

24 T1 re() const { return real_part; }

25 T2 im() const { return imag_part; }

26

27 };

28

29 template<class T1, class T2>

30 ostream& operator<<(ostream& os, const mycomplex<T1,T2>& z) {

31 os << "(" << z.re() << ") + (" << z.im() << ")i";

32 return os;

33 }

If we use this alternativemycomplextemplate, variable declarations require thespecification of two types, such as this:

mycomplex<long, double> mixed_up_z;

Our goal is to create a C++ class template to represent polynomials over any field

Kand we call this class templatePolynomial Consider the following declarations,Polynomial<double> P;

Polynomial< complex<double> > Q;

Polynomial<Mod> R;

These are to create polynomials in R[x], C[x], and Zp[x], respectively (Of course,

we need#include <complex>and#include "Mod.h".)

Trang 7

12.3.1 Data

We need to store the coefficients of the polynomial For this, we use avector

variable (see Section 8.4) namedcoef The coefficient of xkis held incoef[k] Wetherefore require the directive#include <vector>in the filePolynomial.h

We hold the degree of the polynomial in alongvariable nameddg The degree isthe largest index k such thatcoef[k]is nonzero In the case where the polynomial

is equal to zero, we setdgequal to −1

See lines 11–12 in Program 12.4

12.3.2 Constructors

A basic, zero-argument constructor produces the zero polynomial This is plished by a call to aclear() method that resizes coefto hold only one value,sets that value to zero, and setsdgequal to −1 See lines 23–25 and 78–81 of Pro-gram 12.4

accom-A single-argument constructor is used to produce a constant polynomial; that is, apolynomial in which ck= 0 for all k ≥ 1 This constructor may be used explicitly orimplicitly to convert scalar values to polynomials For example, consider this code:Polynomial<double> P(5.);

for storage inQ Similarly,-M_PIis a real number and this needs to be converted to

a complex type for storage inR

To do this, we allow the argument to be of any type and then cast that argument totypeK Let’s look at the full code for this constructor (lines 27–33):

struc-Polynomial< complex<double> > Q;

Q = val;

the variablevalmay be of any type

Trang 8

There is, of course, a catch We assigncoef[0]with the valueK(a) This is anexplicit request to convert the valueato type K This is fine if we are converting

alongto adoubleor adoubleto acomplex<double>, but fails whenais notconvertible to typeK, for example, ifKwere typedoubleandawere typePTriple.Notice the call to the private methoddeg_check() This method scans the dataheld incoefto find the last nonzero value and resetsdgaccordingly Various opera-tions on polynomials might alter their degree (e.g., addition of polynomials, changingcoefficients, etc.) and this method makes suredgholds the correct value

Next we have a three-argument constructor (lines 35–43) To create the mial ax2+ bx + c one simply invokesPolynomial<K>(a,b,c) As before, thethree arguments need not be typeK; it is enough that they be convertible to typeK.For example, consider this code

complex<double> b(4.,-3.);

Polynomial< complex<double> > P(a,b,c);

This creates a polynomialPequal to 7x2+ (4 − 3i)x + π

Finally, it is useful to be able to create a polynomial given an array of coefficients.The constructor on lines 45–60 takes two arguments: the size of an array and anarray of coefficients The array is declared as typeJ*; that is, an array of elements

of typeJ The only requirement onJis that values of that type must be convertible

to typeK

12.3.3 Get and set methods

We include an assortment of methods to inspect and modify the coefficients held

in aPolynomial

• Thedeg()method returns the degree of the polynomial (See line 62.)

• Theget(k)method returns the coefficient of xk In the case where k is invalid(negative or greater than the degree), we return zero (See lines 64–67.)

As an alternative toget(k)we provideoperator[](line 69) For a mialP, bothP[k]andP.get(k)have the same effect However, we have notset upoperator[]to work on the left-hand side of an assignment; we cannotchange the kth coefficient by a statement such asP[k]=c;

polyno-• TheisZero()method returns true if the polynomial is identically zero Seeline 89

• Theset(idx,a)method sets the coefficientcoef[idx]equal to the value

a See lines 71–76

Trang 9

Some care must be taken here First, ifidxis negative, no action is taken If

idxis greater than the degree, we need to expandcoefaccordingly Also, thismethod might set the highest coefficient to zero, so we invokedeg_check()

• Theclear()method sets all coefficients to zero See lines 78–82

• Theminimize()method frees up any wasted memory held in coef It isconceivable that a polynomial may at one point have large degree (causing

coefto expand) and then later have small degree Although the size ofcoef

grows and shrinks with the degree, the capacity ofcoefwould remain large.This method causes thevectormethodreserveto be invoked forcoef Seelines 84–87

• Finally, we have theshift(n)method See lines 91–105

If n is positive, this has the effect of multiplying the polynomial by xn Eachcoefficient is shifted upwards; the coefficient of xk before the shift becomesthe coefficient of xk+nafter

Shifting with a negative index has the opposite effect Coefficients are moved

to lower powers of x Coefficients shifted to negative positions are discarded

The polynomialP 4x2+ 6x − 2AfterP.shift(2) 4x4+ 6x3− 2x2AfterP.shift(-1) 4x + 6

Notice that we give the argumentna default value of 1 (see line 91) Thus

P.shift()is the same asP.shift(1)

12.3.4 Function methods

Polynomials are functions and to use them as such we provide a method named

of Invoking P.of(a) evaluates the polynomial p(x) at x = a See lines 109–118

An efficient way to evaluate a polynomial such as 3x4+ 5x3− 6x2+ 2x + 7 at x = a

is this:

(3 × a) + 5 × a + (−6)×a + 2

Because polynomials are functions, they may be composed and the result is again

a polynomial We use the same method names,ofandoperator(), for polynomialcomposition For polynomialsPandQ, the result ofP.of(Q)(and alsoP(Q)) is thepolynomial p(q(x)) See lines 122–135

These methods depend on the ability to do polynomial arithmetic, and we describethose methods below (Subsection 12.3.6)

Trang 10

12.3.5 Equality

To check if two polynomials are equal, we make sure they have the same degreeand that corresponding coefficients are equal The operators==and!=are given onlines 139–149

12.3.6 Arithmetic

We provide methods for the usual arithmetic operators: addition, subtraction, tiplication, and division (quotient and remainder) See lines 153ff

mul-Each of the basic operators is defined like this:

Polynomial<K> operator+(const Polynomial<K>& that) const { }

IfPandQare of typePolynomial<double>, then the expressionP+Qinvokes thismethod withthatreferring toQ However, the expressionP+5also engages thismethod; implicitly the5 is cast to a polynomial via Polynomial<double>(5).However, the expression5+Pcannot be handled by this method (because5is not apolynomial) Therefore, we also provide procedure templates such as this:

template <class J, class K>

Polynomial<K> operator+(J x, const Polynomial<K>& P) {

With the exception of division, the code for these various operators is reasonablystraightforward Division requires a bit more attention

As in the case of integers, division of polynomials produces two results: the tient and the remainder Let a(x) and b(x) be polynomials with b 6= 0 Then thereexist polynomials q(x) and r(x) for which

quo-a(x) = q(x)b(x) + r(x) and deg r(x) < deg b(x)

Furthermore, q and r are unique For example, if a(x) = 3x2+x−2 and b(x) = 2x+1,then q(x) =32x−1

4and r(x) = −74

We defineA/BandA%Bto be the quotient and remainder, respectively, when wedivide a(x) by b(x)

To this end, we define the procedurequot_rem(A,B,Q,R)(see lines 300–321)

to find the quotient and remainder Theoperator/andoperator%make use of

quot_remto do their work

Please note that the division methods require that K be a field If K is only acommutative ring (e.g.,longintegers), then most of the class template works fine,but the division methods do not

Trang 11

12.3.7 Output to the screen

The operator<<for writing to the computer’s screen appears on lines 269–289.This operator writes the polynomial 5x3− x +1

2 like this:

(5)Xˆ3 + (-1)X + (0.5)

The procedure is smart enough to omit terms whose coefficient is zero, to omit thesuperscript 1 on the linear term, and to omit the variable altogether on the constantterm However, it does not convert(-1)Xinto the more legible- X, or even- (1)X

We might think that it is possible for the code to check if a coefficient is negative andmodify behavior accordingly However, for some fields K (such as C and Zp) thisdoes not make sense

12.3.8 GCD

Let a(x) and b(x) be polynomials A common divisor of a(x) and b(x) is a nomial c(x) with the property that there exist polynomials s(x) and t(x) so thata(x) = c(x)s(x) and b(x) = c(x)t(x) A greatest common divisor of a(x) and b(x)

poly-is a common divpoly-isor of highest possible degree

Two polynomials may have several different greatest common divisors becauseany nonzero scalar multiple of a greatest common divisor is again a greatest commondivisor

To settle on a specific meaning for gcd[a(x), b(x)] we choose the greatest commondivisor d(x) whose leading coefficient is 1 (A polynomial whose leading coefficient

is 1 is called monic.) Any two nonzero polynomials have a unique monic greatestcommon divisor

Thegcdprocedure for two polynomials is given on lines 323–336 This dure uses the helper methodsis_monic()andmake_monic(); the former checks

proce-if the polynomial is monic and the latter transforms the polynomial into a monicpolynomial by dividing by the leading coefficient See lines 256–265

We use the Euclidean algorithm (described in Section 3.3) to calculate the gcd oftwo polynomials

In addition to the usual gcd procedure, we provide an extended version Givenpolynomials a(x) and b(x), the extended gcd procedure finds d(x) = gcd[a(x), b(x)]

as well as polynomials s(x) and t(x) so that d(x) = a(x)s(x) + b(x)t(x) See lines337–376

Trang 13

95 for (long k=0; k<=dg+n; k++) coef[k] = coef[k-n];

96 for (long k=dg+n+1; k<=dg; k++) coef[k] = K(0);

102 for (long k=dg; k>=0; k ) coef[k+n] = coef[k];

103 for (long k=0; k<n; k++) coef[k] = K(0);

Trang 14

139 bool operator==(const Polynomial<K>& that) const {

140 if (dg != that.dg) return false;

147 bool operator!=(const Polynomial<K>& that) const {

148 return !(*this == that);

157 for (long k=0; k<=dmax; k++) {

158 ans.coef[k] = get(k) + that.get(k);

164 Polynomial<K> operator+=(const Polynomial<K>& that) {

165 (*this) = (*this) + that;

Trang 15

181 for (long k=0; k<=dmax; k++) {

182 ans.coef[k] = get(k) - that.get(k);

188 Polynomial<K> operator-=(const Polynomial<K>& that) {

189 (*this) = (*this) - that;

195 if (isZero() || that.isZero()) return ans;

196 long dans = dg + that.dg;

209 Polynomial<K> operator*=(const Polynomial<K>& that) {

210 *this = (*this) * that;

Trang 16

251 Polynomial<K> operator%=(const Polynomial<K>& that) {

252 (*this) = (*this) % that;

Trang 17

291 template <class J, class K>

292 Polynomial<K> operator+(J x, const Polynomial<K>& P)

293 { return P + K(x); }

294

295 template <class J, class K>

296 Polynomial<K> operator-(J x, const Polynomial<K>& P)

297 { return (-P) + K(x); }

298

299 template <class J, class K>

300 Polynomial<K> operator*(J x, const Polynomial<K>& P)

Trang 18

347 // If A and B are both 0, set S=T=0 and return 0.

348 if (A.isZero() && B.isZero()) {

In Chapter 3 we considered the question (phrased imprecisely here): What is theprobability that two positive integers are relatively prime? We found that the answer

is 1/ζ (2) Here we consider a similar problem: What is the probability that two

Trang 19

randomly chosen polynomials are relatively prime?

To be more precise, let Bd denote the set of all polynomials in Z2[x] of degreeless than d; there are 2d such polynomials ad−1xd−1+ ad−2xd−2+ · · · + a1x+ a0where the ajs are 0 or 1 Let pddenote the probability the two polynomials, chosenuniformly and independently from Bdare relatively prime What can we say about

pdas d → ∞?

To formulate a conjecture, we write a program to evaluate pdby direct tion This is the approach we used in Section 3.5 With luck, modest values of d willlead us to the answer The overall structure of the program is this:

enumera-1 Ask the user to input d

2 Build an array containing all the polynomials in Bd

3 For all i < j, count the number of times the ith and jth polynomials are tively prime

rela-4 From this count, we learn the numerator of pd Divide by 22d to find theanswer

Of these, the most difficult part is the construction of the list in step 2 To generatethis table efficiently, we observe that there is a natural one-to-one correspondencebetween d-digit binary numbers and polynomials in Bd, illustrated here with d = 6

bd−1bd−2 b1b0 7→ bd−1xd−1+ bd−2xd−2+ · · · + b1x+ b0∈ Bd

We call this procedurelong2poly Here is its header file

Program 12.5: Header file long2poly.h

1 #ifndef LONG_TO_POLY_H

2 #define LONG_TO_POLY_H

3

Trang 20

This header defines a constantmax_bitsthat sets an upper bound on d; this value

is based on the size of alonginteger on the computer on which this program is to

be run

The procedure takes alonginteger argument and returns aPolynomial<Mod>

To write this program, we want to access the individual bits of the integer argument,

m The way we do this is to check ifmis even or odd, and then set b0accordingly Wethen dividemby 2, check if the result is even or odd, and then set d1 We continue inthis fashion untilmis zero Here is the code

Program 12.6: Code file for the long2poly procedure

Next, we need a main to implement the exhaustive algorithm

Program 12.7: Main program for the GCD revisited problem

Trang 21

23 cerr << "Generating polynomials ";

24 for (long k=0; k<bound; k++) {

25 list[k] = long2poly(k);

26 }

27 cerr << "done! " << endl << bound

28 << " polynomials of degree less than "

34 for (long i=0; i<bound-1; i++) {

35 for (long j=i+1; j<bound; j++) {

36 if( gcd(list[i],list[j]) == one ) count++;

42 cout << count << " out of " << bound*bound

43 << " pairs are relatively prime" << endl;

Enter degree bound > 10

Generating polynomials done!

1024 polynomials of degree less than 10 generated

524289 out of 1048576 pairs are relatively prime

Trang 22

12.5 Working in binary

Thelong2polyprocedure used a trick to convert alonginteger m into mials p(x) in Z2[x] We set the constant coefficient of p(x) based on the parity of m,and then we divided m by 2 (keeping only the integer part) We then repeated thistechnique to set higher and higher coefficients until m vanished In short, we useddivision arithmetic to read off the base-2 digits of m

polyno-In other words, we used a mathematical trick to find the binary representation of

m However, the binary is already present inside the computer; it is more efficient towork directly with that C++ provides a family of operators for working directly onthe bits in the binary form of integers

12.5.1 Signed versus unsigned integers

Integers are stored inside the computer in binary The number 20 is representedinternally as0000000000010100

In this, and subsequent examples, we assume the integers are held asshorttypes;

on my computer these are two bytes (16 bits) long Other integer types may have 32

rep-to the type name For example:

unsigned short x;

To illustrate the difference, suppose we have two variablesxandydeclared thus:unsigned short x;

short y;

Suppose both of these hold the bits1111111111111111 In this case, the value of

xis 65,535 (216− 1) whereas the value ofyis −1

Trang 23

12.5.2 Bit operations

C++ provides six operators for working with the binary representation of integers.Bitwise and For integer variablesxandy, the expressionx&yis the bitwise and of

xandy That is, the kth bit ofx&yis 1 if and only if the kth bits of bothxand

yare 1 Here is an example

x 0100001101100000

y 0001000111101101x&y 0000000101100000

The bitwise and operation & should not be confused with the Boolean andoperation&& You should use&&only withboolvalues

Bitwise or Similar to bitwise and, the operationx|ygives the bitwise or ofxandy.That is, the kth bit ofx|yis 0 if and only if the kth bits of bothxandyare 0.Here is an example

x 0100001101100000

y 0001000111101101x|y 0101001111101101

The bitwise or operation|should not be confused with the Boolean or tion|| You should use||only withboolvalues

opera-Exclusive or The expressionxˆygives the bitwise exclusive or ofxandy That is,the kth bit ofx|yis 0 if and only if exactly one of the kth bits of bothxandy

is 1 Here is an example

x 0100001101100000

y 0001000111101101xˆy 0101001010001101

Bitwise not The expression˜xinterchanges 1s and 0s inx That is, the kth bit of

˜xis 1 if and only if the kth bit ofxis 0 Here is an example

x 0100001101100000

˜x 1011110010011111

The bitwise not operation˜should not be confused with the Boolean not eration! You should use!only withboolvalues

op-Left shift The expressionx<<n(where n is a nonnegative integer) shifts the bits of

xto the left n steps The right-hand side of the result is filled with 0s Any bits

in the highest n positions are lost Here is an example

x 0100001101100000

Trang 24

The symbol <<is the same one we use for writing to the console, as in thestatementcout << x << endl; C++ is able to distinguish between thesecases by inspecting the types of objects on either side of the<<symbol.The expressionx<<nis equivalent to multiplying x by 2n(unless bits are lost

at the left)

Right shift The expressionx>>n(where n is a nonnegative integer) shifts the bits

of x to the right n places Bits in the lower n places are lost The vacatedpositions on the left are filled in with 0s or with 1s depending on the situation:

• Ifxis anunsignedinteger type, 0s are inserted at the left

• Ifxis a signed integer type andxis nonnegative, 0s are inserted at theleft

• Ifxis a negative integer, then 1s are inserted at the left Here are someexamples

All six of these operators can be combined with the assignment operator,= Theexpressionx &= yis equivalent tox = (x&y), and so on

Bit operations can be combined to perform operations that would be difficult withstandard mathematical operators For example, suppose we want to set the kth bit of

xto 1; the following code does the trick:x |= (1<<k); If we want to set that bit

to zero, we do this:x &= ˜(1<<k);

12.5.3 Thebitsetclass template

Using integer types to represent a list of binary values is efficient, but presents twodrawbacks First, this technique is limited to the size of an integer on your computer;

if you want a list of, say, 200 bits, there is no integer type with that capacity Second,using bit manipulation can result in obfuscated code Human beings find statementssuch asx&=˜(1<<k);difficult to understand (The statement sets the kth bit ofxtozero.) If your problem requires high speed for short lists of bits, then bit manipulation

of integer types may be your best option However, there are two other choices ofwhich you should be aware

The first option, also discussed in Section 8.4, is to use vector<bool>ables; these are adjustable arrays of true/false values To set the kth bit of such an

Trang 25

vari-array equal to zero (false), we use the considerably clearer statement x[k]=0;

or x[k]=false; Variables of typevector<bool>use memory efficiently, can

be easily resized, and provide convenient access to their elements However, thebitwise operations (such as&, ˜, >>, etc.) cannot be used with variables of type

vector<bool> If one wished to interchange all the 0s and 1s held inx, the mentx=˜x;does not work Instead, one would need to write aforloop to changethe bits one by one:

state-for (int k=0; k<x.size(); k++) {

x[k] = !x[k];

}

The second option is to use abitset Abitsetobject is a fixed size tory of bits To use variables of typebitset, start with#include <bitset>anddeclare variables like this:

reposi-bitset<100> x;

This sets upxas a list of 100 bits Notice thatbitsetis a template but its argument

is a number, not a type; we explain how to do this later in this section The importantpoint is that this number is a constant, not a variable The following code is illegal.int n;

cout << "Enter number of bits > ";

cin >> n;

bitset<n> x; // illegal constructor, n is not a constant

The size of thebitsetmust be declared when you write your program, not whilethe program is running

Here is a list of the various methods and operators available forbitsets

• Constructors The standard constructor has the form

bitset<number> var;

wherenumberis a specific positive integer This may be aconst intdefinedearlier in the code, or an explicitly typed value, such as 100 The variablevar

holdsnumberbits, and at this point these are all 0s

One may construct from anunsigned longinteger value For example,bitset<20> x(39);

setsxto00000000000000100111(the binary representation of 39).One may also construct from a C++stringobject (these are discussed later

in Section 14.2) The constructor

Trang 26

bitset<20> y(x);

makesya copy ofx Note thatxmust also be abitset<20>and may not be

abitsetof any other size

• Inspection methods These are methods one can use to learn informationabout the bits held in abitset Supposexis abitset<100>:

– x.size()returns the number of bits thatxholds (in this example, 100).– x.any()returnstrueif at least one bit inxis a 1

– x.none()returnstrueif all of the bits are 0

– x.count()returns the number of 1s inx

– x.test(k)returnstrueif the kth bit ofxis a 1 Of course,kmust be

at least 0 and less thanx.size()

• Bit manipulation methods The following methods may be used to alter thevalue held in the bits of abitset Supposexis abitset<100>:

– x.set()sets all ofx’s bits to 1

– x.set(k)sets the kth bit to 1

– x.set(k,b)sets the kth bit base on the value held in the integer variable

b Ifbis zero, the kth bit ofxis set to 0; otherwise it is set to 1

– x.reset()sets all ofx’s bits to 0

– x.reset(k)sets bit k to 0

– x.flip()swaps 0 and 1 values in every position ofx For example,supposexholds 1110001110; after the statementx.flip();, it nowholds0001110001

– x.flip(k)flips the kth bit ofx

• Comparison operators Ifxandyare bothbitsets of the same size, then

we may compare them with the usual expressionsx==yandx!=y

• Bit operators The standard bitwise operators (&,|,ˆ,˜,<<,>>) and theirassignment variants (&=, |=, ˆ=, ˜=, <<=, >>=) may be used on a pair of

bitsets of the same size

• Array style access In addition to the methods described above, individualelements of abitsetmay be accessed using square brackets The expression

x[k]is the kth element ofx The expressionx[k]may appear on the right orthe left of an assignment statement such asx[4]=˜x[10];

In addition, the expressionx[5].flip()is equivalent tox.flip(5); both

of these toggle the fifth bit ofx

Ngày đăng: 12/08/2014, 12:20

TỪ KHÓA LIÊN QUAN