diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml
index bf53086..8f75a06 100644
--- a/.github/workflows/python-app.yml
+++ b/.github/workflows/python-app.yml
@@ -11,12 +11,14 @@ on:
jobs:
build:
-
+ name: Test on ${{ matrix.os }} with Python ${{ matrix.python-version }}
runs-on: ${{ matrix.os }}
+ continue-on-error: true
strategy:
+ fail-fast: false
matrix:
- os: [ubuntu-18.04]
- python-version: [3.6, 3.7, 3.8, 3.9]
+ os: [ubuntu-22.04]
+ python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v2
@@ -38,3 +40,4 @@ jobs:
- name: Test with pytest
run: |
pytest
+
diff --git a/.github/workflows/python-os.yml b/.github/workflows/python-os.yml
index 03f0deb..ededfd0 100644
--- a/.github/workflows/python-os.yml
+++ b/.github/workflows/python-os.yml
@@ -11,13 +11,14 @@ on:
jobs:
build:
-
+ name: Test on ${{ matrix.os }} with Python ${{ matrix.python-version }}
runs-on: ${{ matrix.os }}
+ continue-on-error: true
strategy:
+ fail-fast: false
matrix:
- os: [ubuntu-18.04, ubuntu-20.04, windows-latest, macos-latest]
- python-version: [3.6, 3.7, 3.8, 3.9]
-
+ os: [ubuntu-20.04, ubuntu-22.04, macos-latest, windows-latest]
+ python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml
index 3982790..e17275f 100644
--- a/.github/workflows/python-package.yml
+++ b/.github/workflows/python-package.yml
@@ -11,11 +11,13 @@ on:
jobs:
build:
-
- runs-on: ubuntu-18.04
+ name: Test on ubuntu-22.04 with Python ${{ matrix.python-version }}
+ runs-on: ubuntu-22.04
+ continue-on-error: true
strategy:
+ fail-fast: false
matrix:
- python-version: [3.6, 3.7, 3.8, 3.9]
+ python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v2
diff --git a/.gitignore b/.gitignore
index b50126a..6449502 100644
--- a/.gitignore
+++ b/.gitignore
@@ -143,6 +143,7 @@ results/*
# !.vscode/launch.json
# !.vscode/extensions.json
*.code-workspace
+.devcontainer
# Local History for Visual Studio Code
.history/
@@ -157,4 +158,9 @@ docs/figs/*.svg
temp.py
dev_*
+# temp
+temp/
+*.temp
+# docker
+docker/
diff --git a/_config.yml b/_config.yml
new file mode 100644
index 0000000..f5707d2
--- /dev/null
+++ b/_config.yml
@@ -0,0 +1,4 @@
+title: fxpmath
+description: A python library for fractional fixed-point (base 2) arithmetic and binary manipulation with Numpy compatibility.
+theme: jekyll-theme-slate
+future: true
\ No newline at end of file
diff --git a/changelog.txt b/changelog.txt
index a9adff8..2ad4b97 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,3 +1,15 @@
+version 0.4.9
+--------------------------------------------------
+* Fix wrap fuction over n_word_max (issue #41).
+* Inaccuracy flag is propagated to a new Fxp or resulting Fxp if one or more input Fxp are inaccurate (issue #48).
+* New `from_bin` method and function. Set value or create new Fxp from a binary string (issue #49).
+* Support to complex binary strings as input format.
+* Force to `config.op_input_size='best'` when power operation has an constant operator (non-Fxp). Add warning message. (issue #89).
+* Selection of `prefix` for binary and hexadecimal representations.
+* Fix `cumsum` function bug when dealing with sizes bigger than 32 bits (windows) / 64 bits (linux) (issue #76).
+* Fix `numpy.reshape` function handling. This function was returning optimal size instead of same by default (issue #77).
+* Fix negative number parsing in `dtype` string (issue #80).
+
version 0.4.8
--------------------------------------------------
* Fix value dtype handling for windows OS and uint as 32 bits.
diff --git a/docs/config.md b/docs/config.md
new file mode 100644
index 0000000..ff78fa7
--- /dev/null
+++ b/docs/config.md
@@ -0,0 +1,304 @@
+# Config
+
+The class `config` is a parameters set which determines the behavior of a Fxp object in several processes.
+
+Let's take a look over this class:
+
+```python
+x = Fxp(None, True, 16, 4)
+x.config.print()
+```
+
+> max_error : 1.0842021724855044e-19
+> n_word_max : 64
+> overflow : saturate
+> rounding : trunc
+> shifting : expand
+> op_method : raw
+> op_input_size : same
+> op_out : None
+> op_out_like : None
+> op_sizing : optimal
+> const_op_sizing : same
+> array_output_type : fxp
+> array_op_out : None
+> array_op_out_like : None
+> array_op_method : repr
+> dtype_notation : fxp
+> bin_prefix : None
+> hex_prefix : 0x
+
+The first 5 parameters were present in older versions, but they were move here. Note that size parameters don't live here.
+
+Following sections will explain breafly rest of parameters.
+
+# op_method
+
+This parameter defines if a operation involving its Fxp object is going to be performed using `raw` or `repr` method.
+
+The `raw` method use the `int` internal representation of data, whilst `repr` use the original type of data for the operation. The `raw` method is more accurate and emulate binary level operation, but is slower most of cases. This method is needed in cases of *extended precision*.
+
+```python
+a = Fxp([-1.0, 0.0, 1.0], True, 128, 96)
+b = Fxp([2**-64, -2**48, 2**32], True, 128, 96)
+
+c = a + b
+print(c)
+print(c-a) # equal to b
+```
+
+> [-1.0 -2147483648.0 2147483649.0]
+> [5.421010862427522e-20 -2147483648.0 2147483648.0]
+
+```python
+a.config.op_method = 'repr'
+b.config.op_method = 'repr'
+
+c = a + b
+print(c)
+print(c-a) # should be equal to b, but it doesn't
+```
+
+> [-1.0 -2147483648.0 2147483649.0]
+> [0.0 -2147483648.0 2147483648.0]
+
+Using `repr`, addition is equivalent to $c = \text{Fxp}(a() + b())$. The fist value of $c - a$ is not equal to first value of $b$ because $2^{-64}$ has been lost when it was added to $1.0$ becuase *float precision* limit.
+
+## op_input_size
+
+When an arithmetic operator is used between an Fxp and a non-Fxp object, last is going to be converted to Fxp before operation is performed. Sizing process of this non-Fxp object is specified by `op_input_size`.
+
+The values could be `'same'` (default, same size than Fxp) or `'best'` (best size according value(s) of non-Fxp).
+
+```python
+x = Fxp(2.0, True, 16, 2)
+x.config.op_input_size = 'same'
+
+z = x * 2.125
+
+z.info()
+```
+
+> dtype = fxp-s16/2
+> Value = 4.0
+
+Note that 2.125 is converted to Fxp(2.125, True, 16, 2), losing precision.
+
+```python
+x = Fxp(2.0, True, 16, 2)
+x.config.op_input_size = 'best'
+
+z = x * 2.125
+
+z.info()
+```
+
+> dtype = fxp-s16/2
+> Value = 4.25
+
+Now, the value 2.125 is converted to Fxp using the best resolution in order to represent the real value before the aritmetic operation.
+
+## op_out
+
+This can point to a specific Fxp object to store a result. By default this is `None`.
+
+If two Fxp objects are used the first will be the reference.
+
+```python
+x = Fxp(2.0, True, 16, 2)
+z = Fxp(0.0, True, 16, 4)
+
+x.config.op_out = z
+
+(x + 1).info()
+z.info()
+```
+
+> dtype = fxp-s16/4
+> Value = 3.0
+>
+> dtype = fxp-s16/4
+> Value = 3.0
+
+## op_out_like
+
+This defines the Fxp type for result. By default this is `None`.
+
+If two Fxp objects are used the first will be the reference.
+
+```python
+x = Fxp(2.0, True, 16, 2)
+x.config.op_out = Fxp(None, True, 24, 4)
+
+z = x * 3.5
+
+z.info()
+```
+
+> dtype = fxp-s24/4
+> Value = 7.0
+
+## op_sizing
+
+This defines size of Fxp returned by an operation, applied to one or two Fxp objects. The option for config this parameters are: 'optimal', 'same', 'fit', 'largest', 'smallest'. Where:
+
+- `'optimal'`: size is theorical optimal according operation and sizes of operands.
+- `'same'`: same size that firs operand.
+- `'fit'`: best size is calculated according result value(s).
+- `'largest'`: same size that largest (size) Fxp operand.
+- `'smallest'`: same size that smallest (size) Fxp operand.
+
+```python
+x = Fxp(3.5, True, 16, 4)
+y = Fxp(-1.25, True, 24, 8)
+
+for s in x.config._op_sizing_list:
+ x.config.op_sizing = s
+ print('{}:'.format(x.config.op_sizing))
+ (x + y).info()
+```
+
+optimal:
+ dtype = fxp-s25/8
+ Value = 2.25
+
+same:
+ dtype = fxp-s16/4
+ Value = 2.25
+
+fit:
+ dtype = fxp-s11/8
+ Value = 2.25
+
+largest:
+ dtype = fxp-s24/8
+ Value = 2.25
+
+smallest:
+ dtype = fxp-s16/4
+ Value = 2.25
+
+
+## const_op_sizing
+
+This defines the same behavior that `op_sizing` parameter, but when a constant is used as operand instead other Fxp object. First, constat is converted to Fxp according to `op_input_size` and then output Fxp (result) size is choosen by `const_op_sizing`.
+
+```python
+x = Fxp(3.5, True, 16, 4)
+
+for s in x.config._const_op_sizing_list:
+ x.config.const_op_sizing = s
+ print('{}:'.format(x.config.const_op_sizing))
+ (x + 2).info()
+```
+
+optimal:
+ dtype = fxp-s17/4
+ Value = 5.5
+
+same:
+ dtype = fxp-s16/4
+ Value = 5.5
+
+fit:
+ dtype = fxp-s8/4
+ Value = 5.5
+
+largest:
+ dtype = fxp-s16/4
+ Value = 5.5
+
+smallest:
+ dtype = fxp-s16/4
+ Value = 5.5
+
+
+## array_output_type
+
+This defines the type of the object get as result when use array (numpy) functions. The options are: 'fxp' (defautl, return an Fxp) or 'array' (return an numpy n-dimensional array).
+
+```python
+x = Fxp([1.0, 2.5, 3.0, 4.5], dtype='fxp-s16/4')
+x.config.array_output_type = 'fxp'
+
+z = np.sum(x)
+z.info()
+
+x.config.array_output_type = 'array'
+z = np.sum(x)
+print(z, type(z))
+```
+
+ dtype = fxp-s18/4
+ Value = 11.0
+
+11.0 <class 'numpy.ndarray'>
+
+
+## array_op_out
+
+Same as `op_output` but used with numpy functions:
+
+```python
+w = Fxp([1.0, -2.5, 3.0, -4.5], dtype='fxp-s16/4')
+z = Fxp(0.0, True, 16, 4)
+w.config.array_op_out = z
+
+y = np.sum(w)
+y.info()
+z.info()
+print(y is z)
+```
+
+ dtype = fxp-s16/4
+ Value = -3.0
+
+ dtype = fxp-s16/4
+ Value = -3.0
+
+True
+
+
+## array_op_out_like
+
+Same as `op_out_like` but used with numpy functions:
+
+```python
+w = Fxp([1.0, -2.5, 3.0, -4.5], dtype='fxp-s16/4')
+w.config.array_op_out_like = Fxp(0.0, True, 32, 8)
+
+y = np.sum(w)
+y.info()
+
+y = np.cumsum(w)
+y.info()
+```
+
+ dtype = fxp-s32/8
+ Value = -3.0
+
+ dtype = fxp-s32/8
+ Value = [ 1. -1.5 1.5 -3. ]
+
+
+## array_op_method
+
+This property defines what values are used for (numpy) arrays created from Fxp objects. If 'raw', arrays have *raw values* of Fxp object, whilst 'repr', arrays have values in original (representation) type.
+
+This parameter is used also to defined kernel op_method when array conversion is involved.
+
+```python
+w = Fxp([1.0, -2.5, 3.0, -4.5], dtype='fxp-s8/2')
+w.config.array_op_method = 'repr'
+
+w_array = np.asarray(w)
+print(w_array, type(w_array))
+
+w.config.array_op_method = 'raw'
+w_array = np.asarray(w)
+print(w_array, type(w_array))
+```
+
+[ 1. -2.5 3. -4.5] <class 'numpy.ndarray'>
+[ 4 -10 12 -18] <class 'numpy.ndarray'>
+
diff --git a/docs/install.md b/docs/install.md
new file mode 100644
index 0000000..996632f
--- /dev/null
+++ b/docs/install.md
@@ -0,0 +1,26 @@
+# install
+
+To install from *pip* just do the next:
+
+```bash
+pip install fxpmath
+```
+
+To install with *conda* just do the next:
+
+```bash
+conda install -c francof2a fxpmath
+```
+
+Or you can clone the repository doing in your console:
+
+```bash
+git clone https://github.com/francof2a/fxpmath.git
+```
+
+and then go to the fxpmath folder and install it:
+
+```bash
+cd fxpmath
+pip install .
+```
diff --git a/docs/quick_start.md b/docs/quick_start.md
new file mode 100644
index 0000000..0cdee4d
--- /dev/null
+++ b/docs/quick_start.md
@@ -0,0 +1,463 @@
+# quick start
+
+## creation
+
+Let's jump into create our new **fractional fixed-point** variable:
+
+```python
+from fxpmath import Fxp
+
+x = Fxp(-7.25) # create fxp variable with value 7.25
+x.info()
+```
+
+> dtype = fxp-s6/2
+> Value = -7.25
+
+We have created a variable of 6 bits, where 1 bit has been reserved for sign, 2 bits for fractional part, and 3 remains for integer part. Here, bit sizes had been calculated to just satisfy the value you want to save.
+
+But the most common way to create a **fxp** variable beside the its value is defining explicitly if it is signed, the number of bits for whole word and for the fractional part.
+
+**Note**: `dtype` of Fxp object is a propietary *type* of each element stored in it. The format is:
+
+**`fxp-/-{complex}`**
+
+i.e.: `fxp-s16/15`, `fxp-u8/1`, `fxp-s32/24-complex`
+
+```python
+x = Fxp(-7.25, signed=True, n_word=16, n_frac=8)
+```
+
+or just
+
+```python
+x = Fxp(-7.25, True, 16, 8)
+```
+
+Formats can also be specified using a string, either in the fxp `dtype` format,
+or by using `Qm.n` or `UQm.n` notation (or the equivalent `Sm.n`/`Um.n` notation).
+
+```python
+x = Fxp(-7.25, dtype='fxp-s16/8')
+x = Fxp(-7.25, dtype='S8.8')
+```
+
+You can print more information only changing the verbosity of *info* method.
+
+```python
+x.info(verbose=3)
+```
+
+> dtype = fxp-s16/8
+> Value = -7.25
+>
+> Signed = True
+> Word bits = 16
+> Fract bits = 8
+> Int bits = 7
+> Val data type = ``
+>
+> Upper = 127.99609375
+> Lower = -128.0
+> Precision = 0.00390625
+> Overflow = saturate
+> Rounding = trunc
+> Shifting = expand
+
+## Representations
+
+We can representate the value stored en `x` in several ways:
+
+```python
+x
+```
+
+> fxp-s16/8(-7.25)
+
+```python
+x.get_val() # return a Numpy array with the val/values in original data type representation
+x() # equivalent to x.get_val() or x.astype(self.vdtype)
+```
+
+> -7.25
+
+In different bases:
+
+```python
+x.bin()
+x.bin(frac_dot=True) # binary with fractional dot
+x.base_repr(2) # binary with sign symbol (not complement)
+x.hex()
+x.base_repr(16) # hex with sign symbol (not complement)
+```
+
+> '1111100011000000'
+> '11111000.11000000'
+> '-11101000000'
+> '0xF8C0'
+> '-740'
+
+In different types:
+
+```python
+x.astype(int)
+x.astype(float)
+x.astype(complex)
+```
+
+> -8
+> -7.25
+> (-7.25+0j)
+
+**Note** that if we do:
+
+```python
+x.val
+```
+
+we will get the fixed point value stored in memory, like an integer value. Don't use this value for calculations, but in some cases you may need it.
+
+## changing values
+
+We can change the value of the variable in several ways:
+
+```python
+x(10.75) # the simpliest way
+x.set_val(2.125) # another option
+```
+
+**DO NOT DO THIS**:
+
+```python
+x = 10.75 # wrong
+```
+
+because you are just modifying `x` type... it isn't a *Fxp* anymore, just a simple *float* right now.
+
+The same as `x.val` gives you the raw underlying value, you can set that value with
+
+```python
+x.set_val(43, raw=True)
+```
+
+## changing size
+
+If we want to resize our fxp variable we can do:
+
+```python
+x.resize(True, 8, 6) # signed=True, n_word=8, n_frac=6
+```
+
+## data types supported
+
+Fxp can handle following input data types:
+
+* int, uint
+* float
+* complex
+* list
+* ndarrays (n-dimensional numpy arrays)
+* strings (bin, hex, dec)
+* Fxp objects
+
+Here some examples:
+
+```python
+x(2)
+x(-1.75)
+x(-2.5 + 1j*0.25)
+x([1.0, 1.5, 2.0])
+x(np.random.uniform(size=(2,4)))
+x('3.5')
+x('0b11001010')
+x('0xA4')
+```
+
+## indexing
+
+If we had been save a list or array, we can use indexing just like:
+
+```python
+x[2] = 1.0 # modify the value in the index 2
+print(x[2])
+```
+
+---
+
+## arithmetic
+
+*Fxp* supports some basic math operations like:
+
+```python
+0.75 + x # add a constant
+x - 0.125 # substract a constant
+3 * x # multiply by a constant
+x / 1.5 # division by a constant
+x // 1.5 # floor division by a constant
+x % 2 # modulo
+x ** 3 # power
+```
+
+This math operations using a Fxp and a constant returns a **new Fxp** object with a precision that depends of configuration of Fxp object, `x.config` for examples above.
+
+The constant is converted into a new Fxp object before math operation, where the Fxp size for the constant operand is defined by `x.config.op_input_size` in examples above. The default value for `op_input_size` is 'best' (best enoguh precision to represent the constant value), but it could be used 'same' to force the constant's size equals to Fxp object size (x in the examples).
+
+The result of math operation is returned as a new Fxp object with a precision defined according to `x.config.const_op_sizing`. This parameter could be configured with following options: 'optimal', 'same' (default), 'fit', 'largest', 'smallest'. For math operations with constants, by default (`config.const_op_sizing = 'same'`), a Fxp with same size is returned.
+
+In all these cases we can assign the result to a (Fxp) variable, or to the same (overwritting the old Fxp object).
+
+```python
+y = 3.25 * (x - 0.5) # y is a new Fxp object
+```
+
+Math operations using **two or more Fxp** variables is also supported, returning a new Fxp object like before cases. The size of returned Fxp object depends of both Fxp operand's sizes and the `config.op_sizing` parameter of the first (left) Fxp object. By default, `config.op_sizing = 'optimal'`, so, the returned size depends also of the math operation type. For example, in the addition case, the integer size of returned Fxp is 1 bit larger than largest integer size of operands, and size of fractional part of returned Fxp is equal to largest fractional size of operands.
+
+```python
+# Fxp as operands
+x1 = Fxp(-7.25, signed=True, n_word=16, n_frac=8)
+x2 = Fxp(1.5, signed=True, n_word=16, n_frac=8)
+x3 = Fxp(-0.5, signed=True, n_word=8, n_frac=7)
+
+y = 2*x1 + x2 - 0.5 # y is a new Fxp object
+
+y = x1*x3 - 3*x2 # y is a new Fxp object, again
+```
+
+If we need to model that the result of a math operation is stored in other fractional fixed-point variable with a particular format we should do the following:
+
+```python
+# variable to store a result
+y = Fxp(None, signed=True, n_word=32, n_frac=16)
+
+y.equal(x1*x3 - 3*x2)
+```
+
+At the end, we also have the possibility of get the value of a math operation and set that val in the varible created to store the result.
+
+```python
+y.set_val( (x1*x3 - 3*x2).get_val() ) # equivalent to y.equal(x1*x3 - 3*x2), but less elegant
+y( (x1*x3 - 3*x2)() ) # just a little more elegant
+```
+
+Another example could be a sin wave function represented in Fxp:
+
+```python
+import numpy as np
+
+f = 5.0 # signal frequency
+fs = 400.0 # sampling frequency
+N = 1000 # number of samples
+
+n = Fxp( list(range(N)) ) # sample indices
+y( 0.5 * np.sin(2 * np.pi * f * n() / fs) ) # a sin wave with 5.0 Hz of frequecy sampled at 400 samples per second
+```
+
+### logical (bitwise) operators
+
+*Fxp* supports logical (bitwise) operations like *not* (*inverse*), *and*, *or*, *xor* with constants or others Fxp variables. It also supports bits *shifting* to the right and left.
+
+```python
+x & 0b1100110011110000 # Fxp var AND constant
+x & Fxp('0b11001100.11110000') # Fxp var AND other Fxp with same constant
+x & y # x AND y, both previoulsy defined
+
+~x # bits inversion
+x | y # x OR y
+x ^ y # x XOR y
+
+x << 5 # x shifted 5 bits to the left
+x >> 3 # x shifted 3 bits to the right (filled with sign bit)
+```
+
+When logical operations are performed with a constant, this constant is converted to a Fxp with de same characteristics of Fxp operand.
+
+### Comparisons
+
+*Fxp* supoorts comparison operators with constants, other variables, or another Fxp.
+
+```python
+x > 5
+x == y
+# ... and other comparison availables
+```
+
+---
+
+## behaviors
+
+Fxp has embedded some behaviors to process the value to store.
+
+## overflow / underflow
+
+A Fxp has upper and lower limits to representate a fixed point value, those limits are define by fractional format (bit sizes). When we want to store a value that is outside those limits, Fxp has an **overflow** y process the value depending the behavior configured for this situation. The options are:
+
+* *saturate* (default): the stored value is clipped to *upper* o *lower* level, as appropiate. For example, if upper limit is 15.75 and I'd want to store 18.00, the stored value will be 15.75.
+* *wrap* : the stored value is wrapped inside valid range. For example, if we have a `fxp-s7/2` the lower limit is -16.00 and the upper +15.75, and I'd want to store 18.00, the stored value will be -14.00 (18.00 is 2.00 above upper limit, so is stored 2.00 above lower limit).
+
+We can change this behavior doing:
+
+```python
+# at instantiation
+x = Fxp(3.25, True, 16, 8, overflow='saturate')
+
+# afer ...
+x.overflow = 'saturate'
+# or
+x.overflow = 'wrap'
+```
+
+If we need to know which are the *upper* and *lower* limits, Fxp have those stored inside:
+
+```python
+print(x.upper)
+print(x.lower)
+```
+
+It is important to know the Fxp doesn't raise a warning if *overflow* or *underflow* happens. The way to know that is checking field `status['overflow']` and `status['underflow']` of each Fxp.
+
+## rounding
+
+Until now we had been storing values in our Fxp that were represented without loss of precision, and that was because we defined enough amount of bit for word and fractional part. In other words, if we want to save the value -7.25, we need 1 bit for sign, at least 3 bits for integer (2^**3** = 8), and at least 2 bits for fractional (2^-**2** = 0.25). In this case our Fxp would have `fxp-s6/2` format.
+
+But, if we want to change the value of our Fxp to -7.3, the precision is not enough and Fxp will store -7.25 again. That is because Fxp is **rounding** the value before storing as a fractional fixed point value. Fxp allows different types of rounding methods:
+
+* *trunc* (default): The truncated value of the scalar (let's say `x`) will be the nearest fractional supported value which is closer to zero than `x` is. In short, the fractional part of the signed number `x` that is not supported, is discarded. Round to nearest fractional supported value towards zero.
+* *around* : Evenly round of the given value to the nearest fractional supported value, for example: 1.5 is rounded to 2.0.
+* *floor* : The floor of the scalar `x` is the largest fractional supported value `i`, such that i <= x. It is often denoted as $\lfloor x \rfloor$.
+* *ceil* : The ceil of the scalar `x` is the smallest fractional supported value `i`, such that i >= x. It is often denoted as \lceil x \rceil.
+* *fix* : Round to nearest fractional supported value towards zero.
+
+We can change this behavior doing:
+
+```python
+# at instantiation
+x = Fxp(3.25, True, 16, 8, rounding='floor')
+
+# after ...
+x.rounding = 'trunc'
+# or ...
+x.rounding = 'around'
+x.rounding = 'floor'
+x.rounding = 'ceil'
+x.rounding = 'fix'
+```
+
+If we want to know what is the **precision** of our Fxp, we can do:
+
+```python
+print(x.precision) # print the precision of x
+
+# or, in a generic way:
+print(Fxp(n_frac=7).precision) # print the precision of a fxp with 7 bits for fractional part.
+```
+
+## inaccuracy
+
+When the input value couldn't be represented exactly as a fixed-point, a **inaccuracy** flag is raised in the status of Fxp variable. You can check this flag to know if you are carrying a precision error.
+
+## Status flags
+
+*Fxp* have **status flags** to show that some events have occured inside the variable. The status flags are:
+
+* overflow
+* underflow
+* inaccuracy
+
+Those can be checked using:
+
+```python
+x.get_status() # returns a dictionary with the flags
+
+# or
+x.get_status(format=str) # return a string with flags RAISED only
+```
+
+The method **reset** can be call to reset status flags raised.
+
+```python
+x.reset()
+```
+
+---
+
+## copy
+
+We can copy a Fxp just like:
+
+```python
+y = x.copy() # copy also the value stored
+# or
+y = x.deepcopy()
+
+# if you want to preserve a value previously stored in `y` and only copy the properties from `x`:
+y = y.like(x)
+```
+
+This prevent to redefine once and once again a Fxp object with same properties. If we want to modify the value en same line, we can do:
+
+```python
+y = x.copy()(-1.25) # where -1.25 y the new value for `y` after copying `x`. It isn't necessary the `y` exists previously.
+# or
+y = Fxp(-1.25).like(x)
+# or
+y = Fxp(-1.25, like=x)
+
+# be careful with:
+y = y(-1.25).like(x) # value -1.25 could be modify by overflow or rounding before considerating `x` properties.
+y = y.like(x)(-1.25) # better!
+```
+
+It is a good idea create Fxp objects like **template**:
+
+```python
+# Fxp like templates
+DATA = Fxp(None, True, 24, 15)
+ADDERS = Fxp(None, True, 40, 16)
+MULTIPLIERS = Fxp(None, True, 24, 8)
+CONSTANTS = Fxp(None, True, 8, 4)
+
+# init
+x1 = Fxp(-3.2).like(DATA)
+x2 = Fxp(25.5).like(DATA)
+c = Fxp(2.65).like(CONSTANTS)
+m = Fxp().like(MULTIPLIERS)
+y = Fxp().like(ADDERS)
+
+# do the calc!
+m.equal(c*x2)
+y.equal(x1 + m)
+
+```
+
+## Scaling
+
+*Fxp* implements an alternative way to input data and represent it, as an linear transformation through *scale* and *bias*. In this way, the raw fracitonal value stored in Fxp variable is "scaled down" during input and "scaled up" during output or operations.
+
+It allows to use less bits to represent numbers in a huge range and/or offset.
+
+For example, suppose that the set of numbers to represent are in [10000, 12000] range, and the precision needed is 0.5. We have 4000 numbers to represent, at least. Using scaling we can avoid to represent 12000 number or more. So, we only need 12 bits (4096) values.
+
+```python
+x = Fxp(10128.5, signed=False, n_word=12, scale=1, bias=10000)
+
+x.info(3)
+```
+
+> dtype = fxp-u12/1
+> Value = 10128.5
+> Scaling = 1 * val + 10000
+>
+> Signed = False
+> Word bits = 12
+> Fract bits = 1
+> Int bits = 11
+> Val data type = ``
+>
+> Upper = 12047.5
+> Lower = 10000.0
+> Precision = 0.5
+> Overflow = saturate
+> Rounding = trunc
+> Shifting = expand
+
+Note that *upper* and *lower* limits are correct, and that the *precision* is what we needed.
diff --git a/examples/rounding_methods.ipynb b/examples/rounding_methods.ipynb
new file mode 100755
index 0000000..7347e2e
--- /dev/null
+++ b/examples/rounding_methods.ipynb
@@ -0,0 +1,456 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 175,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "from fxpmath import Fxp"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 176,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\tdtype\t\t=\tfxp-s3/2\n",
+ "\tValue\t\t=\t0.0\n",
+ "\n",
+ "\tSigned\t\t=\tTrue\n",
+ "\tWord bits\t=\t3\n",
+ "\tFract bits\t=\t2\n",
+ "\tInt bits\t=\t0\n",
+ "\tVal data type\t=\t\n",
+ "\n",
+ "\tUpper\t\t=\t0.75\n",
+ "\tLower\t\t=\t-1.0\n",
+ "\tPrecision\t=\t0.25\n",
+ "\tOverflow\t=\tsaturate\n",
+ "\tRounding\t=\ttrunc\n",
+ "\tShifting\t=\texpand\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "n_frac = 2\n",
+ "n_int = 0\n",
+ "n_word = n_int + n_frac\n",
+ "overflow = 'saturate'\n",
+ "\n",
+ "fxp_ref = Fxp(None, signed=True, n_int=n_int, n_frac=n_frac, overflow=overflow)\n",
+ "\n",
+ "fxp_ref.info(3)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 177,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[-1.25 -1.1875 -1.125 -1.0625 -1. -0.9375 -0.875 -0.8125 -0.75\n",
+ " -0.6875 -0.625 -0.5625 -0.5 -0.4375 -0.375 -0.3125 -0.25 -0.1875\n",
+ " -0.125 -0.0625 0. 0.0625 0.125 0.1875 0.25 0.3125 0.375\n",
+ " 0.4375 0.5 0.5625 0.625 0.6875 0.75 0.8125 0.875 0.9375]\n"
+ ]
+ }
+ ],
+ "source": [
+ "ratio = 4\n",
+ "float_precision = fxp_ref.precision / ratio\n",
+ "x = np.arange(fxp_ref.lower - (ratio*float_precision), fxp_ref.upper + ratio*float_precision, step=float_precision)\n",
+ "print(x)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## around"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 178,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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dJuBRN9P9T3tc9/TPvet2u5vX50lng50Kfe4M7DfR9v2uldeeYVPP/2UZ5555pz7iI+P54cffvBiVSIiUp/5KrA/BG4xbnFArrX2rOnwupKUlsPL3+4iKS2n1n3dddddJCcnc+2115KTc6q/tLQ0xo0bx4UXXsi4cePYs2cPAB999BEjRoxg8ODBXHbZZRw8eJDU1FReffVV/va3vzFo0CCWL19e67pERKR+89bXuhYBY4G2xph04AkgDMBa+yrwKe6vdO3C/bWu6d7Y7h8+2sLW/UerbJNXWML2jDxcFhwG+raPJDKi8q8r9e/YnCeuOb/S11999VU+//xzvv32Wz7++OOTz//mN7/hlltu4dZbb2XevHnce++9vP/++4waNYrExESMMcyZM4fnnnuOv/71r9x11100a9aM3/72tzX/xUVEpMHxSmBbaydV87oF7vbGtmrqaGEprrKj5S7rflxVYJ+rFStW8N577wEwdepUHnroIcD9NbSbbrqJAwcOUFxcrK9KiYjIOQnoi39Up6qR8AlJaTlMmZNISamLsFAHL04czNBureq8thNfO7vnnnt44IEHuPbaa4mPj+fJJ5+s822LiEj9U++XJh3arRUL74jjgSv6sPCOuDoL64suuojFixcDsHDhQkaNGgVAbm4unTp1AuD1118/2T4yMtLnX9USEZHgVe8DG9yhffelvep0ZP3SSy8xf/58LrzwQt58801efPFFAJ588kluuOEGRo8eTdu2bU+2v+aaa1i6dKlOOhMREY8E9ZS4v6SmpgIwbdo0pk2bBriv3f3NN9+c1fa6667juuuuO+v58847j40bN9ZlmSIiUo8osEVERM7BJxv3k5pdQFyPtj45N0qBLSIiUkOv/5DKEx9uwQCNwnbV6TlSJzSIY9giIiLesnznIf748VbAvcZ2SamLxOTsOt+uAltERMRD327P5PbX19CpZWMahToIMRAW6iCuR5s637amxEVERDzw3y0Z3P32Wvq0j+TN20aQnFVAYnI2cT3a6Bi2iIhIIPhk4wHuW7yOCzq14PXbhtOicRhDm4b7JKhP0JT4OXjppZfo168fU6ZM8XcptRYTE0NWVpa/yxARCVgfrN/HPYvWMqhLS9683R3W/tAwAjsvA+aPh7yDXunuxOU1Fy5c6JX+qmKtxeVy1fl2RETkbP9JSud/lqxnePfW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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "rounding = 'around'\n",
+ "fxp_var = Fxp(x, rounding=rounding, like=fxp_ref)\n",
+ "\n",
+ "plt.figure(figsize=(8,8))\n",
+ "plt.plot(x, x, marker='.', label='float')\n",
+ "plt.plot(x, fxp_var, marker='*', label=f'fxp {rounding}')\n",
+ "plt.grid()\n",
+ "plt.title(f'{rounding} rounding')\n",
+ "plt.legend()\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## ceil"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 179,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAewAAAHiCAYAAAAqIP8QAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAABN9klEQVR4nO3deXhU1eH/8feZrOyrYReCAorKYgIEBcWqrVqtta2KgCwiaGvVr7a1WrtYf7ZVa7Vaq5TdhcWl4i7WLSQqCRD2fckkELZANhLIPuf3x0QECckks2Umn9fz5JntzDlnLkM+Oefee66x1iIiIiJNmyPYHRAREZH6KbBFRERCgAJbREQkBCiwRUREQoACW0REJAQosEVEREKAAlskBBljSowxfWvuzzfGPBbsPtXGGJNljLmi5v7vjDGzg90nkVAVGewOiEjDWWtbB7sPDWWt/Wuw+yASyjTCFmlGjDH6I10kRCmwRYLIGNPLGPOWMeaQMSbPGPP8Ca/dZozZYowpMMZ8bIzpfcJr1hhztgf1TzbGfGWMecYYkw88YoxpZ4x5uabNbGPM740xjpryjxhjXj3h/X1q2oqseZxsjPl/NXUWG2P+Z4zpfEL5W2vqzDPGPPydvhyv+4R6JxljdhtjDp9Y3hjTwhjzUs1n32KMecAYk9OojSwSJhTYIkFijIkA3geygT5AD2BxzWs/Bn4H/AQ4A0gFFjWyqRFAJhAH/AX4F9AO6AtcCkwEpjSgvnE15eOAaODXNX0eCLwI3Ap0BzoBPeupaxQwALgc+KMx5tya5/+Ee5v0Ba4EJjSgfyJhSYEtEjzDcQfbb6y1R621ZdbaL2teuwP4m7V2i7W2CvgrMOTEUXYD7LPW/qumngrgZuAha22xtTYL+AfukPXUPGvtdmttKfA6MKTm+Z8B71trU6y15cAfAFc9df3ZWltqrV0HrAMG1zx/E/BXa22BtTYHeK4B/RMJSwpskeDpBWTXBOl39QaeNcYUGmMKgXzA4B6FN9SeE+53xj0qzj7huewG1nvghPvHgG8OgOt+YlvW2qNAni/q+s59kWZJgS0SPHuAM09zINge4A5rbfsTflpYa79uRDsnXpLvMFCJ+w+Cb5wJ7K25fxRoecJrXRvQzn7cf4QAYIxpiXtavDH2c/J0eq/TFRRpLhTYIsGzAncwPW6MaWWMiTXGXFzz2gzgIWPMeQA1B4rd6G2D1tpq3NPYfzHGtKmZYr8f+OZAs7XAJcaYM40x7YCHGlD9m8C1xphRxpho4FEa/zvmddyfv4Mxpgfwy0bWIxI2FNgiQVITntcBZwO7gRzc+5ex1i4BngAWG2OOABuBq33U9N24R9KZwJfAQmBuTbufAK8B64EM3AfFecRauwm4q6a+/UAB7s/UGI/WvNcJfIr7j4HyRtYlEhaMtbb+UiIiQWSM+Tkw1lp7abD7IhIsGmGLSJNjjOlmjLnYGOMwxgwAfgUsCXa/RIJJqx6JSFMUDfwHiAcKcZ+f/kIwOyQSbJoSFxERCQGaEhcREQkBCmwREZEQ0KT3YXfu3Nn26dMn2N0IuqNHj9KqVatgd6NZ0TYPPG3zwNM2DyxPtndGRsZha+0Ztb3WpAO7T58+rFq1KtjdCLrk5GTGjBkT7G40K9rmgadtHnja5oHlyfY2xmSf7jVNiYuIiIQABbaIiEgIUGCLiIiEAJ/swzbGzAWuBXKttefX8roBngWuwX0JvcnW2tWNaauyspKcnBzKysq86XJIadeuHVu2bKm3XGxsLD179iQqKioAvRIRkUDy1UFn84HngZdP8/rVQL+anxHAizW3DZaTk0ObNm3o06cP7r8Dwl9xcTFt2rSps4y1lry8PHJycoiPjw9Qz0REJFB8MiVurU0B8usocj3wsnVLA9obY7o1pq2ysjI6derUbMLaU8YYOnXq1KxmHkREmpNAndbVA9hzwuOcmuf2f7egMWY6MB2gS5cuJCcnn/R6u3btKCkp8VtHm6Lq6mqKi4s9KltWVnbKNpOGKykp0XYMMG3zwNM2Dyxvt3egAru24XCti5hba2cCMwESExPtd89Z27JlS73Tw/723HPP8eKLL3LkyBFuuOEGnn/++QbXkZycTHR0NBdddFG9ZT2ZEv9GbGwsQ4cObXB/5GQ6PzXwtM0DT9s8sLzd3oE6SjwH6HXC457AvgC17XMvvPACH374IX/5y18aXUdycjJff/21D3slIiLhLFCB/S4w0bglAUXW2lOmw/0lI7uAf3+xk4zsAq/ruvPOO8nMzORHP/oRBQXf1pednc3ll1/OoEGDuPzyy9m9ezcA7733HiNGjGDo0KFcccUVHDx4kKysLGbMmMEzzzzDkCFDSE1N9bpfIiIS3nx1WtciYAzQ2RiTA/wJiAKw1s4APsR9StdO3Kd1TfFFu39+bxOb9x2ps0xxWSVbDxTjsuAwcE7XNrSJPf1pTwO7t+VP15132tdnzJjB0qVL+eKLL3j//fePP//LX/6SiRMnMmnSJObOncs999zD22+/zahRo0hLS8MYw+zZs3nyySf5xz/+wZ133knr1q359a9/3fAPLiIizY5PAttae0s9r1vgLl+01VBHyqpw1ewtd1n347oCu7GWL1/OW2+9BcCtt97KAw88ALhPQ7v55pvZv38/FRUVOuVKREQapUlf/KM+dY2Ev5GRXcD42WlUVrmIinTw7NihJPTu4Pe+fXPa2d13383999/Pj370I5KTk3nkkUf83raIiISfsF+aNKF3BxbcnsT93x/AgtuT/BbWF110EYsXLwZgwYIFjBo1CoCioiJ69OgBwEsvvXS8fJs2bTw+VUtERCTsAxvcoX3XZWf7dWT93HPPMW/ePAYNGsQrr7zCs88+C8AjjzzCjTfeyOjRo+ncufPx8tdddx1LlizRQWciIuKRkJ4SD5asrCwAJk+ezOTJkwH3tbs///zzU8pef/31XH/99ac8379/f9avX+/PboqISBhRYIuIiDTCB+v3kZV3lKS+nQNybJQCW0REpIFe+jqLP727CQPERO306zFS32gW+7BFRER8JXXHIf7f+5sB9xrblVUu0jLz/N6uAltERMRDX2zNZepLq+jRvgUxkQ4iDERFOkjq28nvbWtKXERExAP/23SAuxauZkDXNrxy2wgyDx8lLTOPpL6dtA9bRESkKfhg/X7uXbyG83u046XbhtOuRRQJraIDEtTf0JR4Izz33HOce+65jB8/PqDtzpgxg5dffhlwn1L25ptvBrR9EZHm6J21e7l70WqG9GrPK1PdYR0MzWOEXXwA3pwCP5sPbbp4Xd0LL7zARx99FPB1we+8886Atici0ty9mZHDb95cx4j4jsyZNIxWMcGLzeYxwl72JOxOg2VPeF3ViZfXfOaZZ7jnnnt49NFHAfj444+55JJLcLlcTJ48mTvvvJPRo0fTv3//k67sdaInn3ySCy64gMGDB/Pggw8CsGvXLq666ioSEhIYPXo027dvB9yrpj311FNefwYREanfohW7+c2b6xh1dmfmTR4e1LCGUB9hf/QgHNhw+td3fwXWfvt41Rz3jzFw5sW1v6frBXD146et8sTLa3bu3Jljx44xbNgw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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "rounding = 'ceil'\n",
+ "fxp_var = Fxp(x, rounding=rounding, like=fxp_ref)\n",
+ "\n",
+ "plt.figure(figsize=(8,8))\n",
+ "plt.plot(x, x, marker='.', label='float')\n",
+ "plt.plot(x, fxp_var, marker='*', label=f'fxp {rounding}')\n",
+ "plt.grid()\n",
+ "plt.title(f'{rounding} rounding')\n",
+ "plt.legend()\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## floor"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 180,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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nj3ceOONZGf/WF9KSgqXX345AwYM4PLLL2fv3r0AfPTRR4wYMYLBgwdzxRVXcPDgQZKTk3nttdf45z//yaBBg1ixYkWt+yUiIvWbr27rWgSMBtoYY1KBPwIRANba14AleG7p2oXntq7Jvmj3qY+2sDXtyBnL5BWVsj09D7cFh4Fz2jWjWXTltzj169CcP95wbqXbX3vtNT777DO++eYbPv744+Ov//rXv2bixInccccdzJ49m/vvv5/333+fiy66iISEBIwxzJw5k+eee45//OMf3HPPPTRt2pTf/va31X/jIiLS4PgksK21Y6vYboF7fdFWdR0pKsNdfrbcbT3PzxTYNbVy5UreffddACZMmMDDDz8MeG5Du+222zhw4AAlJSW6vUpERGqkTn/5R1XONBI+Jiklm9tnJlBa5iYi3MG/xwxmaNdWfu/bsdvO7rvvPh588EFuvPFGli1bxpNPPun3tkVEpP6p90uTDu3aigVT4njwqj4smBLnt7C+4IILWLx4MQALFizgoosuAiA3N5eOHTsCMG/evOPlmzVrVqtbtUREpGGp94ENntC+99Kefh1Zv/jii8yZM4cBAwYwf/58/v3vfwPw5JNPcsstt3DxxRfTpk2b4+VvuOEG3nvvPV10JiIiXgnpKfFgSU5OBmDSpElMmjQJ8Hx399dff31a2ZtuuombbrrptNd79+7Nxo0b/dlNERGpRxTYIiIiNfDJxjSSswqI69EmINdGKbBFRESqad73yfzxwy0YICpil1+vkTqmQZzDFhER8ZUVOw/xp4+3Ap41tkvL3CTsyfJ7uwpsERERL32zPYO75q2hY8tGRIU7CDMQEe4grkdrv7etKXEREREvfLElnXsXrqVPu2bMv3MEezILSNiTRVyP1jqHLSIiUhd8svEAv1m8jv4dWzDvzuG0aBTB0CaRAQnqYxTYNXDs6zWHDBnCggULalXXQw89xJIlS7juuuto0qSJ1hcXEaljPli/nwfeWs+QLq2YM/l8vyxv7Y2GEdh56fDOZPjFXGgWW+vqXnnlFT799FOfrAv++uuvc+jQIaKiony2bGlZWRnh4Q3jP62IiD+9k5TKQ+9sYET3s5h1x/k0iQrev60N46Kz5c/B3gRY/rdaV3Xi12v+85//5P777+fpp58G4PPPP+eSSy7B7XYzadIk7rnnHi6++GJ69+590jd7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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "rounding = 'floor'\n",
+ "fxp_var = Fxp(x, rounding=rounding, like=fxp_ref)\n",
+ "\n",
+ "plt.figure(figsize=(8,8))\n",
+ "plt.plot(x, x, marker='.', label='float')\n",
+ "plt.plot(x, fxp_var, marker='*', label=f'fxp {rounding}')\n",
+ "plt.grid()\n",
+ "plt.title(f'{rounding} rounding')\n",
+ "plt.legend()\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## trunc"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 181,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "rounding = 'trunc'\n",
+ "fxp_var = Fxp(x, rounding=rounding, like=fxp_ref)\n",
+ "\n",
+ "plt.figure(figsize=(8,8))\n",
+ "plt.plot(x, x, marker='.', label='float')\n",
+ "plt.plot(x, fxp_var, marker='*', label=f'fxp {rounding}')\n",
+ "plt.grid()\n",
+ "plt.title(f'{rounding} rounding')\n",
+ "plt.legend()\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## fix"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 182,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "rounding = 'fix'\n",
+ "fxp_var = Fxp(x, rounding=rounding, like=fxp_ref)\n",
+ "\n",
+ "plt.figure(figsize=(8,8))\n",
+ "plt.plot(x, x, marker='.', label='float')\n",
+ "plt.plot(x, fxp_var, marker='*', label=f'fxp {rounding}')\n",
+ "plt.grid()\n",
+ "plt.title(f'{rounding} rounding')\n",
+ "plt.legend()\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## nearest\n",
+ "\n",
+ "Rounding to plus infinity"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 183,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAewAAAHiCAYAAAAqIP8QAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAABNPElEQVR4nO3dd3yUVb7H8c+ZVHpPkB4EKRbAIAQFxN71ursqRRREUNfVvXp3va66u67rel3Xsuuqi3QLRVfFXlZUCAoJEHovmQRCCwkBkkDazLl/TKRI+kxmMjPf9+uV15TnzHl+eRz55pynGWstIiIi0rA5Al2AiIiIVE+BLSIiEgQU2CIiIkFAgS0iIhIEFNgiIiJBQIEtIiISBBTYIkHIGFNgjOle/nyWMebpQNdUEWNMhjHm8vLnjxljpgW6JpFgFRnoAkSk9qy1TQNdQ21Za58JdA0iwUwjbJEwYozRH+kiQUqBLRJAxpjOxpgPjDEHjDG5xphXTlp2lzFmkzEmzxjzlTGm60nLrDGmRw36H2eM+cEY85Ix5iDwpDGmhTHmzfJ1ZhpjnjDGOMrbP2mMefukz3crX1dk+euFxpg/l/eZb4z5jzGm7Untx5b3mWuMefwntRzv+6R+7zTG7DTG5Jzc3hjTyBjzRvnvvskY84gxJqtOG1kkRCiwRQLEGBMBfApkAt2AjsC88mX/BTwG/AxoBywG5tZxVYOBdCAO+AvwT6AF0B24GLgDGF+L/kaXt48DooHflNfcF/gXMBboALQBOlXT11CgF3AZ8AdjTJ/y9/+IZ5t0B64Abq9FfSIhSYEtEjiD8ATbb621hdbaImvt9+XL7gH+z1q7yVpbBjwD9D95lF0Le6y1/yzvpwS4DfidtTbfWpsBvIAnZGtqprV2q7X2GPAu0L/8/V8An1prk621xcDvAXc1ff3JWnvMWrsGWAP0K3//VuAZa22etTYLeLkW9YmEJAW2SOB0BjLLg/SnugL/MMYcMsYcAg4CBs8ovLZ2nfS8LZ5RceZJ72XWst99Jz0/Cvx4AFyHk9dlrS0Ecn3R10+ei4QlBbZI4OwCulRyINgu4B5rbcuTfhpZa5fUYT0n35IvByjF8wfBj7oAu8ufFwKNT1rWvhbr2YvnjxAAjDGN8UyL18VeTp1O71xZQ5FwocAWCZxleILpWWNME2NMrDHmovJlk4HfGWPOBig/UOwWb1dorXXhmcb+izGmWfkU+8PAjwearQaGG2O6GGNaAL+rRffvAdcbY4YaY6KBp6j7vzHv4vn9WxljOgK/qmM/IiFDgS0SIOXheQPQA9gJZOHZv4y1dj7wV2CeMeYIsB64xkerfgDPSDod+B6YA8woX+/XwDvAWiANz0FxNWKt3QDcX97fXiAPz+9UF0+Vf9YJLMDzx0BxHfsSCQnGWlt9KxGRADLG3AeMtNZeHOhaRAJFI2wRaXCMMWcYYy4yxjiMMb2A/wHmB7oukUDSVY9EpCGKBl4HEoBDeM5Pfy2QBYkEmqbERUREgoCmxEVERIKAAltERCQINOh92G3btrXdunULdBkBV1hYSJMmTQJdRljRNvc/bXP/0zb3r5ps77S0tBxrbbuKljXowO7WrRsrVqwIdBkBt3DhQkaMGBHoMsKKtrn/aZv7n7a5f9VkextjMitbpilxERGRIKDAFhERCQIKbBERkSDgk33YxpgZwPVAtrX2nAqWG+AfwLV4bqE3zlq7si7rKi0tJSsri6KiIm9KDiotWrRg06ZN1baLjY2lU6dOREVF+aEqERHxJ18ddDYLeAV4s5Ll1wA9y38GA/8qf6y1rKwsmjVrRrdu3fD8HRD68vPzadasWZVtrLXk5uaSlZVFQkKCnyoTERF/8cmUuLU2GThYRZObgDetRwrQ0hhzRl3WVVRURJs2bcImrGvKGEObNm3CauZBRCSc+Ou0ro7ArpNeZ5W/t/enDY0xk4BJAPHx8SxcuPCU5S1atKCgoKDeCm2IXC4X+fn5NWpbVFR02jaT2isoKNB29DNtc//TNvcvb7e3vwK7ouFwhRcxt9ZOAaYADBw40P70nLVNmzZVOz1c315++WX+9a9/ceTIEW6++WZeeeWVWvexcOFCoqOjufDCC6ttW5Mp8R/FxsYyYMCAWtcjp9L5qf6nbe5/2ub+5e329tdR4llA55NedwL2+GndPvfaa6/x+eef85e//KXOfSxcuJAlS5b4sCoREQll/grsj4E7jEcScNhae9p0eH1Jy8zj1e+2k5aZ53Vf9957L+np6dx4443k5Z3oLzMzk8suu4zzzjuPyy67jJ07dwLwySefMHjwYAYMGMDll1/O/v37ycjIYPLkybz00kv079+fxYsXe12XiIiENl+d1jUXGAG0NcZkAX8EogCstZOBz/Gc0rUdz2ld432x3j99soGNe45U2Sa/qJTN+/JxW3AY6N2+Gc1iKz/tqW+H5vzxhrMrXT558mS+/PJLvvvuOz799NPj7//qV7/ijjvu4M4772TGjBk8+OCDfPjhhwwdOpSUlBSMMUybNo3nnnuOF154gXvvvZemTZvym9/8pva/uIiIhB2fBLa1dlQ1yy1wvy/WVVtHispwl+8td1vP66oCu66WLl3KBx98AMDYsWN55JFHAM9paLfddht79+6lpKREp1yJiEidNOibf1SnqpHwj9Iy8xgzLYXSMjdRkQ7+MXIAiV1b1XttP5529sADD/Dwww9z4403snDhQp588sl6X7eIiISekL80aWLXVsy+O4mHr+zF7LuT6i2sL7zwQubNmwfA7NmzGTp0KACHDx+mY8eOALzxxhvH2zdr1qzGp2qJiIiEfGCDJ7Tvv6RHvY6sX375ZWbOnMl5553HW2+9xT/+8Q8AnnzySW655RaGDRtG27Ztj7e/4YYbmD9/vg46ExGRGgnqKfFAycjIAGDcuHGMGzcO8Ny7+9tvvz2t7U033cRNN9102vtnnXUWa9eurc8yRUQkhCiwRURE6uCztXvIyC0kqXtbvxwbpcAWERGppTeWZPDHjzdggJio7fV6jNSPwmIftoiIiK8s3naAP3+6EfBcY7u0zE1Kem69r1eBLSIiUkPfbc5mwhsr6NiyETGRDiIMREU6SOrept7XrSlxERGRGvjPhn3cP2clvdo34627BpOeU0hKei5J3dtoH7aIiEhD8Nnavfx63irO6diCN+4aRItGUSQ2ifZLUP9IU+J18PLLL9OnTx/GjBnj1/VOnjyZN998E/CcUvbee+/5df0iIuHoo9W7eWDuSvp3bslbEzxhHQjhMcLO3wfvjYdfzIJm8V5399prr/HFF1/4/brg9957r1/XJyIS7t5Ly+K3761hcEJrpt95AU1iAheb4THCXvQc7EyBRX/1uquTb6/50ksv8eCDD/LUU08B8NVXXzF8+HDcbjfjxo3j3nvvZdiwYZx11lmn3NnrZM899xznnnsu/fr149FHHwVgx44dXH311SQmJjJs2DC2bt0KeK6a9vzzz3v9O4iISPXmLtvJb99bw9AebZk5blBAwxqCfYT9xaOwb13ly3f+ANaeeL1iuufHGOhyUcWfaX8uXPNspV2efHvNtm3bcvToUS644AKG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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "rounding = 'ceil'\n",
+ "fxp_var = Fxp(x-2**(-2*n_frac), rounding=rounding, like=fxp_ref)\n",
+ "\n",
+ "plt.figure(figsize=(8,8))\n",
+ "plt.plot(x, x, marker='.', label='float')\n",
+ "plt.plot(x, fxp_var, marker='*', label=f'fxp {rounding}')\n",
+ "plt.grid()\n",
+ "plt.title(f'{rounding} rounding')\n",
+ "plt.legend()\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Rounding to zero"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 184,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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PvroI4YNG8bgwYO56qqrOHToEKmpqUybNo2XXnqJQYMGsXz58lrXJSIiDZuvfta1EBgJtDXGpANPAeEA1tppwBI8P+naiednXRN98b5//GgzW/Yfq7RNbkEx2w7m4rbgMNC3fRRRkRX/pKlfx+Y8ddP5FT4/bdo0PvvsM77++ms+/vjjU48/8MAD3HXXXdx9993Mnj2bhx56iPfff59LLrmEpKQkjDHMnDmT559/nr///e/cd999NGvWjF//+tfV/+AiIhJyfBLY1toxVTxvgft98V7VdaygBHfp3nK39dyvLLBrasWKFbz33nsAjB8/nsceewzw/Aztjjvu4MCBAxQVFennVCIiUiP1+uQfValsJHxSclo242YmUVziJjzMwT9HDya2W6s6r+3kz84efPBBfvWrX3HzzTeTkJDA008/XefvLSIiDU+DX5o0tlsr5k+O51fX9GH+5Pg6C+uLLrqIRYsWATB//nwuueQSAHJycujUqRMA8+bNO9U+KirKpz/VEhGRhq3BBzZ4Qvv+y3vV6cj65ZdfZs6cOQwYMIA333yTf/7znwA8/fTT3HbbbYwYMYK2bduean/TTTexePFiHXQmIiJeCeop8UBJTU0FYMKECUyYMAHwnLv7q6++OqvtLbfcwi233HLW4+eeey4bNmyoyzJFRKQBUWCLiIjUwCcb9pOalU98z7Z+OTZKgS0iIlJN875L5akPN2OARuE76/QYqZNCYh+2iIiIryzfcZg/fbwF8KyxXVziJml3Vp2/rwJbRETES19vy2DSvDV0atmYRmEOnAbCwxzE92xT5++tKXEREREv/HfzQe5fsJY+7aN4855h7M7MJ2l3FvE922gftoiISH3wyYYDPLzoey7o1IJ59wylReNwYptG+CWoT9KUeA28/PLLnHfeeYwbN65W/aSmprJgwQIfVSUiInXhg3X7eHDhWgZ1acmbkzxhHQihEdi5B2HOKMg95JPuTp5ec/78+bXqp7LALikpqVXfIiJSe/9JTud/3l7H0B6tmXfP0Do5F4W3QiOwlz0Pe5Jg2d9q3VXZ02u+9NJLPPTQQzzzzDMAfP7551x66aW43W4mTJjAfffdx4gRIzj33HPPOLPXSY8//jjLly9n0KBBvPTSS8ydO5fbbruNm266iWuuuYaEhARuvPHGU+0feOAB5s6dC3gWannqqacYMmQI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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "rounding = 'trunc'\n",
+ "fxp_var = Fxp(x + np.sign(x)*2**(-2*n_frac), rounding=rounding, like=fxp_ref)\n",
+ "\n",
+ "plt.figure(figsize=(8,8))\n",
+ "plt.plot(x, x, marker='.', label='float')\n",
+ "plt.plot(x, fxp_var, marker='*', label=f'fxp {rounding}')\n",
+ "plt.grid()\n",
+ "plt.title(f'{rounding} rounding')\n",
+ "plt.legend()\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Rounding to infinity"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 185,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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kiWMHj2a4cOHc9lll3HgwAFSU1OZPn06L774IsOGDWP58uV1rktEREKbr07rWgiMBdobY9KBJ4AIAGvtdOATPKd07cJzWtdkX3zuH5dsYWvGkSrb5BeVsj0zH7cFh4GBHaOJjqr8lKbBnVvyxPVnVfr69OnT+eyzz/jmm2/46KOPTjz/y1/+kjvuuIM777yTOXPm8MADD/D+++9zwQUXkJSUhDGGWbNm8eyzz/L8889z77330qJFC37961/X/IuLiEij45PAttbeVs3rFrjPF59VU0eKynCX7y13W8/jqgK7tlasWMF7770HwMSJE3n44YcBz2lot956K/v376ekpESnU4mISK006It/VKeqkfBxyWm5TJiVRGmZm4hwB/8cN5yRPdrUe23HTzu7//77eeihh7jhhhtISEjgySefrPfPFhGR0BPyS5OO7NGG+VPjeeiKAcyfGl9vYX3eeeexaNEiAObPn88FF1wAQF5eHl26dAHgtddeO9E+Ojrap6dqiYhIaAv5wAZPaN93Sd96HVm/9NJLzJ07lyFDhvDGG2/wz3/+E4Ann3ySm2++mQsvvJD27dufaH/99dezePFiHXQmIiJeCeop8UBJTU0FYNKkSUyaNAnwXLv766+/PqPtjTfeyI033njG8/3792fjxo31WaaIiIQQBbaIiEgtfLwxg9ScQuJ7t/fLsVEKbBERkRp67btUnvhwCwZoErGrXo+ROq5R7MMWERHxleU7D/Knj7YCnjW2S8vcJKXk1PvnKrBFRES89M32LKa8toYurZvSJNxBmIGIcAfxvdvV+2drSlxERMQLX2zJ5L4FaxnQMZo37hpNSnYhSSk5xPdup33YIiIiDcHHG/fzq0XrOLtLK167axStmkYwsnmkX4L6OE2J18JLL73EoEGDmDBhQp36SU1NZcGCBT6qSkRE6sMH6/dx/8K1DOvWmjemeMI6EBpHYOdnwtyrIf+AT7o7fnnN+fPn16mfqgK7rKysTn2LiEjdvZOczv+9tZ5Rvdry2l2j6uVaFN5qHIG97FnYkwTL/lbnrk6+vOaLL77IAw88wFNPPQXA559/zkUXXYTb7WbSpEnce++9XHjhhfTv3/+UK3sd98gjj7B8+XKGDRvGiy++yLx587j55pu5/vrrueKKK0hISOC666470f6Xv/wl8+bNAzwLtTzxxBOMGDGCc845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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "rounding = 'trunc'\n",
+ "fxp_var = Fxp(x + 2*np.sign(x)*2**(-2*n_frac), rounding=rounding, like=fxp_ref)\n",
+ "\n",
+ "plt.figure(figsize=(8,8))\n",
+ "plt.plot(x, x, marker='.', label='float')\n",
+ "plt.plot(x, fxp_var, marker='*', label=f'fxp {rounding}')\n",
+ "plt.grid()\n",
+ "plt.title(f'{rounding} rounding')\n",
+ "plt.legend()\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Rounding to minus infinity"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 186,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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wo033khOznf9paWlcfnll3PhhRdy+eWXc+DAAQDee+89xo4dy4gRI7jiiis4evQoqampvPDCC/ztb39j+PDhrFmzpsF1iYhI0+ary7pWAJOAzsaYdOC3QASAtfYFYBWeS7r24bmsa7Yv1vu793by9eETNbbJLypld0Y+bgsOA+fERhMdVf0lTkO7t+W33zuv2uUvvPACH330Ef/97395//33T7/+05/+lBkzZjBz5kwWLVrEAw88wNtvv83FF19MUlISxhgWLFjAU089xV//+lfuvfde2rRpw89//vO6f3AREWl2fBLY1toptSy3wH2+WFddnSgqw11+tNxtPc9rCuz6Wrt2LW+++SYA06dP55FHHgE8l6HddtttHDlyhJKSEl1eJSIi9RLUN/+oTU17wt9KTsth2oIkSsvcRIQ7+MfkEYzq06HRa/v2srP777+fn/3sZ9x4440kJCTw+OOPN/q6RUSk6WnyU5OO6tOB5XfF87OrhrD8rvhGC+vx48ezcuVKAJYvX87FF18MQF5eHj169ABg6dKlp9tHR0c36FItERFpXpp8YIMntO+7dGCj7lk/88wzLF68mAsvvJBly5bxj3/8A4DHH3+cW265hQkTJtC5c+fT7b/3ve/x1ltv6aQzERHxSkgPiQdKamoqALNmzWLWrFmA597dn3/+eaW2N910EzfddFOl1wcPHsy2bdsas0wREWlCFNgiIiL18MG2w6RmFxLfv7Nfzo1SYIuIiNTR0q9S+e27OzFAi4h9jXqO1LeaxTFsERERX1mz9xi/f/9rwDPHdmmZm6SU7EZfrwJbRETES//dncmdSzfSo31LWoQ7CDMQEe4gvn+nRl+3hsRFRES88J+dGdz3yiaGxEaz7I6xpGQVkpSSTXz/TjqGLSIiEgw+2HaEB1du5vwe7Vh6xxjatYxgVOtIvwT1txTY9fDt7TVHjhzJ8uXLG9TXww8/zKpVq7juuuto3bq15hcXEQky72w5xEOvbmFk7w4snj26Uaa39kbzCOz8DHh9NvxoCUTHNLi7559/ng8//NAn84K/+OKLHDt2jBYtWvhs2tKysjLCw5vHf1oRkcb0enI6D7++lbH9OrJw5mhatwjcv63N46Sz1U/BgSRY/ecGd1Xx9pp/+9vfeOCBB5g7dy4AH3/8MZdccglut5tZs2Zx7733MmHCBAYPHnzGnb2+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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "rounding = 'floor'\n",
+ "fxp_var = Fxp(x+2**(-2*n_frac), rounding=rounding, like=fxp_ref)\n",
+ "\n",
+ "plt.figure(figsize=(8,8))\n",
+ "plt.plot(x, x, marker='.', label='float')\n",
+ "plt.plot(x, fxp_var, marker='*', label=f'fxp {rounding}')\n",
+ "plt.grid()\n",
+ "plt.title(f'{rounding} rounding')\n",
+ "plt.legend()\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3.8.13 ('dev')",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.13"
+ },
+ "orig_nbformat": 4,
+ "vscode": {
+ "interpreter": {
+ "hash": "e1489a44d9d2cc8502fc38ac3fffdaa99c0b3f818da830c696c3587ea31e036b"
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/fxpmath/__init__.py b/fxpmath/__init__.py
index fbe5a84..34872e7 100644
--- a/fxpmath/__init__.py
+++ b/fxpmath/__init__.py
@@ -1,4 +1,4 @@
-__version__ = '0.4.8'
+__version__ = '0.4.9'
import sys
import os
@@ -58,6 +58,7 @@
from .functions import (
fxp_like,
fxp_sum,
+ from_bin,
fxp_max,
fxp_min,
add,
@@ -78,5 +79,6 @@
trace,
prod,
dot,
- nonzero
+ nonzero,
+ reshape
)
diff --git a/fxpmath/functions.py b/fxpmath/functions.py
index c95c1f7..3fd98d4 100644
--- a/fxpmath/functions.py
+++ b/fxpmath/functions.py
@@ -129,6 +129,10 @@ def _function_over_one_var(repr_func, raw_func, x, out=None, out_like=None, sizi
else:
z = Fxp(val, signed=signed, n_int=n_int, n_frac=n_frac, like=out_like, raw=raw)
+ # propagate inaccuracy from argument
+ if x.status['inaccuracy']:
+ z.status['inaccuracy'] = True
+
return z
def _function_over_two_vars(repr_func, raw_func, x, y, out=None, out_like=None, sizing='optimal', method='raw', optimal_size=None, **kwargs):
@@ -177,6 +181,10 @@ def _function_over_two_vars(repr_func, raw_func, x, y, out=None, out_like=None,
else:
z = Fxp(val, signed=signed, n_int=n_int, n_frac=n_frac, like=out_like, raw=raw, config=config)
+ # propagate inaccuracy from arguments
+ if x.status['inaccuracy'] or y.status['inaccuracy']:
+ z.status['inaccuracy'] = True
+
return z
def fxp_like(x, val=None):
@@ -264,7 +272,7 @@ def fxp_sum(x, sizes='best_sizes', axis=None, dtype=None, out=None, vdtype=None)
raise TypeError('out argument must be a Fxp object!')
elif sizes == 'best_sizes':
signed = x.signed
- n_word = np.ceil(np.log2(x().size)).astype(int) + x.n_word
+ n_word = int(np.ceil(np.log2(x().size))) + x.n_word
n_frac = x.n_frac
sum_along_axis = Fxp(x_sum, signed=signed, n_word=n_word, n_frac=n_frac)
@@ -277,6 +285,9 @@ def fxp_sum(x, sizes='best_sizes', axis=None, dtype=None, out=None, vdtype=None)
return sum_along_axis
+def from_bin(x, **kwargs):
+ return Fxp(utils.add_binary_prefix(x), **kwargs)
+
@implements(np.max)
def fxp_max(x, axis=None, out=None, out_like=None, sizing='optimal', method='raw', **kwargs):
"""
@@ -543,7 +554,7 @@ def _sum_raw(x, n_frac, **kwargs):
x = Fxp(x)
signed = x.signed
- n_word = np.ceil(np.log2(x.size)).astype(int) + x.n_word
+ n_word = int(np.ceil(np.log2(x.size))) + x.n_word
n_frac = x.n_frac
n_int = n_word - int(signed) - n_frac
optimal_size = (signed, n_word, n_int, n_frac)
@@ -563,7 +574,7 @@ def _cumsum_raw(x, n_frac, **kwargs):
x = Fxp(x)
signed = x.signed
- n_word = np.ceil(np.log2(x.size)).astype(int) + x.n_word
+ n_word = int(np.ceil(np.log2(x.size))) + x.n_word
n_frac = x.n_frac
n_int = n_word - int(signed) - n_frac
optimal_size = (signed, n_word, n_int, n_frac)
@@ -672,7 +683,7 @@ def _trace_raw(x, n_frac, **kwargs):
num_of_additions = np.diagonal(np.array(a), offset=offset, axis1=axis1, axis2=axis2).size
signed = a.signed
- n_word = np.ceil(np.log2(num_of_additions)).astype(int) + a.n_word
+ n_word = int(np.ceil(np.log2(num_of_additions))) + a.n_word
n_frac = a.n_frac
n_int = n_word - int(signed) - n_frac
optimal_size = (signed, n_word, n_int, n_frac)
@@ -720,7 +731,7 @@ def _dot_raw(x, y, n_frac, **kwargs):
num_of_additions = x.shape[-1]
signed = x.signed or y.signed
n_frac = x.n_frac + y.n_frac
- n_word = np.ceil(np.log2(num_of_additions)).astype(int) + x.n_word + y.n_word
+ n_word = int(np.ceil(np.log2(num_of_additions))) + x.n_word + y.n_word
n_int = n_word - int(signed) - n_frac
optimal_size = (signed, n_word, n_int, n_frac)
@@ -735,4 +746,15 @@ def nonzero(x):
if x.scaled:
return np.nonzero(x.get_val())
else:
- return np.nonzero(x.val)
\ No newline at end of file
+ return np.nonzero(x.val)
+
+@implements(np.reshape)
+def reshape(a, newshape, order='C', out=None, out_like=None, sizing='same', method='raw', **kwargs):
+ """
+ """
+ def _reshape_raw(x, newshape, order, **kwargs):
+ return np.reshape(x.val, newshape=newshape, order=order)
+
+ kwargs['newshape'] = newshape
+ kwargs['order'] = order
+ return _function_over_one_var(repr_func=np.reshape, raw_func=_reshape_raw, x=a, out=out, out_like=out_like, sizing=sizing, method=method, optimal_size=None, **kwargs)
diff --git a/fxpmath/objects.py b/fxpmath/objects.py
index 723955e..e560a29 100644
--- a/fxpmath/objects.py
+++ b/fxpmath/objects.py
@@ -315,12 +315,15 @@ def get_dtype(self, notation=None):
self._update_dtype(notation) # update dtype
return self._dtype
- _qfmt = re.compile(r'(s|u|q|uq|qu)(\d+)(\.\d+)?')
- _fxpfmt = re.compile(r'fxp-(s|u)(\d+)/(\d+)(-complex)?')
+ def _qfmt(self):
+ return re.compile(r'(s|u|q|uq|qu)(\d+)(\.[+-]?\d+)?')
+
+ def _fxpfmt(self):
+ return re.compile(r'fxp-(s|u)(\d+)/([+-]?\d+)(-complex)?')
def _parseformatstr(self, fmt):
fmt = fmt.casefold()
- mo = self._qfmt.match(fmt)
+ mo = self._qfmt().match(fmt)
if mo:
# Q/S notation counts the sign bit as an integer bit, such that
# the total number of bits is always int+frac
@@ -333,7 +336,7 @@ def _parseformatstr(self, fmt):
n_word = n_frac + n_int
complex_dtype = False
else:
- mo = self._fxpfmt.match(fmt)
+ mo = self._fxpfmt().match(fmt)
if mo:
signed = mo.group(1) == 's'
n_word = int(mo.group(2))
@@ -349,11 +352,25 @@ def _parseformatstr(self, fmt):
return signed, n_word, n_frac, complex_dtype
def _init_size(self, val=None, signed=None, n_word=None, n_frac=None, n_int=None, max_error=_max_error, n_word_max=_n_word_max, raw=False):
+ # check signed type
+ if not isinstance(signed, (type(None), bool, int)):
+ raise TypeError("signed must be boolean (True, False), int (1 or 0) or None!")
+
+ # check n_word, n_frac, n_int type
+ if not isinstance(n_word, (type(None), int)):
+ raise TypeError("n_word must be integer or None!")
+ if not isinstance(n_frac, (type(None), int)):
+ raise TypeError("n_frac must be integer or None!")
+ if not isinstance(n_int, (type(None), int)):
+ raise TypeError("n_int must be integer or None!")
+
# sign by default
if signed is None:
self.signed = True
else:
- self.signed = signed
+ self.signed = bool(signed)
+ if self.signed != 0 and self.signed != 1:
+ raise ValueError("If signed is int, the valid values are 1 (True) and 0 (False)!")
# n_int defined:
if n_word is None and n_frac is not None and n_int is not None:
@@ -399,6 +416,24 @@ def resize(self, signed=None, n_word=None, n_frac=None, n_int=None, restore_val=
_old_val = self.val
_old_n_frac = self.n_frac
+ # check signed type
+ if not isinstance(signed, (type(None), bool, int)):
+ raise TypeError("signed must be boolean (True, False), int (1 or 0) or None!")
+
+ # check n_word, n_frac, n_int type
+ if not isinstance(n_word, (type(None), int)):
+ raise TypeError("n_word must be integer or None!")
+ if not isinstance(n_frac, (type(None), int)):
+ raise TypeError("n_frac must be integer or None!")
+ if not isinstance(n_int, (type(None), int)):
+ raise TypeError("n_int must be integer or None!")
+
+ # sign by default
+ if signed is not None:
+ self.signed = bool(signed)
+ if self.signed != 0 and self.signed != 1:
+ raise ValueError("If signed is int, the valid values are 1 (True) and 0 (False)!")
+
# check if a string-based format has been provided
if dtype is not None:
if signed is not None or n_word is not None or n_frac is not None or n_int is not None:
@@ -418,10 +453,10 @@ def resize(self, signed=None, n_word=None, n_frac=None, n_int=None, restore_val=
self.signed = signed
# word
if n_word is not None:
- self.n_word = n_word
+ self.n_word = int(n_word)
# frac
if n_frac is not None:
- self.n_frac = n_frac
+ self.n_frac = int(n_frac)
# n_int
self.n_int = self.n_word - self.n_frac - (1 if self.signed else 0)
@@ -570,12 +605,12 @@ def reshape(self, shape, order='C'):
If an integer, then the result will be a 1-D array of that length.
One shape dimension can be -1. In this case, the value is inferred from the length of the array and remaining dimensions.
- order : {‘C’, ‘F’, ‘A’}, optional
+ order : {'C', 'F', 'A'}, optional
Read the elements of a using this index order, and place the elements into the reshaped array using this index order.
- ‘C’ means to read / write the elements using C-like index order, with the last axis index changing fastest, back to the first axis index changing slowest.
- ‘F’ means to read / write the elements using Fortran-like index order, with the first index changing fastest, and the last index changing slowest.
- Note that the ‘C’ and ‘F’ options take no account of the memory layout of the underlying array, and only refer to the order of indexing.
- ‘A’ means to read / write the elements in Fortran-like index order if a is Fortran contiguous in memory, C-like order otherwise.
+ 'C' means to read / write the elements using C-like index order, with the last axis index changing fastest, back to the first axis index changing slowest.
+ 'F' means to read / write the elements using Fortran-like index order, with the first index changing fastest, and the last index changing slowest.
+ Note that the 'C' and 'F' options take no account of the memory layout of the underlying array, and only refer to the order of indexing.
+ 'A' means to read / write the elements in Fortran-like index order if a is Fortran contiguous in memory, C-like order otherwise.
Returns
---
@@ -594,12 +629,12 @@ def flatten(self, order='C'):
Parameters
---
- order{‘C’, ‘F’, ‘A’, ‘K’}, optional
- ‘C’ means to flatten in row-major (C-style) order.
- ‘F’ means to flatten in column-major (Fortran- style) order.
- ‘A’ means to flatten in column-major order if a is Fortran contiguous in memory, row-major order otherwise.
- ‘K’ means to flatten a in the order the elements occur in memory.
- The default is ‘C’.
+ order{'C', 'F', 'A', 'K'}, optional
+ 'C' means to flatten in row-major (C-style) order.
+ 'F' means to flatten in column-major (Fortran- style) order.
+ 'A' means to flatten in column-major order if a is Fortran contiguous in memory, row-major order otherwise.
+ 'K' means to flatten a in the order the elements occur in memory.
+ The default is 'C'.
Returns
---
@@ -614,7 +649,7 @@ def flatten(self, order='C'):
# methods about value
- def _format_inupt_val(self, val, return_sizes=False, raw=False):
+ def _format_inupt_val(self, val, return_sizes=False, raw=False, set_inaccuracy=True):
vdtype = None
signed = self.signed
n_word = self.n_word
@@ -635,6 +670,11 @@ def _format_inupt_val(self, val, return_sizes=False, raw=False):
if self.signed is None: self.signed = val.signed
if self.n_word is None: self.n_word = val.n_word
if self.n_frac is None: self.n_frac = val.n_frac
+
+ # check inaccuracy
+ if set_inaccuracy and val.status['inaccuracy']:
+ self.status['inaccuracy'] = True
+
# force return raw value for better precision
val = val.val * 2**(self.n_frac - val.n_frac)
raw = True
@@ -689,7 +729,6 @@ def _format_inupt_val(self, val, return_sizes=False, raw=False):
val = int(val * 2**(self.n_frac))
raw = True
-
else:
raise ValueError('Not supported input type: {}'.format(type(val)))
@@ -750,7 +789,9 @@ def _update_dtype(self, notation=None):
self._dtype = 'fxp-{sign}{nword}/{nfrac}{comp}'.format(sign='s' if self.signed else 'u',
nword=self.n_word,
nfrac=self.n_frac,
- comp='-complex' if (self.val.dtype == complex or self.vdtype == complex) else '')
+ comp='-complex' if (isinstance(self.val, complex) or \
+ self.val.dtype == complex or \
+ self.vdtype == complex) else '')
else:
self._dtype = 'fxp-{sign}{nword}/{nfrac}'.format(sign='s' if self.signed else 'u',
nword=self.n_word,
@@ -1014,7 +1055,7 @@ def uraw(self):
"""
return np.where(self.val < 0, (1 << self.n_word) + self.val, self.val)
- def equal(self, x):
+ def equal(self, x, index=None):
"""
Sets the value of the Fxp using the value of other Fxp object.
If `x` is not a Fxp, this method set the value just like `set_val` method.
@@ -1025,6 +1066,9 @@ def equal(self, x):
x : Fxp object, None, int, float, complex, list of numbers, numpy array, str (bin, hex, dec)
Value(s) to be stored in fractional fixed-point (base 2) format.
+ index : int, optional, default=None
+ Index of the element to be overwritten in list or array of values by `val` input.
+
Returns
---
@@ -1033,10 +1077,15 @@ def equal(self, x):
"""
if isinstance(x, Fxp):
- new_val_raw = x.val * 2**(self.n_frac - x.n_frac)
- self.set_val(new_val_raw, raw=True)
+ if index is None:
+ raw_val = x.val[index]
+ else:
+ raw_val = x.val
+
+ new_val_raw = raw_val * 2**(self.n_frac - x.n_frac)
+ self.set_val(new_val_raw, raw=True, index=index)
else:
- self.set_val(x)
+ self.set_val(x, index=index)
return self
# behaviors
@@ -1304,7 +1353,10 @@ def __pow__(self, x):
from .functions import pow
if not isinstance(x, Fxp):
- x = self._convert_op_input_value(x)
+ if self.config is not None and self.config.op_input_size != 'best':
+ print("Warning: using config.op_input_size != 'best' could lead to long execution times and huge memory usage! Forcing to config.op_input_size='best'")
+ print(f"Tip: force a explicit Fxp dtype for your exponent. Instead of x**{x} use x**Fxp({x}) or x**Fxp({x}, dtype='some fxp dtype')")
+ x = self._convert_op_input_value(x, op_input_size='best')
_sizing = self.config.const_op_sizing
else:
_sizing = self.config.op_sizing
@@ -1501,48 +1553,61 @@ def info(self, verbose=1):
# base representations
- def bin(self, frac_dot=False):
+ def bin(self, frac_dot=False, prefix=None):
if frac_dot:
n_frac_dot = self.n_frac
else:
n_frac_dot = None
+
+ # set prefix if it's necessary
+ prefix = prefix if prefix is not None else self.config.bin_prefix
+ if prefix is not None:
+ if isinstance(prefix, bool) and prefix == True:
+ prefix = '0b' # default binary prefix
if isinstance(self.val, (list, np.ndarray)) and self.val.ndim > 0:
if self.vdtype == complex:
- real_val = [utils.binary_repr(utils.int_array(val.real), n_word=self.n_word, n_frac=n_frac_dot) for val in self.val]
- imag_val = [utils.binary_repr(utils.int_array(val.imag), n_word=self.n_word, n_frac=n_frac_dot) for val in self.val]
+ real_val = [utils.binary_repr(utils.int_array(val.real), n_word=self.n_word, n_frac=n_frac_dot, prefix=prefix) for val in self.val]
+ imag_val = [utils.binary_repr(utils.int_array(val.imag), n_word=self.n_word, n_frac=n_frac_dot, prefix=prefix) for val in self.val]
rval = utils.complex_repr(real_val, imag_val)
else:
- rval = [utils.binary_repr(utils.int_array(val), n_word=self.n_word, n_frac=n_frac_dot) for val in self.val]
+ rval = [utils.binary_repr(utils.int_array(val), n_word=self.n_word, n_frac=n_frac_dot, prefix=prefix) for val in self.val]
else:
if self.vdtype == complex:
- real_val = utils.binary_repr(utils.int_array(self.val.real), n_word=self.n_word, n_frac=n_frac_dot)
- imag_val = utils.binary_repr(utils.int_array(self.val.imag), n_word=self.n_word, n_frac=n_frac_dot)
+ real_val = utils.binary_repr(utils.int_array(self.val.real), n_word=self.n_word, n_frac=n_frac_dot, prefix=prefix)
+ imag_val = utils.binary_repr(utils.int_array(self.val.imag), n_word=self.n_word, n_frac=n_frac_dot, prefix=prefix)
rval = utils.complex_repr(real_val, imag_val)
else:
- rval = utils.binary_repr(int(self.val), n_word=self.n_word, n_frac=n_frac_dot)
+ rval = utils.binary_repr(int(self.val), n_word=self.n_word, n_frac=n_frac_dot, prefix=prefix)
+
return rval
- def hex(self, padding=True):
+ def hex(self, padding=True, prefix=None):
if padding:
hex_n_word = self.n_word
else:
hex_n_word = None
+ # set prefix if it's necessary
+ prefix = prefix if prefix is not None else self.config.hex_prefix
+ if prefix is not None:
+ if isinstance(prefix, bool) and prefix == True:
+ prefix = '0x' # default hexadecimal prefix
+
if isinstance(self.val, (list, np.ndarray)) and self.val.ndim > 0:
if self.vdtype == complex:
- real_val = [utils.hex_repr(utils.binary_repr(utils.int_array(val.real), n_word=self.n_word, n_frac=None), n_word=hex_n_word, base=2) for val in self.val]
- imag_val = [utils.hex_repr(utils.binary_repr(utils.int_array(val.imag), n_word=self.n_word, n_frac=None), n_word=hex_n_word, base=2) for val in self.val]
+ real_val = [utils.hex_repr(utils.binary_repr(utils.int_array(val.real), n_word=self.n_word, n_frac=None), n_word=hex_n_word, base=2, prefix=prefix) for val in self.val]
+ imag_val = [utils.hex_repr(utils.binary_repr(utils.int_array(val.imag), n_word=self.n_word, n_frac=None), n_word=hex_n_word, base=2, prefix=prefix) for val in self.val]
rval = utils.complex_repr(real_val, imag_val)
else:
- rval = [utils.hex_repr(val, n_word=hex_n_word, base=2) for val in self.bin()]
+ rval = [utils.hex_repr(val, n_word=hex_n_word, base=2, prefix=prefix) for val in self.bin()]
else:
if self.vdtype == complex:
- real_val = utils.hex_repr(utils.binary_repr(utils.int_array(self.val.real), n_word=self.n_word, n_frac=None), n_word=hex_n_word, base=2)
- imag_val = utils.hex_repr(utils.binary_repr(utils.int_array(self.val.imag), n_word=self.n_word, n_frac=None), n_word=hex_n_word, base=2)
+ real_val = utils.hex_repr(utils.binary_repr(utils.int_array(self.val.real), n_word=self.n_word, n_frac=None), n_word=hex_n_word, base=2, prefix=prefix)
+ imag_val = utils.hex_repr(utils.binary_repr(utils.int_array(self.val.imag), n_word=self.n_word, n_frac=None), n_word=hex_n_word, base=2, prefix=prefix)
rval = utils.complex_repr(real_val, imag_val)
else:
- rval = utils.hex_repr(self.bin(), n_word=hex_n_word, base=2)
+ rval = utils.hex_repr(self.bin(), n_word=hex_n_word, base=2, prefix=prefix)
return rval
def base_repr(self, base, frac_dot=False):
@@ -1565,6 +1630,10 @@ def base_repr(self, base, frac_dot=False):
rval = utils.base_repr(int(self.val), base=base, n_frac=n_frac_dot)
return rval
+ def from_bin(self, val, raw=False):
+ self.set_val(utils.add_binary_prefix(val), raw=raw)
+ return self
+
# copy
def copy(self):
return copy.copy(self)
@@ -1587,17 +1656,19 @@ def reset(self):
'underflow': False,
'inaccuracy': False}
- def _convert_op_input_value(self, x):
+ def _convert_op_input_value(self, x, op_input_size=None):
if not isinstance(x, Fxp):
- if self.config is not None:
- if self.config.op_input_size == 'best':
- x_fxp = Fxp(x)
- elif self.config.op_input_size == 'same':
- x_fxp = Fxp(x, like=self)
- else:
- raise ValueError('Sizing parameter not supported: {}'.format(self.config.op_input_size))
- else:
+ if op_input_size is None and self.config is not None:
+ op_input_size = self.config.op_input_size
+
+ if op_input_size is None:
+ x_fxp = Fxp(x)
+ elif op_input_size == 'best':
x_fxp = Fxp(x)
+ elif op_input_size == 'same':
+ x_fxp = Fxp(x, like=self)
+ else:
+ raise ValueError('Sizing parameter not supported: {}'.format(op_input_size))
else:
x_fxp = x
@@ -1857,9 +1928,6 @@ def item(self, *args):
items = args[0]
return self.astype(item=items)
- # ToDo:
- # nonzero
-
def clip(self, a_min=None, a_max=None, **kwargs):
from .functions import clip
@@ -1958,6 +2026,10 @@ def __init__(self, **kwargs):
if isinstance(self.template, Config):
self.__dict__ = copy.deepcopy(self.template.__dict__)
+ # prefixes
+ self.bin_prefix = kwargs.pop('bin_prefix', None)
+ self.hex_prefix = kwargs.pop('hex_prefix', '0x')
+
# ---
# properties
# ---
@@ -2196,6 +2268,37 @@ def dtype_notation(self, val):
else:
raise ValueError('dtype_notation must be str type with following valid values: {}'.format(self._dtype_notation_list))
+ # prefixes
+ @property
+ def bin_prefix(self):
+ return self._bin_prefix
+
+ @bin_prefix.setter
+ def bin_prefix(self, prefix):
+ if prefix is not None and not isinstance(prefix, str):
+ print("Warning: the prefix should be a string, converted to string automatically!")
+ prefix = str(prefix)
+
+ if prefix not in [None, 'b', '0b', 'B', '0B']:
+ print(f"Warning: the prefix {prefix} is not a common prefix for binary values!")
+
+ self._bin_prefix = prefix
+
+ @property
+ def hex_prefix(self):
+ return self._hex_prefix
+
+ @hex_prefix.setter
+ def hex_prefix(self, prefix):
+ if prefix is not None and not isinstance(prefix, str):
+ print("Warning: the prefix should be a string, converted to string automatically!")
+ prefix = str(prefix)
+
+ if prefix not in [None, 'x', '0x', 'X', '0X', 'h', '0h', 'H', '0H']:
+ print(f"Warning: the prefix {prefix} is not a common prefix for hexadecimal values!")
+
+ self._hex_prefix = prefix
+
# endregion
# ---
diff --git a/fxpmath/utils.py b/fxpmath/utils.py
index f751d31..ba8367b 100644
--- a/fxpmath/utils.py
+++ b/fxpmath/utils.py
@@ -39,7 +39,7 @@
#%%
def array_support(func):
def iterator(*args, **kwargs):
- if isinstance(args[0], (list, np.ndarray)) and args[0].ndim > 0:
+ if isinstance(args[0], (list, np.ndarray)) and np.asarray(args[0]).ndim > 0:
vals = []
for v in args[0]:
vals.append(iterator(v, *args[1:], **kwargs))
@@ -64,8 +64,12 @@ def twos_complement_repr(val, nbits):
def strbin2int(x, signed=True, n_word=None, return_sizes=False):
- x = x.split('b')[-1] # remove 0b at the begining
- x = x.replace(' ', '') # remove spacing
+ x = x.replace('0b', 'b').replace('b', '') # remove 0b at the begining
+ x = x.replace(' ', '').replace('+', '') # remove spacing and +
+
+ # get original sign of number
+ sign = -1 if x[0] == '-' else 1
+ x = x.replace('-', '')
if n_word is None:
n_word = len(x)
@@ -78,12 +82,21 @@ def strbin2int(x, signed=True, n_word=None, return_sizes=False):
raise ValueError('binary val has more bits ({}) than word ({})!'.format(len(x), n_word))
if signed:
+ if len(x) < 2:
+ raise('Signed binary with no enough amount of bits!')
+
val = int(x[1:], 2)
if x[0] == '1':
val = -1*( (1 << (n_word - 1)) - val)
+
+ if sign == -1:
+ print('Warning: you are using a negative sign (-) with an already binary signed. The value conversion could be wrong!')
else:
val = int(x, 2)
+ # set same original sign
+ val = sign * val
+
if return_sizes:
return val, signed, n_word
else:
@@ -110,6 +123,35 @@ def strbin2float(x, signed=True, n_word=None, n_frac=None, return_sizes=False):
else:
return val
+def strbin2complex(x, signed=True, n_word=None, n_frac=None, return_sizes=False):
+ x = x.replace(' ', '').replace('+', '|').replace('-', '|-').split('|')
+
+ if len(x) == 1 and isinstance(x[0], str) and 'j' in x[0]:
+ # imaginary number
+ val, signed, n_word, n_frac = strbin2float(x[0].replace('j', ''), signed, n_word, n_frac, return_sizes=True)
+ val = 1j*val
+ elif len(x) == 1 and isinstance(x[0], str) and not 'j' in x[0]:
+ # real number
+ val, signed, n_word, n_frac = strbin2float(x[0], signed, n_word, n_frac, return_sizes=True)
+ val = val + 1j*0
+ elif len(x) == 2 and isinstance(x, list) and not 'j' in x[0] and 'j' in x[1]:
+ # complex
+ val_real, signed_real, n_word_real, n_frac_real = strbin2float(x[0], signed, n_word, n_frac, return_sizes=True)
+ val_imag, signed_imag, n_word_imag, n_frac_imag = strbin2float(x[1].replace('j', ''), signed, n_word, n_frac, return_sizes=True)
+ val = val_real + 1j*val_imag
+
+ signed = signed_real or signed_imag
+ n_word = max(n_word_real, n_word_imag)
+ n_frac = max(n_frac_real, n_frac_imag)
+ else:
+ raise ValueError(f"Wrong complex format of binary string!")
+
+ if return_sizes:
+ return val, signed, n_word, n_frac
+ else:
+ return val
+
+
def strhex2int(x, signed=True, n_word=None, return_sizes=False):
x = x.replace('0x', '')
if n_word is None:
@@ -171,9 +213,16 @@ def str2num(x, signed=True, n_word=None, n_frac=None, base=10, return_sizes=Fals
# binary
if '.' in x or (n_frac is not None and n_frac > 0):
# fractional binary
- val, signed, n_word, n_frac = strbin2float(x, signed, n_word, n_frac, return_sizes=True)
+ if 'j' in x:
+ val, signed, n_word, n_frac = strbin2complex(x, signed, n_word, n_frac, return_sizes=True)
+ else:
+ val, signed, n_word, n_frac = strbin2float(x, signed, n_word, n_frac, return_sizes=True)
else:
- val, signed, n_word = strbin2int(x, signed, n_word, return_sizes=True)
+ # integer binary
+ if 'j' in x:
+ val, signed, n_word = strbin2complex(x, signed, n_word, return_sizes=True)
+ else:
+ val, signed, n_word = strbin2int(x, signed, n_word, return_sizes=True)
n_frac = 0
elif base == 16 or 'x' in x[:2]:
@@ -228,15 +277,18 @@ def insert_frac_point(x_bin, n_frac):
return x_bin
@array_support
-def binary_repr(x, n_word=None, n_frac=None):
+def binary_repr(x, n_word=None, n_frac=None, prefix=None):
if n_frac is None:
val = np.binary_repr(int(x), width=n_word)
else:
val = insert_frac_point(np.binary_repr(x, width=n_word), n_frac=n_frac)
+
+ if prefix is not None:
+ val = add_binary_prefix(val, prefix=prefix)
return val
@array_support
-def hex_repr(x, n_word=None, padding=None, base=10):
+def hex_repr(x, n_word=None, padding=None, base=10, prefix='0x'):
if base == 2:
x = int(x, 2)
elif base == 10:
@@ -245,12 +297,12 @@ def hex_repr(x, n_word=None, padding=None, base=10):
raise ValueError('base {base} for input value is not supported!')
if n_word is not None:
- val = '0x{0:0{1}X}'.format(x, int(np.ceil(n_word/4)))
+ val = prefix + '{0:0{1}X}'.format(x, int(np.ceil(n_word/4)))
elif padding is not None:
- val = '0x{0:0{1}X}'.format(x, padding)
+ val = prefix + '{0:0{1}X}'.format(x, padding)
else:
val = hex(x)
- val = '0x'+val[2:].upper()
+ val = prefix + val[2:].upper()
return val
@array_support
@@ -263,6 +315,30 @@ def base_repr(x, n_word=None, base=2, n_frac=None):
val = np.base_repr(x, base=base)
return val
+@array_support
+def add_binary_prefix(x, prefix='0b'):
+ if isinstance(x, np.ndarray) and x.ndim == 0:
+ x = x.item()
+
+ if isinstance(x, str):
+ # convert to easy format
+ x = x.lower().replace(' ', '').replace('i', 'j').replace('0b', '').replace('b', '')
+
+ if ('+' in x or '-' in x) and 'j' in x:
+ # complex format
+ x = prefix + x.replace('+', '+' + prefix).replace('-', '-' + prefix)
+ else:
+ x = prefix + x
+
+ # check valid characters
+ invalid_chars = set(x.replace(prefix, '')) - {'0', '1', '.', 'j', '+', '-'}
+ if len(invalid_chars) > 0:
+ raise ValueError(f"Binary string has invalid characters: {invalid_chars}")
+ else:
+ raise ValueError("Binary value must be a string!")
+
+ return x
+
def complex_repr(r, i):
r = np.asarray(r)
i = np.asarray(i)
@@ -277,6 +353,10 @@ def complex_repr(r, i):
c[idx] = str(r[idx]) + imag_sign_symbol + str(i[idx]) + 'j'
else:
raise ValueError('parameters must be a list of array of strings!')
+
+ # return single element is array has one value
+ if c.size == 0:
+ c = c.item(0)
return c
def bits_len(x, signed=None):
@@ -342,19 +422,20 @@ def int_clip(x, val_min, val_max):
return x_clipped
def wrap(x, signed, n_word):
+
+ m = (1 << n_word)
if n_word >= _n_word_max:
dtype = object
+ x = int_array(x).astype(dtype) & (m - 1)
else:
dtype = int
+ x = np.array(x).astype(dtype) & (m - 1)
+
+ x = np.asarray(x).astype(dtype)
- m = (1 << n_word)
if signed:
- x = np.array(x).astype(dtype) & (m - 1)
- x = np.asarray(x).astype(dtype)
- x = np.where(x < (1 << (n_word-1)), x, x | (-m))
- else:
- x = np.array(x).astype(dtype) & (m - 1)
- x = np.asarray(x).astype(dtype)
+ x = np.where(x < (1 << (n_word-1)), x, x | (-m))
+
return x
def get_sizes_from_dtype(dtype):
diff --git a/index.md b/index.md
new file mode 100644
index 0000000..0e709ce
--- /dev/null
+++ b/index.md
@@ -0,0 +1,26 @@
+
+
+A python library for fractional fixed-point (base 2) arithmetic and binary manipulation with Numpy compatibility.
+
+Some key features:
+
+* Fixed-point signed and unsigned numbers representation.
+* Arbitrary word and fractional sizes. Auto sizing capability. Extended precision capability.
+* Arithmetic and logical (bitwise) operations supported.
+* Input values can be: int, float, complex, list, numpy arrays, strings (bin, hex, dec), Decimal type.
+* Input rounding methods, overflow and underflow behaviors and flags.
+* Binary, Hexadecimal, and other bases representations (like strings).
+* Indexing supported.
+* Linear scaling: scale and bias.
+* Numpy backend.
+* Suppport for Numpy functions. They can take and return Fxp objects.
+* Internal behavior configurable: inputs/outputs formating, calculation methods.
+
+---
+
+## Table of content
+
+- [install](docs/install)
+- [quick start](docs/quick_start)
+- [behavioral configuration](docs/config)
+
diff --git a/tests/test_basic.py b/tests/test_basic.py
index dc3cddc..bb31ff4 100644
--- a/tests/test_basic.py
+++ b/tests/test_basic.py
@@ -132,12 +132,41 @@ def test_instances():
assert x.n_int == 4
assert x.n_word == 7
+ x = Fxp('0b00000.01+0b01111.00j')
+ assert x() == 0.25 + 1j*15
+
+ x = Fxp('0b00000.01+0b11111.11j')
+ assert x() == 0.25 - 1j*0.25
+
+ x = Fxp('0b00000.01-0b0000.10j')
+ assert x() == 0.25 - 1j*0.5
+
x = Fxp([[1.5, 2.25], [-0.125, -3.75]])
assert (x() == np.array([[1.5, 2.25], [-0.125, -3.75]])).all()
x = Fxp([['0b1100', '0b0110'], ['0b0000', '0b1111']], signed=True, n_frac=2)
assert (x() == np.array([[-1.0, 1.5], [0.0, -0.25]])).all()
+ # Fxp from a Fxp
+ x = Fxp(-1.75, dtype='fxp-s8/4')
+ y = Fxp(x)
+ assert x() == y()
+
+ y = Fxp(x, like=x)
+ assert x() == y() and x.dtype == y.dtype
+
+ y = Fxp(x, signed=False)
+ assert x() != y() and y() == 0
+
+ x = Fxp(1.75, dtype='fxp-u8/4')
+ y = Fxp(x)
+ assert x() == y()
+
+ x1 = Fxp(4, False, 9, 3)
+ x2 = Fxp(5, False, 9, 3)
+ cast = Fxp(None, True, 9, 3)
+ y = cast(x1) - cast(x2)
+
def test_signed():
# signed
x_fxp = Fxp(0.0, True, 8, 7)
@@ -202,6 +231,9 @@ def test_base_representations():
# decimal positive
x(2.5)
assert x.bin() == '00101000'
+ assert x.bin(frac_dot=True) == '0010.1000'
+ assert x.bin(prefix='0b') == '0b00101000'
+ assert x.bin(prefix=True) == '0b00101000'
assert x.hex() == '0x28'
assert x.hex(padding=False) == '0x28'
assert x.base_repr(2) == '101000'
@@ -211,6 +243,7 @@ def test_base_representations():
x(-7.25)
assert x.bin() == '10001100'
assert x.bin(frac_dot=True) == '1000.1100'
+ assert x.bin(frac_dot=True, prefix='b') == 'b1000.1100'
assert x.hex() == '0x8C'
assert x.hex(padding=False) == '0x8C'
assert x.base_repr(2) == '-1110100'
@@ -220,6 +253,8 @@ def test_base_representations():
# complex
x(1.5 + 1j*0.75)
assert x.bin() == '00011000+00001100j'
+ assert x.bin(frac_dot=True) == '0001.1000+0000.1100j'
+ assert x.bin(frac_dot=True, prefix=True) == '0b0001.1000+0b0000.1100j'
assert x.hex() == '0x18+0x0Cj'
assert x.hex(padding=False) == '0x18+0xCj'
assert x.base_repr(2) == '11000+1100j'
diff --git a/tests/test_functions.py b/tests/test_functions.py
index 1922ae2..93180f1 100644
--- a/tests/test_functions.py
+++ b/tests/test_functions.py
@@ -49,3 +49,37 @@ def test_fxp_sum():
y = fxp.fxp_sum(x, axis=1)
assert (y() == np.sum(vals, axis=1)).all()
+
+def test_from_bin():
+ x = from_bin('0', signed=False)
+ assert x() == 0
+
+ x = fxp.from_bin('1', signed=False)
+ assert x() == 1
+
+ x = fxp.from_bin('011')
+ assert x() == 3
+
+ x = fxp.from_bin('111')
+ assert x() == -1
+
+ x = fxp.from_bin('111', signed=False)
+ assert x() == 7
+
+ x = fxp.from_bin('1.11')
+ assert x() == -0.25
+
+ x = fxp.from_bin('0b1.11', signed=False)
+ assert x() == 1.75
+
+ x = fxp.from_bin('0.11')
+ assert x() == 0.75
+
+ x = fxp.from_bin('01100100.01')
+ assert x() == 100.25
+ assert x.n_word == 10 and x.n_frac == 2
+
+ x = fxp.from_bin('01100100.01', dtype='fxp-s16/4')
+ assert x() == 100.25
+ assert x.n_word == 16 and x.n_frac == 4
+
\ No newline at end of file
diff --git a/tests/test_issues.py b/tests/test_issues.py
index 69ba000..cbfce6a 100644
--- a/tests/test_issues.py
+++ b/tests/test_issues.py
@@ -4,6 +4,7 @@
import fxpmath as fxp
from fxpmath.objects import Fxp, Config
+from fxpmath import functions
import numpy as np
@@ -152,6 +153,25 @@ def test_issue_41_v0_4_2():
assert x() == 2
assert y() == 2
+ x = Fxp(2, False, 31, 0, overflow='wrap')
+ y = Fxp(2, False, 32, 0, overflow='wrap')
+
+ assert x() == 2
+ assert y() == 2
+
+ x = Fxp(2.5, signed=True, n_word=31, n_frac=24, overflow='wrap')
+ y = Fxp(2.5, signed=True, n_word=32, n_frac=24, overflow='wrap')
+
+ assert x() == 2.5
+ assert y() == 2.5
+
+ x = Fxp(2.5, signed=True, n_word=63, n_frac=48, overflow='wrap')
+ y = Fxp(2.5, signed=True, n_word=64, n_frac=48, overflow='wrap')
+
+ assert x() == 2.5
+ assert y() == 2.5
+
+
def test_issue_42_v0_4_2():
b = Fxp(2, True, 4, 0, overflow='wrap')
assert (b + 8)() == -6.0
@@ -189,6 +209,81 @@ def test_issue_44_v0_4_3():
b = Fxp(2**64+6, False, 64, 0, overflow='wrap', scaling=2, bias=8)
assert b() == 2**64+6
+def test_issue_48_v0_4_8():
+ """
+ Flags not propagated
+ https://github.com/francof2a/fxpmath/issues/48
+ """
+ a = Fxp(-2., dtype="fxp-s24/8")
+ b = Fxp(2.15, dtype="fxp-s24/8")
+ assert b.status['inaccuracy']
+
+ # inaccuracy in b must be propagated to c
+ c = a + b
+ assert c.status['inaccuracy']
+
+ # add extra test using a inaccurate Fxp to set a new Fxp
+ d = Fxp(c)
+ assert d.status['inaccuracy']
+
+def test_issue_49_v0_4_8():
+ """
+ Reversal of .bin()
+ https://github.com/francof2a/fxpmath/issues/49
+ """
+ # Method 1
+ x1 = Fxp(3.4)
+ x_bin = x1.bin()
+ x2 = Fxp('0b' + x_bin, like=x1)
+ assert x1 == x2
+
+ # Method 2
+ x_bin = x1.bin(frac_dot=True)
+ x2 = Fxp('0b' + x_bin)
+ assert x1 == x2
+
+ # Method 3
+ x_bin = x1.bin()
+ x2 = Fxp(like=x1).from_bin(x_bin)
+ assert x1 == x2
+
+ x_bin = x1.bin(frac_dot=True)
+ x2 = Fxp(like=x1).from_bin(x_bin)
+ assert x1 == x2
+
+ # Method 4
+ x_bin = x1.bin(frac_dot=True)
+ x2 = functions.from_bin(x_bin)
+ assert x1 == x2
+
+ # alternatives to get binary string with prefix
+ x_bin = x1.bin(frac_dot=True, prefix='0b')
+ x2 = Fxp(x_bin)
+ assert x1 == x2
+
+ x1.config.bin_prefix = '0b'
+ x_bin = x1.bin(frac_dot=True)
+ x2 = Fxp(x_bin)
+ assert x1 == x2
+
+ # test negative value
+ x1 = Fxp(-3.4)
+ x_bin = x1.bin(frac_dot=True)
+ x2 = functions.from_bin(x_bin)
+ assert x1 == x2
+
+ # test raw value
+ x_bin = x1.bin()
+ x2 = functions.from_bin(x_bin, raw=True, like=x1)
+ assert x1 == x2
+
+ # test complex value
+ x1 = Fxp(-3.4 + 1j*0.25)
+ x_bin = x1.bin(frac_dot=True)
+ x2 = functions.from_bin(x_bin)
+ assert x1 == x2
+
+
def test_issue_53_v0_4_5():
x = Fxp(2j, dtype = 'fxp-u4/0-complex')
z = x/2
@@ -255,3 +350,119 @@ def test_issue_62_v0_4_7():
y[0][0] = y[0][0] + 1.0
assert y[0][0]() == 0.0
+
+def test_issue_66_v0_4_8():
+ x = Fxp(np.array([1.25, 0.5]), dtype='S8.4')
+ y = Fxp(np.array([2.25, 1.5]), dtype='S16.6')
+ # x[0].equal(y[0]) # it does NOT work
+ # x[0] = y[0] # it works
+ x.equal(y[0], index=0) # it works
+
+ assert x[0]() == y[0]()
+
+def test_issue_67_v0_4_8():
+ input_size = Fxp(None, dtype='fxp-s32/23')
+ f = [0,10+7j,20-0.65j,30]
+ f = Fxp(f, like = input_size)
+
+ def FFT(f):
+ N = len(f)
+ if N <= 1:
+ return f
+
+ # division: decompose N point FFT into N/2 point FFT
+ even= FFT(f[0::2])
+ odd = FFT(f[1::2])
+
+ # store combination of results
+ temp = np.zeros(N, dtype=complex)
+ # temp = Fxp(temp, dtype='fxp-s65/23')
+ temp = Fxp(temp, dtype='fxp-s65/46')
+
+ for u in range(N//2):
+ W = Fxp(np.exp(-2j*np.pi*u/N), like=input_size)
+ temp[u] = even[u] + W* odd[u]
+ temp[u+N//2] = even[u] - W*odd[u]
+
+ return temp
+
+ # testing the function to see if it matches the manual computation
+ F_fft = FFT(f)
+
+def test_issue_73_v0_4_8():
+ # single unsigned value does work
+ a = Fxp(10, False, 14, 3)
+ b = Fxp(15, False, 14, 3)
+ c = a - b
+ assert c() == 0.0 # 0.0 --> correct
+
+ # unsigned list does not work
+ d = Fxp([10, 21], False, 14, 3)
+ e = Fxp([15, 15], False, 14, 3)
+ f = d - e
+ assert f[0]() == 0.0 # [4095.875 6.0] --> 4095.875 is the upper limit
+ assert f[1]() == 6.0
+
+def test_issue_76_v0_4_8():
+ # Numpy Issue with Bigger bit sizes
+ # Getting strange results when using larger bit sizes in numpy calls
+
+ # This works
+ w = Fxp([1, 1, 1, 1], dtype='fxp-s29/0')
+ y = np.cumsum(w)
+ assert np.all(y() == np.array([1, 2, 3, 4]))
+
+ # This doesn't
+ w = Fxp([1, 1, 1, 1], dtype='fxp-s32/0')
+ y = np.cumsum(w)
+ assert np.all(y() == np.array([1, 2, 3, 4])) # works in linux, not in windows
+
+ # Increase word size above 64 bits
+ w = Fxp([1, 1, 1, 1], dtype='fxp-s64/0')
+ y = np.cumsum(w)
+ assert np.all(y() == np.array([1, 2, 3, 4]))
+
+def test_issue_77_v0_4_8():
+ # Precision error when numpy.reshape
+
+ a = np.array([[0.762, 0.525], [0.345, 0.875]], dtype=complex)
+ x = Fxp(a, signed=True, n_word=5, n_frac=3)
+ # fxp-s5/3-complex
+ assert x.signed == True and x.n_word == 5 and x.n_frac == 3
+
+ y = np.reshape(x, (1, 4))
+ # fxp-s4/3-complex
+ assert y.signed == True and y.n_word == 5 and y.n_frac == 3
+
+def test_issue_80_v0_4_8():
+ # Creation of Fxp-object with negative n_frac
+
+ # The following code results in unexpected behaviour
+ # when trying to specify the same type using alternative formats
+ x = Fxp(16, signed=True, n_word=8, n_frac=-2)
+ # -> x.dtype = 'fxp-s8/-2' , ok
+ assert x.dtype == 'fxp-s8/-2'
+
+ x = Fxp(16, dtype='S10.-2')
+ assert x.dtype == 'fxp-s8/-2'
+
+ x = Fxp(16, dtype='fxp-s8/-2')
+ assert x.dtype == 'fxp-s8/-2'
+
+def test_issue_85_v0_4_8():
+ # Wrap overflow breaks on 0.0 value
+
+ dt_values = ['fxp-s32/16', 'fxp-s64/32', 'fxp-s96/64']
+
+ for dt in dt_values:
+ x = Fxp(0, dtype=dt) # => Success
+ assert x() == 0.0
+
+ x = Fxp(0.0, dtype=dt) # => Success
+ assert x() == 0.0
+
+ x = Fxp(0, dtype=dt, overflow='wrap') # => Success
+ assert x() == 0.0
+
+ x = Fxp(0.0, dtype=dt, overflow='wrap') # EXCEPTION
+ assert x() == 0.0
diff --git a/tests/test_utils.py b/tests/test_utils.py
index a596b35..e90b628 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -34,6 +34,13 @@ def test_strbin2float():
assert strbin2float('0001', n_frac=2) == 0.25
assert strbin2float('000.1', n_frac=4) == 0.5
+def test_strbin2complex():
+ assert strbin2complex('0001') == 1.0 + 1j*0
+ assert strbin2complex('0b10000000j') == -1j*128.0
+ assert strbin2complex('0b01+0b10000000j') == 1.0 - 1j*128.0
+ assert strbin2complex('0b1+0b1000 0000j', signed=False) == 1.0 + 1j*128.0
+ assert strbin2complex('0b1 - 0b1000 0000j', signed=False) == 1.0 - 1j*128.0
+
def test_strhex2int():
assert strhex2int('0x00') == 0
assert strhex2int('0x0A') == 10
@@ -105,7 +112,6 @@ def test_base_repr():
assert base_repr(30, base=16) == '1E'
assert base_repr(-30, base=16) == '-1E'
-
def test_bits_len():
assert bits_len(1) == 1
assert bits_len(-1) == 1
@@ -114,3 +120,56 @@ def test_bits_len():
assert bits_len(32) == 6
assert bits_len(-32) == 6
assert bits_len(-33) == 7
+
+def test_add_binary_prefix():
+ # single values
+ assert add_binary_prefix('0') == '0b0'
+ assert add_binary_prefix('1') == '0b1'
+ assert add_binary_prefix('b0') == '0b0'
+ assert add_binary_prefix('b1') == '0b1'
+ assert add_binary_prefix('0b0') == '0b0'
+ assert add_binary_prefix('0b1') == '0b1'
+
+ assert add_binary_prefix('0110') == '0b0110'
+ assert add_binary_prefix('b1111') == '0b1111'
+
+ assert add_binary_prefix('01.001') == '0b01.001'
+ assert add_binary_prefix('00.000') == '0b00.000'
+
+ # list and arrays
+ assert np.all(add_binary_prefix(['110', '001']) == np.array(['0b110', '0b001']))
+ assert np.all(
+ add_binary_prefix([['110', '001'], ['b111', '0b101']]) == \
+ np.array([['0b110', '0b001'], ['0b111', '0b101']])
+ )
+ assert np.all(add_binary_prefix(np.array(['110', '001'])) == np.array(['0b110', '0b001']))
+ assert np.all(
+ add_binary_prefix(np.array([['110', '001'], ['b111', '0b101']])) == \
+ np.array([['0b110', '0b001'], ['0b111', '0b101']])
+ )
+
+ # complex
+ assert add_binary_prefix('0110+1110j') == '0b0110+0b1110j'
+ assert add_binary_prefix('0110-1110j') == '0b0110-0b1110j'
+ assert add_binary_prefix('0b0110-1110j') == '0b0110-0b1110j'
+ assert add_binary_prefix('0110-0b1110j') == '0b0110-0b1110j'
+ assert np.all(add_binary_prefix(['110+101j', '001-111j']) == np.array(['0b110+0b101j', '0b001-0b111j']))
+
+ # test wrong input formats
+ inputs_list = [0, 1, 3, '3', '102', '0b1102']
+ for i in inputs_list:
+ try:
+ _ = add_binary_prefix(i)
+ except:
+ assert True
+ else:
+ print(f"input processed right when should be wrong: {i}")
+ assert False
+
+def test_complex_repr():
+ assert complex_repr('2', '-4.5') == '2-4.5j'
+ assert complex_repr('2', '4.5') == '2+4.5j'
+ assert complex_repr('-2', '4.5') == '-2+4.5j'
+
+ assert np.all(complex_repr(['1', '-2.5'], ['4.5', '0']) == np.array(['1+4.5j', '-2.5+0j']))
+
\ No newline at end of file