
Data TypesThis is the first of several lessons on the data types used by Python. Computer programs can process instructions that work with many different kinds of data, and the instructions need to be very precise. If you add a word to this sentence, 'add' means something very different from when you add 2 and 3. A computer language has to have a set of rules defining what operations can be applied to different kinds of data, and for this to work, there also has to be a set of rules defining exactly what data can be used with each operation. For example, if you want to calculate grossProfit = salesIncome  costs, a program has to know that these quantities are variables containing numbers rather than just strings of letters. They must have a numerical data type rather than string data type. If you are not clear about the meaning in computer science of variables and of data types, it may help to brush up on the lesson Introduction_to_Programming/Variables. Two useful Builtin Functionsclass type(object)With one argument, return the type of an object. >>> type(6)
<class 'int'>
>>>
>>> type(6.4)
<class 'float'>
>>>
>>> type('6.4')
<class 'str'>
>>>
>>> type(b'6.4')
<class 'bytes'>
>>>
>>> type(['6.4'])
<class 'list'>
>>>
isinstance(object, classinfo)Return true if the object argument is an instance of the classinfo argument. classinfo can be a tuple. isinstance arg 2 must be a type or tuple of types. >>> isinstance(6,int)
True
>>>
>>> isinstance(6,str)
False
>>>
>>> isinstance('6',str)
True
>>>
>>> isinstance('6',(int,float,bytes))
False
>>>
>>> isinstance('6',(int,float,bytes,str))
True
>>>
>>> isinstance({},dict)
True
>>>
>>> isinstance({3,4,5},set)
True
>>>
>>> isinstance(b'',str)
False
>>>
>>> isinstance(b'',bytes)
True
>>>

Introduction to integersPython has several data types to represent numbers. This lesson introduces two: integers, and floating point numbers, or 'floats'. We'll discuss floats later in the lesson. An integer, commonly abbreviated to int, is a whole number (positive, negative, or zero). So >>> isinstance(7, int)
True
>>> isinstance(0, int)
True
>>> isinstance(11, int)
True
>>> isinstance(2, int)
True
>>> isinstance(5, int)
True
>>> isinstance(3.14159, int)
False
>>> isinstance(0.0001, int)
False
>>> isinstance(11.11111, int)
False
>>> isinstance(2.0, int)
False
>>> 2+2
4
>>> 42
2
>>> 6+1
7
>>> 6+73
10
>>> 2*2
4
>>> 2*2*2
8
>>> 2
2
>>> 8/2
4.0
>>> 4*4/2
8.0
>>> 44*2
4
>>> 24
2
>>> 10+10/2
15.0
You can do more mathematical operations than the previously demonstrated ones. We can perform a floor division by using two forward slashes ( >>> 4 // 2
2
>>> 1 // 8
0
>>> 5 // 5
1
>>> 100 // 5
20
>>> 4 // 3
1
>>> 5 % 4
1
>>> 1 % 4
1
>>> 4 % 4
0
>>> 2 % 4
2
>>> 2 % 1
0
>>> 20 % 2
0
>>> 20 % 3
2
>>> 20 % 3
1
The >>> divmod(7,3)
(2, 1)
>>> (q,r) = divmod(7,3)
>>> q; r
2
1
You can also find the power of a number by using two asterisk symbols ( >>> 4 ** 2
16
>>> 4 ** 4
256
>>> 1 ** 11278923689
1
>>> 2 ** 4
16
>>> 10 ** 2
100
>>> 1024 ** 2
1048576
>>> 10 ** 6
1000000
>>> 25 ** (1/2)
0.2
>>> 4 *  3 ** 2
36
>>> 4 * ( 3) ** 2
36
>>> 8 / 4 ** 2
0.5
The operator of exponentiation If unsure of precedence, you can always use parentheses to force the desired result: >>> (4 * ( 3)) ** 2 ; 4 * (( 3) ** 2)
144
36
>>>
There is no limit for the length of integer literals apart from what can be stored in available memory. Nondecimal IntegersAlmost everyone is familiar with ten based numbers. While base 10 is useful for everyday tasks, it isn't ideal for use in the computer world. Three other numeral systems are commonly used in computer science; binary, octal, and hexadecimal. We'll lightly cover Python's use of these in this section. The binary system is essential as all information is represented in binary form in computer hardware. Octal and hexadecimal are convenient for condensing binary numbers to a form that is more easily read by humans, while (unlike decimal) being simple to translate to or from binary. If you have difficulty with this part of the lesson, it may help to brush up on the lesson Numeral_systems in the course Introduction_to_Computers. Most people have heard of binary and it is often associated with computers. Actually, modern binary made its way into the world far before electricity was widely in use. The binary system is 2 based, which means that only two numbers are used. Of course, these numbers are 0 and 1. So unlike the decimal's To use binary numbers in python, prepend >>> 0B11
3
>>> 0B1 + 0B1
2
>>> 0B11 + 0B1
4
>>> 0B10001 + 0B1
18
>>> 0B10001  0B1
16
>>> bin(2345)
'0b100100101001'
>>> 0b_111_0101_0011
1875
The value returned by
>>> 0o3
3
>>> 0o12
10
>>> 0o12 + 0o10
18
>>> 0o12  0o03
7
>>> 0o100
64
>>> 0o777
511
>>> 0o777  0o111
438
>>> oct(1_234_987)
'0o4554053'
>>> 0o_1234_9876
File "<stdin>", line 1
0o_1234_9876
^
SyntaxError: invalid token
>>> 0o_1234_0765
2736629
>>> 0xF
15
>>> 0xF0
240
>>> 0xFF  0xF
240
>>> 0xF + 0xA
25
>>> 0x2 + 0x2
4
>>> 0x12  0xA
8
>>> 0xFF / 0xF
17.0
>>> 0xF * 0xF
225
>>> hex(1_234_987)
'0x12d82b'
>>> 0x_12_D82B
1234987
Bitwise OperatorsAll integers may be tested or modified by the Bitwise Operators: These operators are called 'bitwise' because they operate on individual bits within the integer.
>>> bin (0b1010101 & 0b1111)
'0b101'
>>> bin (0b1010101 & 0b111000)
'0b10000'
>>> hex (0xFF00FF & 0xFF00)
'0x0'
In the first example both input operands 0b1010101
0b 1111
^ ^
'0b101'.
>>> bin (0b1010101  0b1110)
'0b1011111'
>>> bin (0b1010101  0b1100)
'0b1011101'
>>> hex (0xFF00FF  0x3F0)
'0xff03ff'
In the first example both input operands 0b1010101
0b 1110
^ ^^^^^
'0b1011111'.
>> bin (0b1010101 ^ 0b1110)
'0b1011011'
>>> bin (0b1010101 ^ 0b1100)
'0b1011001'
>>> hex (0xFF00FF ^ 0x3F0)
'0xff030f'
In the first example both input operands 0b1010101
0b 1110
^ ^^ ^^
'0b1011011'.
>> bin(0b10101 << 2)
'0b1010100'
>>> bin(0b10101 << 5)
'0b1010100000'
>>> hex(0xFF00FF << 8)
'0xff00ff00'
>>> (0xFF00FF << 8) == (0xFF00FF * 2**8)
True
In the first example the output is the input shifted left 2 bits: 0b 10101
0b1010100
^^
>> bin(0b10101 >> 2)
'0b101'
>>> bin(0b10101 >> 5)
'0b0'
>>> hex(0xFF00FF >> 8)
'0xff00'
>>> (0xFF00FF >> 8) == (0xFF00FF // 2**8)
True
In the first example the output is the input shifted right 2 bits: 0b10101
0b 101
twoBits = operand & 0x3
The bitwise operators above perform as expected on all integers of (almost) unlimited length: >>> hex( ( 0x1234_FEDC << 120 )  ( 0x_CDE_90AB << 60 ) )
'0x1234fedc00000000cde90ab000000000000000'
>>> hex( ( 0x1234_FEDC << 200 ) ^ ( 0x_CDE_90AB << 207 ) )
'0x67d7cab5c00000000000000000000000000000000000000000000000000'
6. The behavior of the invert (~) operator shows that negative numbers are treated as their 2's complement value: >>> a = 0b1100101100101 ; bin(~a)
'0b1100101100110'
For a true 1's complement bitwise invert here is one way to do it: >>> a = 0b1100101100101 ; b = a ^ ( (1 << a.bit_length)  1 ); bin(b)
'0b11010011010'
>>> c = a + b; bin(c)
'0b1111111111111' # to test the operation, all bits of c should be set.
>>> (c+1) == ( 1 << (c.bit_length) )
True # they are.
And another way to do it: from decimal import *
a = 0b11100100011001110001010111 # a is int
b = bin(a) # b is string
print ('a =', b)
formerPrecision = getcontext.prec
getcontext.prec = a.bit_length
d = Decimal.logical_invert( Decimal( b[2:] ) ) # d is Decimal object.
getcontext.prec = formerPrecision
print ('d =', d)
e = int(str(d),2) # e is int
print ('e =', bin(e))
( (a + e) == ( ( 1 << a.bit_length )  1 ) ) and print ('successful inversion')
When you execute the above code, you see the following results: a = 0b11100100011001110001010111
d = 11011100110001110101000
e = 0b11011100110001110101000
successful inversion
The Decimal.logical_invert performs a 1's complement inversion. 
Introduction to floatsAlthough integers are great for many situations, they have a serious limitation, integers are whole numbers. This means that they are not real numbers. A real number is a value that represents a quantity along a continuous line^{[5]}, which means that it can have fractions in decimal forms. >>> isinstance(4.5, float)
True
>>> isinstance(1.25, float)
True
>>> isinstance(0.75, float)
True
>>> isinstance(3.14159, float)
True
>>> isinstance(2.71828, float)
True
>>> isinstance(1.0, float)
True
>>> isinstance(271828, float)
False
>>> isinstance(0, float)
False
>>> isinstance(0.0, float)
True
The basic arithmetic operations used for integers will also work for floats. (Bitwise operators will not work with floats.) >>> 4.0 + 2.0
6.0
>>> 1.0 + 4.5
3.5
>>> 1.75  1.5
0.25
>>> 4.13  1.1
3.03
>>> 4.5 // 1.0
4.0
>>> 4.5 / 1.0
4.5
>>> 4.5 % 1.0
0.5
>>> 7.75 * 0.25
1.9375
>>> 0.5 * 0.5
0.25
>>> 1.5 ** 2.0
2.25
Some technical information about 'floats.'A floating point literal can be either pointfloat or exponentfloat.
These are examples of exponents:
decinteger exponent, for example: pointfloat exponent, for example: The separate parts of a floating point number are:
The
sys.float_infoObject >>> import sys
>>> print ( '\n'.join(str(sys.float_info).split(', ')) )
sys.float_info(max=1.7976931348623157e+308 # maximum representable finite float
max_exp=1024
max_10_exp=308
min=2.2250738585072014e308 # minimum positive normalized float
min_exp=1021
min_10_exp=307
dig=15 # maximum number of decimal digits that can be faithfully represented in a float
mant_dig=53 # float precision: the number of baseradix digits in the significand of a float
epsilon=2.220446049250313e16
radix=2 # radix of exponent representation
rounds=1)
>>>
Information about some of the above values follows: sys.float_info.mant_dig>>> sys.float_info.mant_dig
53
>>>
>>> sys.float_info[7]
53
>>>
>>> I1 = (1<<53)  1 ; I1 ; hex(I1) ; I1.bit_length
9007199254740991
'0x1fffffffffffff'
53
>>> float(I11) ; float(I11) == I11
9007199254740990.0
True
>>> float(I1) ; float(I1) == I1
9007199254740991.0
True
>>> float(I1+1) ; float(I1+1) == I1+1
9007199254740992.0
True
>>> float(I1+2) ; float(I1+2) == I1+2
9007199254740992.0 # Loss of precision occurs here.
False
>>>
>>> I2 = I1  10**11 ; I2 ; hex(I2) ; I2.bit_length ; float(I2) == I2 ; len(str(I2))
9007099254740991
'0x1fffe8b78917ff'
53
True # I2 can be accurately represented as a float.
16
>>> I3 = I1 + 10**11 ; I3 ; hex(I3) ; I3.bit_length ; float(I3) == I3 ; len(str(I3))
9007299254740991
'0x2000174876e7ff'
54 # Too many bits.
False # I3 can not be accurately represented as a float.
16
>>>
sys.float_info.dig>>> len(str(I1))
16
>>>
>>> sys.float_info.dig
15
>>> sys.float_info[6]
15
>>>
As shown above some (but not all) decimal numbers of 16 digits can be accurately represented as a float.
Hence 15 as the limit in sys.float_info.max>>> sys.float_info.max
1.7976931348623157e+308
>>>
>>> sys.float_info[0]
1.7976931348623157e+308
>>>
>>> 1.7976931348623157e+305
1.7976931348623156e+305
>>> 1.7976931348623157e+306
1.7976931348623156e+306
>>> 1.7976931348623157e+307
1.7976931348623158e+307
>>> 1.7976931348623157e+308
1.7976931348623157e+308
>>> 1.7976931348623157e+309
inf
>>>
sys.float_info.min>>> sys.float_info.min
2.2250738585072014e308
>>> sys.float_info[3]
2.2250738585072014e308
>>>
>>> 2.2250738585072014e306
2.2250738585072014e306
>>> 2.2250738585072014e307
2.2250738585072014e307
>>> 2.2250738585072014e308
2.2250738585072014e308
>>> 2.2250738585072014e309
2.225073858507203e309 # Loss of precision.
>>> 2.2250738585072014e310
2.2250738585072e310
>>> 2.2250738585072014e311
2.225073858507e311
>>>
The Precision of FloatsBefore you start calculating with floats you should understand that the precision of floats has limits, due to Python and the architecture of a computer. Some examples of errors due to finite precision are displayed below. >>> 1.13  1.1
0.029999999999999805
>>> 0.001 / 11.11
9.000900090009002e05
>>> 1 + .0000000000000001
1.0
>>> 5.5 % 3.2
0.9000000000000004
>>> float(1_234_567_890_123_456)
1234567890123456.0
>>> float(12_345_678_901_234_567)
1.2345678901234568e+16
In the second example, In the third example, the sum of the addends The fourth example gives the correct result if rewritten: >>> ((5.5*10 ) % (3.2*10)) / 10.0
0.9
When working with Python floats, we need to be aware that there will probably be a margin of error. Decimal fixed point and floating point arithmetic for extreme precisionThe Python "Decimal" module provides support for fast correctlyrounded decimal floating point arithmetic. The module offers several advantages over the float datatype, including:
The usual start to using decimals is importing the module, viewing the current context with getcontext and, if necessary, setting new values for precision, rounding, or enabled traps: >>> from decimal import *
>>> getcontext
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=999999, Emax=999999, capitals=1, clamp=0, flags=[Inexact, FloatOperation, Rounded], traps=[InvalidOperation, DivisionByZero, Overflow])
>>> setcontext(ExtendedContext)
>>> getcontext
Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[])
>>> setcontext(BasicContext)
>>> getcontext
Context(prec=9, rounding=ROUND_HALF_UP, Emin=999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[Clamped, InvalidOperation, DivisionByZero, Overflow, Underflow])
>>> c = getcontext
>>> c.flags[Inexact] = True
>>> c.flags[FloatOperation] = True
>>> c.flags[Rounded] = True
>>> getcontext
Context(prec=9, rounding=ROUND_HALF_UP, Emin=999999, Emax=999999, capitals=1, clamp=0, flags=[Inexact, FloatOperation, Rounded], traps=[Clamped, InvalidOperation, DivisionByZero, Overflow, Underflow])
>>> getcontext.prec = 75 # set desired precision
>>> getcontext
Context(prec=75, rounding=ROUND_HALF_UP, Emin=999999, Emax=999999, capitals=1, clamp=0, flags=[Inexact, FloatOperation, Rounded], traps=[Clamped, InvalidOperation, DivisionByZero, Overflow, Underflow])
We are now ready to use the decimal module. >>> Decimal(3.14) # Input to decimal is float.
Decimal('3.140000000000000124344978758017532527446746826171875') # Exact value of float 3.14.
>>> Decimal('3.14') # Input to decimal is string.
Decimal('3.14') # Exact value of 3.14 in decimal floating point arithmetic.
>>> (2 ** 0.5)**2
2.0000000000000004 # Result of binary floating point operation. We expect 2.
>>> (Decimal('2') ** Decimal('0.5')) ** Decimal('2')
Decimal('1.99999999999999999999999999999999999999999999999999999999999999999999999999')
# Result of decimal floating point operation with string input. We expect 2.
>>> (2.12345678 ** (1/2.345)) ** 2.345
2.1234567800000006 # Result of floating point operation. We expect 2.12345678.
>>> (Decimal('2.12345678') ** (Decimal('1')/Decimal('2.345'))) ** Decimal('2.345')
Decimal('2.12345677999999999999999999999999999999999999999999999999999999999999999999')
# Result of decimal floating point operation with string input . We expect 2.12345678.
>>> getcontext.rounding=ROUND_UP
>>> (Decimal('2.12345678') ** (Decimal('1')/Decimal('2.345'))) ** Decimal('2.345')
Decimal('2.12345678000000000000000000000000000000000000000000000000000000000000000003')
# Result of decimal floating point operation with string input . We expect 2.12345678.
Some mathematical functions are also available to Decimal: >>> getcontext.prec = 30
>>> Decimal(2).sqrt
Decimal('1.41421356237309504880168872421')
>>> (Decimal(2).sqrt)**2
Decimal('2.00000000000000000000000000001') # We expect 2.
>>> Decimal(1).exp
Decimal('2.71828182845904523536028747135') # Value of 'e', base of natural logs.
>>> Decimal( Decimal(1).exp ).ln
Decimal('0.999999999999999999999999999999') # We expect 1.
Lack of precision in the real world(included for philosophical interest) >>> a = 899_999_999_999_999.1 ; a  (a  .1)
0.125
>>> 1.13  1.1
0.029999999999999805
Simple tests indicate that the error inherent in floating point operations is about This raises the question "How much precision do we need?"
Extreme Precision(included for historical interest) If you must have a result correct to 50 places of decimals, Python's integer math comes to the rescue. Suppose your calculation is:
For 50 significant digits after the decimal point your calculation becomes:
>>> dividend = 12345678900
>>> divisor = 456787654
>>>
>>> (quotient, remainder) = divmod(dividend*(10**51), divisor) ; quotient;remainder
27027172892899596625262555804540198890751981663672547
231665262
>>> if remainder >= ((divisor + (divisor & 1)) >> 1) : quotient += 1
...
>>> quotient
27027172892899596625262555804540198890751981663672548
>>>
The correct result but note: >>> quotient*(10**(51))
27.027172892899596 # Lack of precision.
>>>
Put the decimal point in the correct position within a string to preserve precision: >>> str(quotient)[0:51] + '.' + str(quotient)[51:]
'27.027172892899596625262555804540198890751981663672548'
>>>
Format the result: >>> s1 = str(quotient)[51:] ; s1
'027172892899596625262555804540198890751981663672548'
>>> L2 = [ s1[p:p+5] for p in range(0,51,5) ] ; L2
['02717', '28928', '99596', '62526', '25558', '04540', '19889', '07519', '81663', '67254', '8']
>>> decimal = '_'.join(L2) ; decimal
'02717_28928_99596_62526_25558_04540_19889_07519_81663_67254_8'
>>> str(quotient)[0:51] + '.' + decimal
'27.02717_28928_99596_62526_25558_04540_19889_07519_81663_67254_8'
# The result formatted for clarity and accurate to 50 places of decimals.
>>>
Both strings
acceptable as input to Python's Decimal module. Lack of precision and what to do about itLack of precision in floating point operations quickly becomes apparent: sum = 0
increment = 0.000_000_000_1
for count in range(1,1000) :
sum += increment
print ('count= {}, sum = {}'.format(count,sum))
if sum != count/10_000_000_000 : break
count= 1, sum = 1e10 count= 2, sum = 2e10 count= 3, sum = 3e10 count= 4, sum = 4e10 count= 5, sum = 5e10 count= 6, sum = 6e10 count= 7, sum = 7e10 count= 8, sum = 7.999999999999999e10 The problem seems to be that floating point numbers are contained in 53 bits, limiting the number of significant digits in the decimal number displayed to 15 or 16. But this is not really the problem. If the standard limits the number of significant digits displayed to 15 or 16, so be it. The real problem is that underlying calculations are also performed in 53 bits. >>> (0.000_000_000_1).hex
'0x1.b7cdfd9d7bdbbp34'
>>> h1 = '0x1b7cdfd9d7bdbbp86' # increment with standard precision.
>>> float.fromhex(h1)
1e10
>>>
Precision greater than standardRewrite the above code so that the value
>>> x,r = divmod (16**26,10**10) ;x;r
2028240960365167042394
7251286016
>>> x += (r >= (10**10)/2);x
2028240960365167042395
>>> h1 = hex(x)[2:].upper;h1
'6DF37F675EF6EADF5B'
>>> increment = '0x' + h1 + 'p104' ; increment
'0x6DF37F675EF6EADF5Bp104' # Current value of increment.
>>> int(increment[:5],16).bit_length
71 # Greater precision than standard by 18 bits.
>>> float.fromhex(increment)
1e10
>>>
Exact value of increment: >>> from decimal import *
>>> Decimal(x) / Decimal(16**26)
Decimal('1.0000_0000_0000_0000_0000_01355220626007433600102690740628157139990861423939350061118602752685546875E10')
>>> # 22 significant digits.
sum = '0x0p0'
for count in range(1,1000) :
hex_val = sum.partition('p')[0]
sum = hex( eval(hex_val) + x ) + 'p104'
f1 = float.fromhex(sum)
print (
'count = {}, sum = {}, sum as float = {}'.format(count, sum, f1)
)
if f1 != count/10_000_000_000 : exit(99)
count = 1, sum = 0x6df37f675ef6eadf5bp104, sum as float = 1e10 count = 2, sum = 0xdbe6fecebdedd5beb6p104, sum as float = 2e10 count = 3, sum = 0x149da7e361ce4c09e11p104, sum as float = 3e10 ........................... count = 997, sum = 0x1ac354f2d94d7a0b7dd67p104, sum as float = 9.97e08 count = 998, sum = 0x1aca342acfc3697a2bcc2p104, sum as float = 9.98e08 count = 999, sum = 0x1ad11362c63958e8d9c1dp104, sum as float = 9.99e08 Consider the last line above: The most accurate hex representation of value drift vvv count = 999, sum = 0x1ad11362c63958e8d9c1dp104, sum as float = 9.99e08 0x1AD11362C63958E8D9B0Ap104 most accurate hex representation of sum as float ^^^^^^^^^^^^^^^^^^ 18 hex digits = 69 bits drift vvvvv count = 99999, sum = 0xa7c53e539be0252c255b85p104, sum as float = 9.9999e06 0xA7C53E539BE0252C24F026p104 most accurate hex representation of sum as float ^^^^^^^^^^^^^^^^^ 17 hex digits = 68 bits drift vvvvvvvv count = 9999999999, sum = 0xffffffff920c8098a1aceb2ca5p104, sum as float = 0.9999999999 0xFFFFFFFF920C8098A1091520A5p104 most accurate hex representation of sum as float ^^^^^^^^^^^^^^^^^^ 18 hex digits = 72 bits drift 15 decimal digits vvvvvvvvvvvvv count = 999999999999999, sum = 0x1869fffffffff920c81929f8524a0a5p104, sum as float = 99999.9999999999 0x1869FFFFFFFFF920C8098A1091520A5p104 most accurate hex representation of sum as float ^^^^^^^^^^^^^^^^^^ 18 hex digits = 69 bits While floating point operations implemented in software might not depend on conversion to and from hex strings, the above illustrates the accuracy that could be obtained if floating point software of selectable precision were to replace now antiquated floating point hardware.
>>> 1.13  1.1
0.029999999999999805
>>>
In a programming language as magnificent as Python, the above result is intolerable. Python's Decimal moduleWith a few simple changes the above counting loop takes full advantage of Python's Decimal module, and possible loss of precision becomes irrelevant. from decimal import *
def D(v1) : return Decimal(str(v1))
sum = 0
increment = D(0.000_000_000_1)
for count in range(1,1000) :
sum += increment
print ('count = {}, sum = {}'.format(count,sum))
if sum != count * increment :
exit (99)
exit (0)
count = 1, sum = 1E10 count = 2, sum = 2E10 count = 3, sum = 3E10 ................. count = 997, sum = 9.97E8 count = 998, sum = 9.98E8 count = 999, sum = 9.99E8 A float is displayed with 'e', a Decimal object with 'E'. >>> 9.99E8
9.99e08
>>> Decimal(str(9.99e8))
Decimal('9.99E8')
>>>
Reset the floatUsing formatted stringsum = 0
increment = 0.000_000_000_1
for count in range(1,1000) :
sum += increment
s1 = '{0:.10f}'.format(sum)
sum = float(s1)
print ('count= {}, sum = {}'.format(count,sum))
if sum != count / 10_000_000_000 :
exit (99)
exit (0)
count= 1, sum = 1e10 count= 2, sum = 2e10 count= 3, sum = 3e10 ................. count= 997, sum = 9.97e08 count= 998, sum = 9.98e08 count= 999, sum = 9.99e08 Using Decimal precisionPython's floating point standard states that the best accuracy to be expected is 15 significant decimal digits. from decimal import *
getcontext.prec = 15
sum = 0
increment = 0.000_000_000_1
for count in range(1,1000) :
print ( 'count =', (' '+str(count))[3:], end=' ' )
sum += increment
d1 = Decimal(str(sum))
print ( 'd1 = sum =', (' ' + str(d1))[21:], end=' ' )
d1 += 0 # This forces d1 to conform to 15 digits of precision.
print ( 'd1 =', (' ' + str(d1))[20:], end=' ' )
sum = float(d1)
print ('sum =', sum)
if sum != count / 10_000_000_000 :
print (' ', sum, count, increment, count*increment)
exit (99)
exit (0)
count = 1 d1 = sum = 1E10 d1 = 1E10 sum = 1e10 count = 2 d1 = sum = 2E10 d1 = 2E10 sum = 2e10 count = 3 d1 = sum = 3E10 d1 = 3E10 sum = 3e10 count = 4 d1 = sum = 4E10 d1 = 4E10 sum = 4e10 count = 5 d1 = sum = 5E10 d1 = 5E10 sum = 5e10 count = 6 d1 = sum = 6E10 d1 = 6E10 sum = 6e10 count = 7 d1 = sum = 7E10 d1 = 7E10 sum = 7e10 count = 8 d1 = sum = 7.999999999999999E10 d1 = 8.00000000000000E10 sum = 8e10 count = 9 d1 = sum = 9E10 d1 = 9E10 sum = 9e10 count = 10 d1 = sum = 1E9 d1 = 1E9 sum = 1e09 count = 11 d1 = sum = 1.1000000000000001E9 d1 = 1.10000000000000E9 sum = 1.1e09 count = 12 d1 = sum = 1.2E9 d1 = 1.2E9 sum = 1.2e09 count = 13 d1 = sum = 1.3E9 d1 = 1.3E9 sum = 1.3e09 count = 14 d1 = sum = 1.4000000000000001E9 d1 = 1.40000000000000E9 sum = 1.4e09 count = 15 d1 = sum = 1.5E9 d1 = 1.5E9 sum = 1.5e09 count = 16 d1 = sum = 1.6E9 d1 = 1.6E9 sum = 1.6e09 .............................. count = 296 d1 = sum = 2.96E8 d1 = 2.96E8 sum = 2.96e08 count = 297 d1 = sum = 2.97E8 d1 = 2.97E8 sum = 2.97e08 count = 298 d1 = sum = 2.9800000000000002E8 d1 = 2.98000000000000E8 sum = 2.98e08 count = 299 d1 = sum = 2.9899999999999996E8 d1 = 2.99000000000000E8 sum = 2.99e08 count = 300 d1 = sum = 3.0000000000000004E8 d1 = 3.00000000000000E8 sum = 3e08 count = 301 d1 = sum = 3.01E8 d1 = 3.01E8 sum = 3.01e08 count = 302 d1 = sum = 3.02E8 d1 = 3.02E8 sum = 3.02e08 .............................. count = 997 d1 = sum = 9.97E8 d1 = 9.97E8 sum = 9.97e08 count = 998 d1 = sum = 9.98E8 d1 = 9.98E8 sum = 9.98e08 count = 999 d1 = sum = 9.989999999999999E8 d1 = 9.99000000000000E8 sum = 9.99e08 The last line: count = 999 d1 = sum = E8 d1 = E8 sum = 9.99e08 The value

In Python and most languages, a Boolean can be either >>> 1 == 1
True
>>> 1 == 0
False
>>> bool(0)
False
>>> bool(1)
True
>>> bool(10001219830)
True
>>> bool(1908)
True
>>> bool("Hello!")
True
>>> bool("")
False
>>> bool(" ")
True
>>> bool(None)
False
>>> bool(0.000000000000000000000000000000000)
False
>>> bool("0.000000000000000000000000000000000")
True
>>> bool(0.0)
False
>>> bool([])
False
>>> bool([1, 2, 3])
True
>>> bool
False
>>> bool(True)
True
>>> bool(False)
False
>>> bool(1==1)
True
>>> bool(1==0)
False
You can also use three operators to alter a Boolean statement^{[8]}: >>> not False
True
>>> not True
False
>>> True and True
True
>>> True and False
False
>>> True or False
True
>>> False or False
False
>>> not(False or False)
True
>>> not(False and False)
True
>>> not(False and True)
True
All of the possible combinations are: True and True: True
True and False: False
False and True: False
False and False: False
True or True: True
True or False: True
False or True: True
False or False: False
(not(True and True)) == ((not True) or (not True)): True
(not(True and False)) == ((not True) or (not False)): True
(not(False and True)) == ((not False) or (not True)): True
(not(False and False)) == ((not False) or (not False)): True
(not(True or True)) == ((not True) and (not True)): True
(not(True or False)) == ((not True) and (not False)): True
(not(False or True)) == ((not False) and (not True)): True
(not(False or False)) == ((not False) and (not False)): True
The above negated statements reflect "De Morgan's laws." For example, the statement (not(True and True)) == ((not True) or (not True)): True
is equivalent to: True and True True or True. A simple way to choose one of two possible values:>>> L1 = [1,2,0,3,0,5]
Produce list L2, a copy of L1, except that each value 0 in L1 has been replaced by 0xFF: >>> L2 = []
>>>
>>> for p in L1 :
... L2 += ([p], [0xFF])[p == 0]
...
>>> L2
[1, 2, 255, 3, 255, 5]
>>>
Expressions containing multiple booleansConsider the expression: A and B or C
Does this mean (A and B) or C
Does it mean A and (B or C)
It might be tempting to say that there is no difference, but look closely: for A in True, False :
for B in True, False :
for C in True, False :
b1 = (A and B) or C
b2 = A and (B or C)
if b1 != b2 :
print (
'''
for A = {}, B = {}, C = {}
(A and B) or C = {}
A and (B or C) = {}
'''.format(A, B, C, b1, b2)
)
for A = False, B = True, C = True (A and B) or C = True A and (B or C) = False for A = False, B = False, C = True (A and B) or C = True A and (B or C) = False Add another boolean to the expression: A and B or C and D
and the number of different possibilities is at least 96. You can see that the complexity of these expressions quickly becomes unmanageable. The essence of this section: Keep your expressions simple and use parentheses as necessary to ensure that your code is interpreted exactly as you expect.

A complex number is represented as >>> 1+2j
(1+2j)
>>> 1+5.5j
(1+5.5j)
>>> 0+5.5j
5.5j
>>> 2j
2j
>>> 1+0j
(1+0j)
>>> complex(3,2)
(32j)
Note also that j cannot be used on its own without b. If you try to use j on its own, Python will look for a variable >>> a = 5 + 3j
>>> a  j
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'j' is not defined
>>> a  1j
(5+2j)
>>> j = 3j
>>> a  j
(5+6j)
>>> a  1j
(5+2j)
The last result illustrates that even when the variable j has a numerical value, 1j (where, as above, can be any number) is always interpreted as the imaginary number j, not the variable j.
>>> (1+3j)+(25j)
(32j)
>>> (1+3j)(25j)
(1+8j)
>>> (1+3j)*(25j)
(17+1j)
>>> a = complex(3,5) ; b = 1 ; b += 2j ; a ; b
(35j)
(1+2j)
>>> a + b ; a  b
(43j)
(27j)
>>> a * b ; a / b
(13+1j)
(1.42.2j)
>>> a + 4 ; b  2j ; a * 3.1 ; b / 2
(75j)
(1+0j)
(9.315.5j)
(0.5+1j)
>>> b ; b /= 5 ; b
(1+2j)
(0.2+0.4j)
>>> a = complex(3,5j) ; a
(80j)
Look closely at the last example. It does not produce an error, but is it what you want?
>>> (1+2j).real
1.0
>>> (1+2j).imag
2.0
>>> var = 5+3j
>>> var.real
5.0
>>> var.imag
3.0
cmath  Mathematical functions for complex numbers
IntroductionA Python complex number See Figure 1. In Cartesian Geometry of 2 dimensions the real part of complex number In scientific notation the number Note: Because the expression 'bj' could be the name of a variable, and to avoid confusion, it might be better to express a complex number within Python as The values >>> Z = complex(3.6, 2.7) ; Z
(3.6+2.7j)
>>> Z = 3.6 + 2.7j ; Z
(3.6+2.7j)
>>> Z = 3.6 + 2.7J ; Z # 'J' upper case.
(3.6+2.7j)
>>> Z.real ; Z.imag
3.6
2.7
>>>
>>> Z.real + 1j*Z.imag
(3.6+2.7j)
>>> Z.real + 1j*Z.imag == Z
True
>>>
The absolute value of a complex number is the length of the modulus:
>>> abs(Z)
4.5
>>> (Z.real**2 + Z.imag**2)**(1/2)
4.5
>>>
Some useful constants: >>> import cmath
>>> ? = cmath.e ; ? # Greek epsilon, base of natural logarithms.
2.718281828459045
>>> ? = cmath.pi ; ? # Greek pi.
3.141592653589793
>>> ? = cmath.tau ; ? # Greek tau.
6.283185307179586
>>> ? == 2*?
>>> True
Addition of complex numbersTo add two complex numbers in rectangular format, simply add the real parts, then the imaginary parts: >>> import cmath
>>>
>>> cn1 = 1+3j ; cn1
(1+3j)
>>> cn2 = 25j ; cn2
(25j)
>>> cn1 + cn2 == cn1.real + cn2.real + 1j*(cn1.imag + cn2.imag)
True
>>>
Polar coordinatesPolar coordinates provide an alternative way to represent a complex number. In polar coordinates, a complex number
>>> tan_phi = Z.imag/Z.real ; tan_phi
0.75
>>> ? = cmath.atan(tan_phi).real ; ?
0.6435011087932844 # ? in radians
>>> ? * (180/?)
36.86989764584402 # ? in degrees.
>>>
Class method
>>> ?1 = cmath.phase(Z) ; ?1
0.6435011087932844
>>> ?1 == ?
True
>>>
From figure 1:
>>> Z ; r ; ?
(3.6+2.7j)
4.5
0.6435011087932844
>>>
>>> cos? = Z.real / r ; cos?
0.8
>>> sin? = Z.imag / r ; sin?
0.6
>>>
>>> Z1 = r*( cos? + 1j*sin? ) ; Z1
(3.6+2.7j)
>>>
De Moivre's formulaThe format containing polar coordinates is useful because:
Proof
An example>>> sin2? = cmath.sin(2*?).real ; sin2?
0.96
>>> cos2? = cmath.cos(2*?).real ; cos2?
0.28
>>> Z
(3.6+2.7j)
>>> Z**2
(5.67+19.44j)
>>> r*r*(cos2? + 1J*sin2?)
(5.67+19.44j)
>>>
and on polar diagram
= length = abs = length = abs
Angle is the phase of .
Phase of Therefore:
>>> Z1 = 3+1j*(5/4) ; Z1 ; abs(Z1) ; abs(Z1) == 13/4
(3+1.25j)
3.25
True
>>> Z = Z1*Z1 ; Z ; Z.real == 7+(7/16)
(7.4375+7.5j)
True
>>>
>>> sin?_2 = cmath.sin(?/2).real ; sin?_2
0.31622776601683794
>>> cos?_2 = cmath.cos(?/2).real ; cos?_2
0.9486832980505138
>>> Z
(3.6+2.7j)
>>> cmath.sqrt(Z)
(2.0124611797498106+0.670820393249937j)
>>> (r**0.5)*(cos?_2 + 1J*sin?_2)
(2.0124611797498106+0.6708203932499369j)
>>>
The two square roots of >>> 1**2 ; (1)**2
1
1
>>>
The two square roots of >>> (1j)**2 ; (1j)**2
(1+0j)
(1+0j)
>>>
Cube roots of 1 simplified
Proof:
Proof: .
>>> r1 = 1 ; v1 = r1**3 ; v1
1
>>> r2 = ( 1 + 1j * (3**0.5)) / 2 ; v2 = r2**3 ; v2
(0.9999999999999998+1.1102230246251565e16j)
>>> r3 = ( 1  1j * (3**0.5)) / 2 ; v3 = r3**3 ; v3
(0.99999999999999981.1102230246251565e16j)
>>>
>>> [ cmath.isclose(v,1,abs_tol=1e15) for v in (v1,v2,v3) ]
[True, True, True]
>>>
Multiplication of complex numbersTo multiply two complex numbers in polar format, multiply the moduli and add the phases. >>> cn1 = 3+4j ; cn1
(3+4j)
>>> r1,?1 = cmath.polar(cn1) ; r1 ; ?1
5.0
0.9272952180016122 # radians
>>>
>>> cn2 = 4+3j ; cn2
(4+3j)
>>> r2,?2 = cmath.polar(cn2) ; r2 ; ?2
5.0
2.498091544796509 # radians
>>>
>>> v1 = cn1*cn2 ; v1
(247j)
>>> v2 = 25*( cmath.cos(?1 + ?2) + 1j*cmath.sin(?1 + ?2) ) ; v2 # r1 * r2 = 25
(247.000000000000002j)
>>>
>>> cmath.isclose(v1, v2, abs_tol=1e15)
True
>>>
Proof
Classification functionscmath.isclose(a, b, *, rel_tol=1e09, abs_tol=0.0)Return True if the values a and b are close to each other and False otherwise. Whether or not two values are considered close is determined according to given absolute and relative tolerances. >>> v1; cmath.polar(v1)
(87283949+87283949j)
(123438144.45328155, 0.7853981633974483)
>>> v2; cmath.polar(v2)
(87283949+87283950j)
(123438145.16038834, 0.7853981691258783)
>>> cmath.isclose(v1,v2)
False
>>>
>>> cmath.isclose(v1,v2, rel_tol=8e9)
False
>>> cmath.isclose(v1,v2, rel_tol=9e9)
True
>>>
>>> cmath.isclose(v1,v2, abs_tol=1)
True
>>> cmath.isclose(v1,v2, abs_tol=.5)
False
>>>
Power and logarithmic functionscmath.sqrt(x)Return the positive value of the square root of >>> cmath.sqrt(1)
1j
>>>
>>> cmath.sqrt(7+24j)
(4+3j)
>>> cmath.sqrt(7+24j)
(43j) # sqrt has both positive and negative values.
>>> (cmath.sqrt(7+24j))**2
(7+24j)
>>>
>>> cmath.sqrt(7+(7/16) + 1j*7.5)
(3+1.25j)
>>>
cmath.exp(x)Return the exponential value >>> cmath.exp(1)
(2.718281828459045+0j) # Value of e, base of natural logarithms.
>>>
>>> ? = cmath.pi ; ?
3.141592653589793
>>>
>>> cmath.exp(1j*?/3) # ?/3 = 60 degrees.
(0.5+0.8660254037844386j)
>>>
>>> cmath.cos(?/3)
(0.50j)
>>> cmath.sin(?/3)
(0.8660254037844386+0j)
>>>
>>> cmath.exp(1j*?/3) == cmath.cos(?/3) + 1j*cmath.sin(?/3)
True
>>>
The case when : >>> cmath.exp(1j*?)
(1+0j)
>>>
The combination of value When

IntroductionSince integers and floats can't be mixed together in some situations, you'll need to be able to convert them from one type to another. Luckily, it's very easy to perform a conversion. To convert a data type to an integer, use the >>> int(1.5)
1
>>> int(10.0)
10
>>> int(True)
1
>>> int(False)
0
>>> int('0xFF', base=16) ; int('0xF1F0', 16) ; int('0b110100111', 0) ; int('11100100011',2)
255
61936
423
1827
>>> int("100")
100
>>> float(102)
102.0
>>> float(932)
932.0
>>> float(True)
1.0
>>> float(False)
0.0
>>> float("101.42")
101.42
>>> float("4")
4.0
>>> bool(1)
True
>>> bool(0)
False
>>> bool(0.0)
False
>>> bool(0.01)
True
>>> bool(14)
True
>>> bool(14+3j)
True
>>> bool(3j)
True
>>> bool(0j)
False
>>> bool("")
False
>>> bool("Hello")
True
>>> bool("True")
True
>>> bool("False")
True
>>> complex(True)
(1+0j)
>>> complex(False)
0j
>>> complex(3, 1)
(3+1j)
>>> complex(1, 22/7)
(1+3.142857142857143j)
>>> complex(0, 1.5)
1.5j
>>> complex(7, 8)
(7+8j)
>>> complex("1")
(1+0j)
>>> complex("1+4j")
(1+4j)
>>> complex("9.75j")
9.75j
Converting integers, decimal to nondecimalThis conversion is from int to str representing int: >>> a = 12345678901234567890
>>> b = bin(a) ; b
'0b1010101101010100101010011000110011101011000111110000101011010010'
>>> h = hex(a) ; h
'0xab54a98ceb1f0ad2'
>>> o = oct(a) ; o
'0o1255245230635307605322'
>>>
Converting integers, nondecimal to decimalThis conversion is from str representing int to int: >>> a;b;h;o
12345678901234567890
'0b1010101101010100101010011000110011101011000111110000101011010010'
'0xab54a98ceb1f0ad2'
'0o1255245230635307605322'
>>>
>>> int(b,base=0) == int(b,base=2) == int(b,0) == int(b,2) == a # Base 0 or correct base is required.
True
>>> int(h,16) == a
True
>>> int(o,8) == a
True
>>>
>>> int ('ab54a98ceb1f0ad2', 16) == a # When base 16 is supplied, the prefix '0x' is not necessary.
True
>>>
>>> eval(b) == a # Function eval(...) provides simple conversion from str to base type.
True
>>> eval(h) == a
True
>>> eval(o) == a
True
>>>
>>> int('12345678901234567890',0) == int('12345678901234567890',base=0) == a
True
>>> int('12345678901234567890',10) == int('12345678901234567890',base=10) == a
True
>>> eval('12345678901234567890') == int('12345678901234567890') == a
True
>>>
Interfacing with Python's Decimal module>>> from decimal import *
>>> float1 = 3.14159
>>> dec1 = Decimal(float1) ; dec1
Decimal('3.14158999999999988261834005243144929409027099609375')
>>> str(dec1)
'3.14158999999999988261834005243144929409027099609375'
>>>
>>> float2 = eval(str(dec1)) ; float2
3.14159
>>> isinstance(float2, float)
True
>>> float2 == float1
True
>>>
>>> float2 = float(dec1) ; float2
3.14159
>>> isinstance(float2, float)
True
>>> float2 == float1
True
>>>
Converting

Miscellaneous TopicsPlus zero and minus zeroThe concept of plus and minus zero does not apply to the integers: >>> +0 ; 0
0
0
>>> Floats retain the distinction: >>> +0. ; 0. ; +0. == 0. == 0
0.0
0.0
True
>>> As do complex numbers: >>> complex(0., 0.)
(00j)
>>> complex(0., 0.).real
0.0
>>> complex(0., 0.).imag
0.0
>>> Examples of plus and minus zero>>> '{0:0.2f}'.format(.0000)
'0.00'
>>> '{0:0.2f}'.format(.0003)
'0.00'
>>> '{0:0.2f}'.format(.0000)
'0.00'
>>> '{0:0.2f}'.format(.0003)
'0.00'
>>> A small nonzero positive number was displayed as According to values under "Cube roots of 1 simplified," one of the cube roots of unity is We expect that should equal However: >>> r3 = ( 1  1j * (3**0.5)) / 2 ; v3 = r3**3 ; v3
(0.99999999999999981.1102230246251565e16j)
>>> The best accuracy which we can expect from floats is 15 significant digits: >>> '{0:0.15f}'.format( v3.real )
'1.000000000000000'
>>> '{0:0.15f}'.format( v3.imag )
'0.000000000000000'
>>> The respective values
>>> float( '0.000000000000000' )
0.0
>>> The conversion from string to float preserves the distinction of minus zero, indicating that the original value was, probably, a small, nonzero, negative number. Precision and formatted decimalsWithin this section the expression "decimal precision" means precision as implemented by Python's decimal module. Precision means the number of digits used to display a value beginning with and containing the first nonzero digit. Some examples using decimal precision: >>> from decimal import *
>>> getcontext.prec = 4
>>>
>>> Decimal('0.0034567')
Decimal('0.0034567') # Precision not enforced here.
>>> Decimal('0.0034567') + 0
Decimal('0.003457') # '+ 0' forces result to conform to precision of 4.
>>> Decimal('0.003456432') + 0
Decimal('0.003456')
>>> Decimal('3456432') + 0
Decimal('3.456E+6')
>>> Decimal('3456789') + 0
Decimal('3.457E+6')
>>>
>>> Decimal('0.00300055') + 0
Decimal('0.003001')
>>> Decimal('0.00300033') + 0
Decimal('0.003000') # Trailing Zeroes are retained to conform to precision of 4.
>>> Note how the following values are rounded. More about rounding in the next section. >>> from decimal import *
>>> getcontext.prec = 4
>>>
>>> Decimal('3456500') + 0
Decimal('3.456E+6') # Rounded down.
>>> Decimal('3457500') + 0
Decimal('3.458E+6') # Rounded up.
>>> Python's string method >>> '{0:.4f}'.format(0.003456)
'0.0035' # Accurate to four places of decimals.
>>> '{0:.4f}'.format(0.003446)
'0.0034' # Accurate to four places of decimals.
>>> Default rounding provided by python's string method >>>
>>> '{0:.4f}'.format(0.00345)
'0.0034' # Rounded down.
>>> '{0:.4f}'.format(0.00355)
'0.0036' # Rounded up.
>>> Rounding of close but inexact valuesEven elementary calculations lead to increasing complexity in the practical execution of a task involving numbers. It is fairly easy to imagine one fifth of one inch shown mathematically as inch. What if you had to cut from a piece of steel rod a smaller piece with an exact length of inch? Most common measuring instruments have lengths expressed in inches and sixteenths of an inch. Then inch becomes inch. You use a micrometer measuring instrument accurate to inch and inch is inch exactly. What if you had to produce a piece of steel rod with length feet exactly? feet = inches = inches = inches. Both the measuring tape and micrometer seem inadequate for the task. You devise a system dependent on similar triangles and parallel lines. Success. The value can be produced geometrically. What if you had to produce a square with an exact area of square inches? The side of the square would be inches exactly, but how do you measure inches exactly? In practical terms your task becomes feasible if some tolerance in the area of the finished product is allowed, for example square inches. Then a "square" with adjacent sides of 1.4142 and 1.4143 inches has an area within the specified tolerance. DRIP for exampleEven simple calculations based on exact decimals quickly lead to impractical numbers. Suppose you have a DRIP (Dividend ReInvestment Plan) with any of the big wellknown corporations. Most DRIPs permit you to purchase fractions of a share of stock. Shares of an attractive stock are currently trading for and you invest , buying shares of stock. On your statement you don't see a credit of shares of stock. The custodian of the plan may show your holding accurate to four places of decimals: shares. The fraction is actually but your credit is called 'rounding down.' The corporation then issues a dividend of per share when the stock is trading for per share and you reinvest the dividend. If the custodian reinvests the dividend for you at a discount to market price, your credit is shares, shown on your statement as shares giving you a total holding of shares probably shown on your statement as with a current market value of shown on your statement as . The result of your mathematical calculations will probably be a close approximation of the exact value after allowing for tolerable errors based on precision and rounding of intermediate results. Default roundingWhen you import python's decimal module, values are initialized as the 'default' values. >>> from decimal import *
>>> getcontext
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])
>>> setcontext(DefaultContext)
>>> getcontext
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow]) # Same as above.
>>>
The default rounding method is called
>>> getcontext.prec = 4
>>> getcontext
Context(prec=4, rounding=ROUND_HALF_EVEN, Emin=999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])
>>>
>>> Decimal('0.012344') + 0
Decimal('0.01234')
>>> Decimal('0.012345') + 0
Decimal('0.01234') # Rounded down to nearest even number.
>>> Decimal('0.045674') + 0
Decimal('0.04567')
>>> Decimal('0.045675') + 0
Decimal('0.04568') # Rounded up to nearest even number.
>>>
Default rounding provided by python's string method .format is same as that for decimal precision: >>>
>>> '{0:.4f}'.format(0.00345)
'0.0034' # Rounded down.
>>> '{0:.4f}'.format(0.00355)
'0.0036' # Rounded up.
>>>
A disadvantage of this method of rounding is that an examination of the result does not indicate what the original value was: >>> Decimal('0.045675') + 0 == Decimal('0.045685') + 0
True
>>>
Other rounding modesROUND_HALF_UPRounding mode ROUND_HALF_UP is illustrated as follows: >>> getcontext.rounding=ROUND_HALF_UP
>>> getcontext
Context(prec=4, rounding=ROUND_HALF_UP, Emin=999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])
>>>
>>> Decimal('0.012345') + 0
Decimal('0.01235')
>>> Decimal('0.012355') + 0
Decimal('0.01236')
>>> Decimal('0.012365') + 0
Decimal('0.01237')
>>> Decimal('0.012375') + 0
Decimal('0.01238')
Same logic for negative numbers: >>> Decimal('0.012345') + 0
Decimal('0.01235')
>>> Decimal('0.012355') + 0
Decimal('0.01236')
>>> Decimal('0.012365') + 0
Decimal('0.01237')
>>> Decimal('0.012375') + 0
Decimal('0.01238')
ROUND_DOWNThe numbers in the example under DRIP above are derived using python's
setcontext(DefaultContext)
number_of_initial_shares = 100/38
print ('number_of_initial_shares =', number_of_initial_shares)
number_of_initial_shares = Decimal(number_of_initial_shares).quantize(Decimal('.0001'), rounding=ROUND_DOWN)
print (
'''After rounding down
number_of_initial_shares =''', number_of_initial_shares
)
shares_added = 0.37*float(number_of_initial_shares) / (37.26*0.95)
print ('''
shares_added =''', shares_added)
shares_added = Decimal(shares_added).quantize(Decimal('.0001'), rounding=ROUND_DOWN)
print (
'''After rounding down
shares_added =''', shares_added
)
total_shares = shares_added + number_of_initial_shares
value = total_shares * Decimal('37.26')
print ('''
value =''', value)
value = value.quantize(Decimal('.01'), rounding=ROUND_DOWN)
print (
'''After rounding down
value =''', '$'+str(value)
)
number_of_initial_shares = 2.6315789473684212
After rounding down
number_of_initial_shares = 2.6315
shares_added = 0.02750670960815888
After rounding down
shares_added = 0.0275
value = 99.074340
After rounding down
value = $99.07 When using method >>> getcontext.prec = 6
>>> Decimal('0.0000123456').quantize(Decimal('1e6'))
Decimal('0.000012')
>>> Decimal('123.0000123456').quantize(Decimal('1e6'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]
>>> getcontext.prec = 9
>>> Decimal('123.0000123456').quantize(Decimal('1e6'))
Decimal('123.000012') # Desired result has precision of 9.
>>>

>>> + 44 ; eval('  33 ') ; eval('  0003.e002 ') ; eval(' + 0003.00000E002 ') ; eval(' + 0003.12E0073 ')
>>> + 4 + 1j*3 ; complex(2,3) ; complex("2+3j") ; eval("2+3J") ; complex('3',7j)
>>> bool(6) ; bool(0) ; bool('0') ; '123'+0 ; bool('123') + 1 ; 1+3 == 4 ; 2**2 == 3
if sum != count / 10_000_000_000 :
This could be written as: if sum != count * increment :
However: >>> 5*(1e10) ; 6*(1e10) ; 7*(1e10)
5e10
6e10
7.000000000000001e10
>>>
>>> 7 / (1e10)
7e10
>>>
How would you write the line
For greater precision than is available with floating point arithmetic, use Python's decimal module to calculate 

Python's builtin functions:
"abs", "bin", "bool", "complex", "divmod", "eval(expression, ....)", "float", "hex", "int", "oct", "pow", "round", "sys.float_info", "sys.int_info"
Python's documentation:
"3.1.1. Numbers", "Numeric Types", "Integer literals", "Floating point literals", "Imaginary literals", "Operator precedence", "Why are floatingpoint calculations so inaccurate?", "15. Floating Point Arithmetic: Issues and Limitations", "9.4. decimal  Decimal fixed point and floating point arithmetic", "4.4.2. Additional Methods on Integer Types", "4.4.3. Additional Methods on Float"
Manage research, learning and skills at IT1me. Create an account using LinkedIn to manage and organize your IT knowledge. IT1me works like a shopping cart for information  helping you to save, discuss and share.