Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # author: Bartlomiej "furas" Burek (https://blog.furas.pl)
- # 2017.04.03
- '''
- floats approximations
- '''
- # -----------------------------------------------------------------------------
- def example_0():
- '''
- floats can keep only aproximations
- and Python can display rounded values which look correctly
- but it uses aproximations in calculations which give incorrect results
- 0.1 + 0.2 == 0.3 => False
- 0.1 => 0.1000000000000000055511151231257827021181583404541015625
- 0.2 => 0.2000000000000000111022302462515654042363166809082031250
- 0.3 => 0.2999999999999999888977697537484345957636833190917968750
- 0.1 + 0.2 => 0.3000000000000000444089209850062616169452667236328125000
- '''
- print('========== example 0 ==========')
- print('0.1 + 0.2 == 0.3', ' => ', 0.1 + 0.2 == 0.3 ) # False
- print()
- print(' 0.1', ' => ', '%.55f' % 0.1)
- print(' 0.2', ' => ', '%.55f' % 0.2)
- print(' 0.3', ' => ', '%.55f' % 0.3)
- print('0.1 + 0.2', ' => ', '%.55f' % (0.1+0.2))
- # -----------------------------------------------------------------------------
- def example_1():
- '''
- replace floats with integers to get better results (precision: 100)
- number % divider ==> ( (number*100) % (divider*100) ) / 100
- '''
- print('========== example 1 ==========')
- print('1050 % 0.05 ', ' => ', 1050 % 0.05 )
- print('((1050 * 100) % (0.05 * 100)) / 100', ' => ', ((1050 * 100) % (0.05 * 100)) / 100 )
- print('(105000%5)/100 ', ' => ', (105000%5)/100 )
- # -----------------------------------------------------------------------------
- # another examples
- # -----------------------------------------------------------------------------
- def example_2():
- '''
- replace floats with integers to get better results (precision: 100)
- number % divider ==> ( (number*100) % (divider*10) ) / 100
- '''
- print('========== example 2 ==========')
- for d in [0.3, 0.4, 0.5, 0.6, 0.7, 0.05]:
- print('--- x %', d, '---')
- print()
- print('--+-----+-----+-----------------------')
- print('x | int |round| float ')
- print('--+-----+-----+-----------------------')
- for x in range(10):
- print( x, '|', ((x*100) % (d*100)) / 100, '|', round(x%d, 1), '|', x%d )
- print('--+-----+-----+-----------------------')
- print()
- # -----------------------------------------------------------------------------
- def example_3():
- '''
- `math.fmod` - it seems not useful
- `numpy` can make opertion on all elements in array
- but it seems it has the same problem with floats
- '''
- print()
- print('=== math.fmod ===')
- print()
- import math
- for d in [0.3, 0.4, 0.5, 0.6, 0.7, 0.05]:
- print('--- x %', d, '---')
- print()
- print('--+-----------------------')
- print('x | fmod ')
- print('--+-----------------------')
- for x in range(10):
- print( x, '|', math.fmod(x, d) )
- print('--+-----------------------')
- print()
- # -----------------------------------------------------------------------------
- def example_4():
- '''
- numpy has float16, float32, float64
- (https://docs.scipy.org/doc/numpy/user/basics.types.html)
- and float32 gives True for 0.1 + 0.2 == 0.3
- but float16 and float64 give False
- '''
- import numpy as np
- print('========== example 4 - numpy ==========')
- print()
- print('--- 0.1 + 0.2 == 0.3 ---')
- print()
- a16 = np.float16(0.1) # you can use string np.float16("0.1")
- b16 = np.float16(0.2) # you can use string np.float16("0.2")
- c16 = a16 + b16
- d16 = np.float16(0.3) # you can use string np.float16("0.3")
- print('float16:', a16, b16, c16, d16, ' => ', c16 == d16) # 0.1 0.2 0.3 0.3 True
- a32 = np.float32(0.1) # you can use string np.float32("0.1")
- b32 = np.float32(0.2) # you can use string np.float32("0.2")
- c32 = a32 + b32
- d32 = np.float32(0.3) # you can use string np.float32("0.3")
- print('float32:', a32, b32, c32, d32, ' => ', c32 == d32) # 0.1 0.2 0.3 0.3 True
- a64 = np.float64(0.1) # you can use string np.float64("0.1")
- b64 = np.float64(0.2) # you can use string np.float64("0.2")
- c64 = a64 + b64
- d64 = np.float64(0.3) # you can use string np.float64("0.3")
- print('float64:', a64, b64, c64, d64, ' => ', c64 == d64) # 0.1 0.2 0.3 0.3 False
- print()
- print('--- 1050 % d ---')
- print()
- print('int % float16:', 1050 % np.float16(0.05), 'round:', round(1050 % np.float16(0.05), 2)) # 0.00640869140625
- print('int % float32:', 1050 % np.float32(0.05), 'round:', round(1050 % np.float32(0.05), 2)) # 0.0499843545258
- print('int % float64:', 1050 % np.float64(0.05), 'round:', round(1050 % np.float64(0.05), 2)) # 0.0499999999999
- print()
- print('float16 % float16:', np.float16(1050) % np.float16(0.05), 'round:', round(np.float16(1050) % np.float16(0.05), 2)) # 0.0064087
- print('float32 % float32:', np.float32(1050) % np.float32(0.05), 'round:', round(np.float32(1050) % np.float32(0.05), 2)) # 0.0499844
- print('float64 % float64:', np.float64(1050) % np.float64(0.05), 'round:', round(np.float64(1050) % np.float64(0.05), 2)) # 0.0499999999999
- # -----------------------------------------------------------------------------
- def example_5():
- import numpy as np
- for d in [0.3, 0.4, 0.5, 0.6, 0.7, 0.05]:
- print()
- for x in range(10):
- print()
- print('---', x, '%', d, '=', ((x*100) % (d*100)) / 100, '---------')
- print('int % f16 |', x % np.float16(d))
- print('int % f32 |', x % np.float32(d))
- print('int % f64 |', x % np.float64(d))
- print('----------+---')
- print('f16 % f16 |', np.float16(x) % np.float16(d))
- print('f32 % f32 |', np.float32(x) % np.float32(d))
- print('f64 % f64 |', np.float64(x) % np.float64(d))
- print('----------+-----------------')
- print()
- # -----------------------------------------------------------------------------
- example_0() # 0.1 + 0.2 == 0.3
- example_1() # x % 0.05
- example_2() # x % 0.05
- example_3() # math.fmod()
- example_4() # numpy float16/float32/float64
- example_5() # numpy float16/float32/float64
Add Comment
Please, Sign In to add comment