2.3 Device Operation
2.3.2 Power Compensation
In all our day-to-day dealings and transactions numbers are represented and pro-cessed in decimal form. In computers and computer-based schemes and applica-tions numbers are represented in binary form and processed. Methods and funcapplica-tions available in Python do all representation and related algebra with numbers in binary form. For a convenient and compact representation numbers are more often rep-resented in octal or hexadecimal (hex) form. But for displays, printout, and similar human related interface decimal numbers are used. Python has the flexibility to represent numbers in different ways and convert them from one form to another.
These are explained and illustrated here.
sa1 = '''The Wise Dog
One day there passed by a company of cats a wise dog.
And as he came near and saw that they were very intent and heededhim not, he stopped.
Then there arose in the midst of the company a large, grave cat and looked upon them and said, "Brethren, pray ye; and when ye have prayed again and yet again, nothing doubting, verily then it shall rain mice.’’’
And when the dog heard this he laughed in his heart and turned from them saying, "O blind and foolish cats, has it not been written and have I not known and my fathers before me, that that which raineth for prayer and faith and
supplication is not mice but bones." ''' Fig. 7.2 The string SA1 used in Example7.3
144 7 Operations for Text Processing
7.4.1 Integers
Integers can be represented in decimal form directly. Binary, octal, and hex repre-sentations can be done in simple and well accepted formats. Illustrative details are in the Python Interpreter sequence in Fig.7.3.n1 [1] is the hex number 43h.‘0x’ or
‘0X’ signifies the following integer sequence to be a hex number; the integers can be from the set—{0, 1, 2, … 8, 9, a(A), b(B), c(C), d(D), e(E), f(F)}. Small or capital letters can be used for a, b, c, d, e, and f. 0× 43 = 4 * 161+ 3 * 160= 67 (in decimal form) as can be seen from [2]. Octal numbers are represented as‘0o’ or
‘0O’ followed by the number—a sequence of digits from the set—{0, 1, 2, … 6, 7}.
>>> n1 = 0x43 [1]
>>> n3 = 0b1000011 [5]
>>> n3 [6]
67
>>> n4 = int() [7]
>>> n4 [8]
0
>>> m1 = int(501) [9]
>>> m1
>>> for jj in range(2,36):
l2.append (int('01110',jj)) ...
>>> l2[:16]
[14, 39, 84, 155, 258, 399, 584, 819, 1110, 1463, 1884, 2379, 2954, 3615, 4368, 5219]
>>> l2[16:26]
[6174, 7239, 8420, 9723, 11154, 12719, 14424, 16275, 18278, 20439]
>>> l2[26:]
[22764, 25259, 27930, 30783, 33824, 37059, 40494, 44135]
>>> a1, a2, a3, a4 = 34, 0o34,
0x34, 0b1110111 [22]
>>> bin(a1), bin(a2), bin(a3),
bin(a4) [23]
('0b100010', '0b11100', '0b110100', '0b1110111')
>>> hex(a1), hex(a2), hex(a3),
hex(a4) [24]
('0x22', '0x1c', '0x34', '0x77')
>>> oct(a1), oct(a2), oct(a3),
oct(a4) [25]
Fig. 7.3 Python Interpreter sequence illustrating number representations and conversions
The octal number 0O103 in [3] is again the decimal number 67 itself [4].‘0b’ or
‘0B’ followed by a binary sequence is a binary number. 0b1000011 in binary form [5] is again the decimal number 67 [6].
The function int(x) in its simplest form accepts x as a number and returns its integral part as an integer. int() in [7] returns a zero [8]. int(501) in [9] returns 501 itself. int(67.8901) in [10] returns 67. The fractional part of the number is ignored and the integral part returned as an integer. However if rounding-off is to be done round() function can be used (discussed in the following section).
int(y, rr) is the general form of the int() function. Details of its use are as follows:
• If rr is omitted and y is a number, the integral part of y is returned as in the foregoing cases. Here the number is implicitly taken to be a decimal number.
• If rr is present it signifies the radix (base) of the number. It can take any value from 2 to 36. Furthery has to be a string representing the number to the base rr.
The characters in the string are from the set—{0, 1, 2, … 8, 9, a, b, c, … y, z}
where a, b, c,… y, z represent the integer values 10–35 in the same order. The letters can be capital or small versions. In addition the binary, octal, and hex strings are also acceptable.
• Negative integers have the negative sign at the left end of the string.
Lines [11]–[19] illustrate a few possible uses of int() function. In [11] 592 signifies an integer to base 36. Its decimal value is 6806 as seen from [12]. Similarly
‘z’, ‘zxy’, and ‘XYZ’ all to base 36—are shown in the succeeding lines along with their decimal equivalent values. int(‘abc’, 30) in [17] represents ‘abc’ as an integer to base 30. Its equivalent decimal value is 9342. int(0xfe2, 16) in [19]
takes0xfe2 as a hex integer having decimal value 4066 [20].
Example 7.4 The string—‘01110’—is given. Treat it as an integer to bases 2–36 and obtain respective decimal values.
l2 is formed as a null set in [21]. All the required integers are successively appended to it in the following lines. In subsequent lines l2 is displayed in three convenient segments.
The function bin(x) returns the binary equivalent of x as a string. Here x can be an integer in decimal form, octal form, hex form or binary form itself as illustrated in [22].
hex(x) returns the hex value of integer x as a string. Similarly oct(x) returns the octal value ofx as a string. In all these cases x has to be an integer but its representation can be in decimal, octal, binary, or hex form. These are illustrated in [23]–[26].
7.4.2 Floating Point Numbers
The functionfloat(ff) accepts a floating point number (or an integer) ff as a string and returns its equivalent as a decimal value. The Python Interpreter sequences in
146 7 Operations for Text Processing
Fig.7.4a, b illustrate the use of different operations related tofloating point numbers.
The number 345.67 (and−345.67) is represented as strings in different forms in [1]
in Fig.7.4a.float() returns the decimal value. The same set of numbers is assigned tog1, g2, g3, and g4 in [2] and the float values obtained in [3]. With h = (g1, g2, g3, g4) as a tuple the conversion is carried out using the map() function in [5] and the result shown in [6]. Afloating point number can be expressed in the rational form as a ratio of two integers using the method .as_inger_ratio(). [7] illustrates this for 345.67; the (numerator, denominator) pair is returned as a tuple in [8]. [9]
confirms this by evaluating the ratio (numerator/denominator) directly; [10] does the conversion to ratio form for the negative number−345.67.
x.is_integer() tests whether x is an integer; if ‘yes’, ‘True’ is returned; else
‘False’ is returned; the illustrations are in [12], [13], and [14].
>>> f1, f2, f3, f4 = float('345.67'),
float('0.34567e3'),float('3456.7E-1'),float('-3456700e-4') [1]
>>> f1, f2, f3, f4
(345.67, 345.67, 345.67, -345.67)
>>> g1, g2, g3, g4 = 345.67, 0.34567e3, 3456.7E1,
-3456700e-4 [2]
>>> float(g1), float(g2), float(g3), float(g4) [3]
(345.67, 345.67, 345.67, -345.67)
>>> h = (g1, g2, g3, g4) [4]
>>> list(map(float, h)) [5]
[345.67, 345.67, 345.67, -345.67] [6]
>>> j1 = h1.as_integer_ratio() [7]
(6081090949973279, 17592186044416) [8]
>>> j1[0]/j1[1] [9]
345.67
>>> g4.as_integer_ratio() [10]
(-6081090949973279, 17592186044416) [11]
>>> (2.00).is_integer() [12]
True
>>> (0.20e10).is_integer() [13]
True
>>> (2.00e-1).is_integer() [14]
False
>>> nn = 67.8901 [15]
>>> float.hex(nn) [16]
'0x1.0f8f765fd8adbp+6' [17]
>>> (j1[0]/j1[1]).hex() [18]
'0x1.59ab851eb851fp+8'
(a)
Fig. 7.4 a Python Interpreter sequence illustrating floating point number representations and conversions (continued in Fig.7.4b), b Python Interpreter sequence illustrating floating point number representations and conversions (continued from Fig.7.4a)
In algebra involvingfloating point numbers normally the numbers are present in decimal form—represented in ‘int.fraction’ form or in the (mantissa, expo-nent) form.
In Python it is also possible to represent and display afloating point hex number in (mantissa, exponent) form. Here the exponent is represented as‘pa’ signifying 2a with ‘a’ being the (positive/negative) exponent. With this convention a floating point decimal number fn can be represented in hex form using float.formhex (fn). The floating point decimal number 67.8901 is assigned to nn in [15]. It is represented in hex form as explained above usingfloat.hex(nn) in [16] and [17].
The decimal number 345.67—expressed as an integer ratio in [9] (j1[0]/j1[1])—is expressed as afloating point number in hex form in [18]. It is verified through direct
(b)
>>> hh1 = (345.67).hex() [19]
>>> hh1 [20]
'0x1.59ab851eb851fp+8'
>>> hh2 = float.fromhex(hh1) [21]
>>> hh2 [22]
345.67
>>> k1 = '0x2.0fp+3' [23]
>>> float.fromhex(k1) [24]
16.46875 [25]
>>> k3 = '0x2.0p+1' [26]
>>> k4 = float.fromhex(k3) [27]
>>> k4 [28]
>>> b1 = 1.04555500000 [32]
>>> l2 = [] [33]
>>> for jj in range(1,9):l2.append(round(b1,jj)) ...
>>> l2
[1.0, 1.05, 1.046, 1.0456, 1.04556, 1.045555, 1.045555,
1.045555] [34]
>>> a1 = 1.04555000000 [35]
>>> l1 = [] [36]
>>> for jj in range(1,9):l1.append(round(a1,jj)) [37]
...
>>> l1
[1.0, 1.05, 1.046, 1.0455, 1.04555, 1.04555, 1.04555,
1.04555] [38]
>>>
Fig. 7.4 (continued)
148 7 Operations for Text Processing
conversion in [19], [20] and again through reversal to decimal form in [21] and [22]
(in Fig.7.4b).k1 in [23] is a hex number in floating point form (with binary value of 10000.01111); it is converted to decimal form throughfloat.fromhex(k1) in [24] as 16.46875. Two additional examples of conversion from hex to decimal form follow from [26] to [29].
For afloating point number x, round(x) rounds x to the desired accuracy. With a single argument, x round(x) rounds x to an integer as in [30]. round (x, d) rounds x to a number to d significant digits beyond the decimal point as in [31]. The rounding off is carried out based on the actual representation of the number in memory.
Example 7.5 The numbersb1 = 1.0455550 and a1 = 1.045550 are represented as
‘1.04555500000000001215028078149771317839622497558593750’ and
‘1.04554999999999997939426066295709460973739624023437500’ respectively in the computer. Round them off to different accuracies and explain any anomaly.
listl2 is initialized as an empty list in [33]. b1 (=1.0455550) is rounded off to different significant digits and appended to l2 as in [34]. In all cases the rounding is done to the nearest level as is to be expected.
A similar rounding off is done with a1 = 1.045550 [35] and l1 is the list of rounded numbers. [37] shows the respective values. The rounding sequence is as follows:
• 1.045549 is rounded to 1.04555.
• 1.04554 is rounded to 1.0455 and not 1.0456.
• 1.0455 is rounded to 1.046.
• 1.045 is rounded to 1.05.
• 1.04 is rounded to 1.0 and not 1.1.