Features#
Constructing from different bases#
Numbers can be constructed not only from decimal, but rather from any base.
>>> n = Number(2.5)
>>> n.repr_in_base(2)
'10.1'
>>> Number(10.1, 2)
Float(2.5)
>>> Number('10.1', 2)
Float(2.5)
>>> Number(('1', '0', '.', '1'), 2)
Float(2.5)
>>> Number('+-/+', 2, digits=['-', '+'], radix_point='/') # Custom digits and a custom radix point can be used as well
Float(2.5)
Custom digits and radix point#
By default, digits are only present for bases 2-64. Therefore, Basencode lets you provide your own custom digits for not only bases above 64, but any base. You can also supply a custom radix point, for instance, if the default “.” is one of your digits.
>>> n = Number('36⠿25', radix_point='⠿') # 36.25
>>> n.repr_in_base(2, digits=['-', '+'])
'+--+--⠿-+'
>>> n.repr_in_base(94)
...
ValueError: abnormal base base 94 provided, digits must not be empty
>>> from string import digits, ascii_letters, punctuation
>>> n.repr_in_base(94,
... digits=list(digits + ascii_letters + punctuation),
... max_frac_places=10,
... )
'A⠿nK~~~~~~~~'
Memory of default digits and radix point#
Provision of digits to repr_in_base causes the provided digits to be stored on the object.
>>> n = Number('36⠿25', radix_point='⠿') # This radix point is stored as the default for this object
>>> n.repr_in_base(2, digits=['-', '+']) # These digits have now been stored as default digits
'+--+--⠿-+'
>>> n.repr_in_base(2)
'+--+--⠿-+'
>>> from string import digits, ascii_letters, punctuation
>>> n.repr_in_base(94,
... digits=list(digits + ascii_letters + punctuation),
... max_frac_places=2,
... ) # These digits have now been stored as default digits
'A⠿nK'
>>> n.repr_in_base(94)
'A⠿nK~~~~~~~~~~~~Q0"2*hcnQp~,]BCN%Kq)sQE"s=GZp&s)vyC@?n.cfG>Z1V|V*h]7v?%ED.rRM["6>jHA:SAqMZZto/(#|:IS6k'
>>> Number(n.dec_value).repr_in_base(94) # This is a new object without default digits for base 94
...
ValueError: abnormal base base 94 provided, digits must not be empty
Representation mode#
Representations using repr_in_base can be returned as strings or as lists. This is useful when digits contain two or more characters.
>>> Number(134.75).repr_in_base(2, digits=['-+', '+-']) # Digits are indistinguishable
'+--+-+-+-++-+--+.+-+-'
>>> Number(134.75).repr_in_base(2, digits=['-+', '+-'], mode='l') # Digits are now separated
['+-', '-+', '-+', '-+', '-+', '+-', '+-', '-+', '.', '+-', '+-']
It must be noted that this works with Integers as well.
Arithmetic operators#
Operator overloading has been done, and a variety of Python operators are supported.
>>> import math
>>> i = Number(123)
>>> f = Number(1.24)
>>> math.ceil(f)
Integer(2)
>>> round(f)
Integer(1)
>>> bool(i), bool(f), bool(Number(0)), bool(Number(0.))
(True, True, False, False)
>>> i / f, i / 1.24
(Float(99.19354838709677419354838710), Float(99.19354838709677))
>>> i // f
Integer(99)
>>> i % f
Float(0.24)
>>> divmod(i, f)
(Float(99), Float(0.24))
>>> i + f, i - f, i * f
(Float(124.24), Float(121.76), Float(152.52))
>>> abs(i), abs(f)
(123, 1.24)
>>> i == 123, f == Number(1.24)
(True, True)
>>> i != 123, f != Number(1.24)
(False, False)
>>> i << 3, i >> Number(3) # Bitwise operators only work with Integers
(Integer(984), Integer(15))
>>> i & 999, i | Number(999)
(Integer(99), Integer(1023))
>>> hash(i), hash(f)
(123, 1752440687002407404)
It must be noted that instances of Decimal (from Python’s built-in module decimal) can also be used as operands.