*This notebook contains an excerpt from the Python Programming and Numerical Methods - A Guide for Engineers and Scientists, the content is also available at Berkeley Python Numerical Methods.*

*The copyright of the book belongs to Elsevier. We also have this interactive book online for a better learning experience. The code is released under the MIT license. If you find this content useful, please consider supporting the work on Elsevier or Amazon!*

< 9.3 Round-off Errors | Contents | 10.0 Errors, Good Programming Practices, and Debugging >

# Summary¶

Numbers have many representations, and each representation has advantages and disadvantages.

Computers must represent numbers using a finite number of digits (bits).

Binary and IEEE754 are finite representations of numbers used by computers.

Round-off error is an important error associated with numerical methods.

# Problems¶

Write a function

*my_bin_2_dec(b)*where*b*is binary number represented by a list of ones and zeros. The last element of*b*represents the coefficient of \(2^0\), the second-to-last element of b represents the coefficient of \(2^1\), and so on. The output variable,*d*, should be the decimal representation of b. The test cases are provided below.

```
def my_bin_2_dec(b):
# write your function code here
return d
```

```
# Output: 7
my_bin_2_dec([1, 1, 1])
```

```
# Output: 85
my_bin_2_dec([1, 0, 1, 0, 1, 0, 1])
```

```
# Output: 33554431
my_bin_2_dec([1]*25)
```

Write a function

*my_dec_2_bin(d)*, where*d*is a positive integer in decimal, and*b*is the binary representation of*d*. The output*b*must be a list of ones and zeros, and the leading term must be a 1 unless the decimal input value is 0. The test cases are provided below.

```
def my_dec_2_bin(d):
# write your function code here
return b
```

```
# Output: [0]
my_dec_2_bin(0)
```

```
# Output: [1, 0, 1, 1, 1]
my_dec_2_bin(23)
```

```
# Output: [1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1]
my_dec_2_bin(2097)
```

Use the two functions you wrote in problems 1 and 2 to compute

*d = my_bin_2_dec(my_dec_2_bin(12654))*. Do you get the same number?

Write a function

*my_bin_adder(b1,b2)*, where*b1*,*b2*and the output variable*b*are binary numbers represented as in problem 1. The output variable should be computed as*b = b1 + b2*. Do not use your functions from problems 1 and 2 to write this function (i.e., do not convert*b1*and*b2*to decimal; add them, and then convert the result back to binary). This function should be able to accept inputs*b1*and*b2*of any length (i.e., very long binary numbers), and*b1*and*b2*may not necessarily be the same length.

```
def my_bin_adder(b1, b2):
# wrtie your function code here
return b
```

```
# Output: [1, 0, 0, 0, 0, 0]
my_bin_adder([1, 1, 1, 1, 1], [1])
```

```
# Output: [1, 1, 1, 0, 0, 1, 1]
my_bin_adder([1, 1, 1, 1, 1], [1, 0, 1, 0, 1, 0, 0])
```

```
# Output: [1, 0, 1, 1]
my_bin_adder([1, 1, 0], [1, 0, 1])
```

What is the effect of allocating more bits to the fraction versus the characteristic and vice versa? What is the effect of allocating more bits to the sign?

Write a function

*my_ieee_2_dec(ieee)*, where*ieee*is a string contains 64 characters of ones and zeros representing a 64-bit IEEE754 number. The output should be*d*, the equivalent decimal representation of*ieee*. The input variable*ieee*will always be a 64-element string of ones and zeros defining a 64-bit float.

```
def my_ieee_2_dec(ieee):
# Write your function here
return d
```

```
# Output: -48
ieee = '1100000001001000000000000000000000000000000000000000000000000000'
my_ieee_2_dec(ieee)
```

```
# Output: 3.39999999999999991118215802999
ieee = '0100000000001011001100110011001100110011001100110011001100110011'
my_ieee_2_dec(ieee)
```

Write a function

*my_dec_2_ieee(d)*, where*d*is a number in decimal and output variable*ieee*is a string with 64 characters of ones and zeros representing the 64-bit IEEE754 closest to*d*. You can assume that*d*will not cause an overflow for 64-bit*ieee*numbers.

```
def my_dec_2_ieee(d):
# write your function code here
return ieee
```

```
# Output: '0100000000101110010111101010001110011100001100011010010001101000'
d = 1.518484199625
my_dec_2_ieee(d)
```

```
# Output: '1100000001110011010100100100010010010001001010011000100010010000'
d = -309.141740
my_dec_2_ieee(d)
```

```
# Output: '1100000011011000101010010000000000000000000000000000000000000000'
d = -25252
my_dec_2_ieee(d)
```

Define

*ieee_baby*to be a representation of numbers using 6 bits where the first bit is the sign bit, the second and third bits are allocated to the characteristic, and the fourth, fifth, and sixth bits are allocated to the fraction. The normalization for the characteristic is 1.

Write all the decimal numbers that can be represented by *ieee_baby*.
What is the largest/smallest gap in *ieee_baby*?

Use the

*np.spacing*function to determine the smallest number such that the gap is 1.

What are some of the advantages and disadvantages of using binary versus decimal?

Write the number 13 (base10) in base1. How would you do addition and multiplication in base1?

How high can you count on your fingers if you count in binary?

Let

*b*be a binary number having*n*digits. Can you think of ways to multiply and divide*b*by 2 that does not involve any arithmetic? Hint: Think about how you multiply and divide a decimal number by 10.

< 9.3 Round-off Errors | Contents | 10.0 Errors, Good Programming Practices, and Debugging >