Skip to content

Commit 8dbe4d6

Browse files
author
Artur Bać
committed
documentation update
1 parent aeb7b3e commit 8dbe4d6

File tree

6 files changed

+242
-20
lines changed

6 files changed

+242
-20
lines changed

docs/bitwise_operations.md

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
2+
## Bitwise Operations in FixedMath
3+
4+
The FixedMath library includes support for bitwise operations on fixed-point numbers (`fixed_t`), carefully implemented to preserve the integrity of fixed-point arithmetic while providing essential functionality.
5+
6+
### Right Shift Operator
7+
8+
- **`operator >> (fixed_t l, int r) noexcept`**: This function applies the bitwise right shift operation to a `fixed_t` value. If the shift count `r` is non-negative, the function performs the shift operation and returns the result. If `r` is negative, it returns NaN to indicate an invalid operation. This ensures that the operation only proceeds under valid conditions.
9+
10+
### Left Shift Operator
11+
12+
- **`operator << (fixed_t l, int r) noexcept`**: The bitwise left shift operation is more complex due to the need to handle the sign bit correctly in a fixed-point context. If the shift count `r` is non-negative, it performs the shift while maintaining the sign bit of the original value. This is achieved by:
13+
- Shifting the unsigned representation of the value left by `r` bits.
14+
- Clearing any bits that overflow into the sign bit area to avoid corrupting the sign.
15+
- Preserving the original sign bit of the `fixed_t` value.
16+
17+
### Safety and Correctness
18+
19+
Both operators incorporate checks to ensure that shift operations are only performed with non-negative shift counts, adhering to the principles of safety and precision that characterize fixed-point arithmetic in the FixedMath library. This approach prevents undefined or unexpected behavior that could arise from attempting to shift by negative counts or risking overflow/underflow conditions.
20+
21+
### Usage Example
22+
23+
```cpp
24+
fixed_t a = ...; // Initialize with some value
25+
26+
// Right shift operation
27+
fixed_t result_right_shift = a >> 2; // Shifts `a` right by 2 bits
28+
29+
// Left shift operation
30+
fixed_t result_left_shift = a << 3; // Shifts `a` left by 3 bits, maintaining the sign bit
31+
```
32+
33+
### Note on Bitwise Operations
34+
35+
While bitwise operations on fixed-point numbers can be useful, it's essential to use them judiciously, especially considering the potential for altering the numeric value in ways that are not directly analogous to integer arithmetic due to the fixed-point representation.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
2+
## Conversion between Fixed and Arithmetic Types in FixedMath
3+
4+
The FixedMath library provides seamless conversion mechanisms between fixed-point numbers (`fixed_t`) and standard arithmetic types (integers and floating-point numbers). These conversions ensure that fixed-point arithmetic integrates well with the broader C++ type system, allowing for efficient and type-safe operations across different numeric types.
5+
6+
### Conversion from `fixed_t` to Arithmetic Types
7+
8+
- **`fixed_to_arithmetic<arithmetic_type>(fixed_t value) noexcept`**: Converts a `fixed_t` value to a specified arithmetic type (`arithmetic_type`). The function discriminates between integral and floating-point types, using the most appropriate conversion method for each case:
9+
- For integral types, it converts the `fixed_t` value to the corresponding integral conversion.
10+
- For floating-point types, it converts the `fixed_t` value to the corresponding floating-point conversion.
11+
12+
- **`fixed_t::operator arithmetic_type() const noexcept`**: A type conversion operator that allows a `fixed_t` object to be automatically converted to an arithmetic type when required. This leverages the `fixed_to_arithmetic` template function internally to perform the conversion.
13+
14+
### Conversion from Arithmetic Types to `fixed_t`
15+
16+
- **`arithmetic_to_fixed<arithmetic_type>(arithmetic_type value) noexcept`**: Provides a clear interface for converting arithmetic types to `fixed_t`.
17+
18+
### Examples of Use
19+
20+
Conversion from `fixed_t` to arithmetic types:
21+
22+
```cpp
23+
fixed_t fixedValue = 2.5_fix; // Initialize with some fixed-point value
24+
25+
// Convert to an integer
26+
int intValue = fixed_to_arithmetic<int>(fixedValue);
27+
28+
// Convert to a floating-point
29+
double doubleValue = fixedValue; // Implicitly uses fixed_t::operator double() const
30+
```
31+
32+
Conversion from arithmetic types to `fixed_t`:
33+
34+
```cpp
35+
int intInput = 5;
36+
// Convert from integer to fixed_t
37+
fixed_t fixedFromInt = arithmetic_to_fixed(intInput);
38+
39+
double doubleInput = 2.5;
40+
// Convert from floating-point to fixed_t
41+
fixed_t fixedFromDouble = arithmetic_to_fixed(doubleInput);
42+
43+
fixedFromDouble = static_cast<double>(arithmetic_to_fixed(doubleInput));
44+
```
45+
46+
These conversion functions and operators ensure that working with fixed-point numbers in a mixed arithmetic context is both natural and efficient, maintaining type safety and precision across conversions.

docs/index.md

+10-11
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
The FixedMath library provides a comprehensive suite for fixed-point arithmetic operations, optimized for performance and precision. It includes basic arithmetic operations, trigonometric functions, conversion utilities, and more.
66

7-
8-
97
## Main Type
108

119
- [`struct fixed_t`](fixed_t.md): The main type used in calculations.
@@ -18,48 +16,49 @@ The FixedMath library provides a comprehensive suite for fixed-point arithmetic
1816

1917
### Addition
2018

19+
See [documentation of addition](addition.md) for more details.
2120

22-
See our [full documentation of addition](addition.md) for more details.
23-
24-
- `auto fixed_addition(supported_type1 lh, supported_type2 rh) noexcept` : Returns the result of the addition of two arguments.
2521
- `auto operator +(supported_type1 l, supported_type2 r) noexcept` : Operator overload for addition.
2622
- `fixed_t &operator +=(fixed_t &l, supported_type r) noexcept`: Addition assignment.
2723

2824
### Subtraction
2925

30-
- `auto fixed_substract(supported_type1 lh, supported_type2 rh) noexcept`: Returns the result of the subtraction of two arguments.
26+
See [documentation of subtraction](subtraction.md) for more details.
27+
3128
- `auto operator -(supported_type1 l, supported_type2 r) noexcept`: Operator overload for subtraction.
3229
- `fixed_t & operator -=(fixed_t &lh, supported_type rh) noexcept`: Subtraction assignment.
3330

3431
### Multiplication
3532

36-
See our [full documentation of multiplication](multiplication.md) for more details.
33+
See [documentation of multiplication](multiplication.md) for more details.
3734

38-
- `auto fixed_multiply(supported_type1 lh, supported_type2 rh) noexcept`: Returns the result of the multiplication of two arguments.
3935
- `auto operator *(supported_type1 lh, supported_type2 rh) noexcept`: Operator overload for multiplication.
4036
- `fixed_t & operator *=(fixed_t &lh, supported_type rh) noexcept`: Multiplication assignment.
4137

4238
### Division
4339

44-
See our [full documentation of division](division.md) for more details.
40+
See [documentation of division](division.md) for more details.
4541

46-
- `auto fixed_division(supported_type1 lh, supported_type2 rh) noexcept`: Returns the result of the division of two arguments.
4742
- `auto operator /(supported_type1 lh, supported_type2 rh) noexcept`: Operator overload for division.
4843
- `fixed_t & operator /=(fixed_t &lh, supported_type rh) noexcept`: Division assignment.
4944

5045
## Bitwise Operations
5146

47+
See [documentation of bitwise operations](bitwise_operations.md) for more details.
48+
5249
- `fixed_t operator >>(fixed_t l, int r) noexcept`: Shifts right the value of `l` by `r` digits.
5350
- `fixed_t operator <<(fixed_t l, int r) noexcept`: Shifts left the value of `l` by `r` digits.
5451

5552
## Conversion Operations
5653

54+
See [documentation of conversion between fixed and arithmetic types](conversion_between_fixed_and_arithmetic.md) for more details.
55+
5756
- `fixed_t arithmetic_to_fixed(arithmetic_type value) noexcept`: Converts any floating point or integral value into a fixed point.
5857
- `arithmetic_type fixed_to_arithmetic(fixed_t value) noexcept`: Converts `fixed_t` into any floating point or integral type.
5958

6059
## Trigonometric Functions
6160

62-
- `fixed_t sin(fixed_t rad) noexcept`: Returns the sine of `rad` in radians.
61+
- [`fixed_t sin(fixed_t rad) noexcept`](sine.md): Returns the sine of `rad` in radians.
6362
- `fixed_t cos(fixed_t rad) noexcept`: Returns the cosine of `rad` in radians.
6463
- `fixed_t tan(fixed_t rad) noexcept`: Returns the tangent of `rad`.
6564
- `fixed_t asin(fixed_t x) noexcept`: Returns the arc sine of `x`.

docs/sine.md

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
2+
## Sine Function in FixedMath
3+
4+
The FixedMath library provides an implementation for the sine function using Maclaurin series expansion, a form of the Taylor series centered at zero. This method is chosen for its efficiency in computing trigonometric functions within a fixed range of input values, ensuring both accuracy and performance.
5+
6+
### Implementation Details
7+
8+
The sine function's implementation involves normalizing the input angle to a specific range and then calculating the sine using a truncated series expansion. Here's an overview of the process:
9+
10+
- **Normalization**: The input angle (`rad`) is normalized to the range \(-\frac{\phi}{2}\) to \(3\frac{\phi}{2}\), where \(\phi\) represents the value of pi in the fixed-point format. This normalization ensures the angle is within the optimal range for the Maclaurin series calculation.
11+
12+
- **Maclaurin Series for Sine**: The sine of the angle is computed as:
13+
14+
\[ \sin(x) = x - \frac{x^3}{3!} + \frac{x^5}{5!} - \frac{x^7}{7!} + \cdots \]
15+
16+
However, to optimize performance, the series is simplified and truncated, with the error kept below a certain threshold. The implementation uses a series expansion with a reduced number of divisions for efficiency:
17+
18+
\[ x \left( 1 - x^2 \left( \frac{1}{6} - \frac{x^2}{120} \left( 1 - \frac{x^2}{42} \right) \right) \right) \]
19+
20+
This approximation not only simplifies the computation but also significantly reduces the computational overhead by minimizing the number of division operations required.
21+
22+
### Key Functions
23+
24+
- **`sin_range(fixed_t rad) noexcept`**: Normalizes the input angle into the correct range for the sine calculation.
25+
26+
- **`sin(fixed_t rad) noexcept`**: Calculates the sine of the given angle in radians using the optimized Maclaurin series expansion.
27+
28+
### Example Usage
29+
30+
```cpp
31+
fixed_t rad = ...; // some angle in radians
32+
fixed_t sin_value = sin(rad); // calculates sine of rad
33+
```
34+
35+
This sine function implementation ensures high accuracy for angles within the normalized range, making it suitable for various applications requiring trigonometric calculations in fixed-point arithmetic.
36+
37+
## Optimization Process: Reduction of Divisions
38+
39+
The implementation details reveal an innovative approach to reducing the computational cost associated with division operations in the series expansion. By reorganizing the equation and strategically applying mathematical properties, the number of divisions is significantly reduced, enhancing the function's performance while maintaining accuracy. This optimization is particularly beneficial in environments where division operations are costly in terms of processing time.
40+
41+
The sine function's optimization involves a step-by-step transformation of the Maclaurin series to reduce the number of division operations required.
42+
43+
The series of transformations applied to the sine function calculation is as follows:
44+
45+
1. Initial Equation:
46+
\[ x \left( 1 - x^2 \left( 1 - x^2 \left( 1 - x^2 \cdot rac{1}{42}
47+
ight) \cdot rac{1}{20}
48+
ight) \cdot rac{1}{6}
49+
ight) \]
50+
51+
2. Reduction of Division Operations 1:
52+
\[ x \left( 1 - x^2 \left( 1 - x^2 \left( 1 - x^2 \cdot \left( rac{1}{2} \cdot rac{1}{21}
53+
ight)
54+
ight) \cdot \left( rac{1}{4} \cdot rac{1}{5}
55+
ight)
56+
ight) \cdot \left( rac{1}{2} \cdot rac{1}{3}
57+
ight)
58+
ight) \]
59+
60+
3. Reduction of Division Operations 2:
61+
\[ x \left( 1 - x^2 \left( 1 - x^2 \cdot rac{1}{21} \left( 21 - x^2 \cdot rac{1}{2}
62+
ight) \cdot rac{1}{4} \cdot rac{1}{5}
63+
ight) \cdot rac{1}{2} \cdot rac{1}{3}
64+
ight) \]
65+
66+
4. Reduction of Division Operations 3:
67+
\[ x \left( 1 - x^2 \left( 1 - x^2 \cdot rac{1}{105} \left( 21 - x^2 \cdot rac{1}{2}
68+
ight) \cdot rac{1}{4}
69+
ight) \cdot rac{1}{2} \cdot rac{1}{3}
70+
ight) \]
71+
72+
5. Consolidation of Terms:
73+
\[ x \left( 1 - x^2 \cdot rac{1}{630} \left( 105 - x^2 \left( 21 - x^2 \cdot rac{1}{2}
74+
ight) \cdot rac{1}{4}
75+
ight) \cdot rac{1}{2}
76+
ight) \]
77+
78+
6. Further Consolidation:
79+
\[ x \left( rac{3 \cdot 5 \cdot 21 - x^2 \left( 5 \cdot 21 - x^2 \left( 21 - x^2 \cdot rac{1}{2}
80+
ight) \cdot rac{1}{4}
81+
ight) \cdot rac{1}{2} }{3 \cdot 5 \cdot 21}
82+
ight) \]
83+
84+
7. Final Equation before Simplification:
85+
\[ x \left( rac{315 - x^2 \left( 105 - x^2 \left( 21 - x^2 \cdot rac{1}{2}
86+
ight) \cdot rac{1}{4}
87+
ight) \cdot rac{1}{2} }{315}
88+
ight) \]
89+
90+
8. Simplified Final Equation:
91+
\[ x \left( rac{315 - x^2 \left( 105 - x^2 \left( 42 - x^2
92+
ight) \cdot rac{1}{8}
93+
ight) \cdot rac{1}{2} }{315}
94+
ight) \]
95+
96+
This step-by-step approach highlights the methodical reduction in division operations, leading to the final, optimized equation used for calculating the sine function in the FixedMath library.

docs/subtraction.md

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
2+
## Subtraction in FixedMath
3+
4+
The FixedMath library precisely manages the subtraction of fixed-point numbers (`fixed_t`), ensuring accuracy and robustness across various operations. This includes support for mixed-type arithmetic involving `fixed_t`, integers, and floating-point numbers.
5+
6+
### Core Subtraction Functionality
7+
8+
- **`fixed_substracti(fixed_t lh, fixed_t rh) noexcept`**: This function computes the difference between two `fixed_t` values, incorporating checks to prevent anomalous results. It returns NaN to indicate an error when the operation results in an overflow or underflow, especially when subtracting values across different signs that should normally produce a valid range but don't due to fixed-point constraints.
9+
10+
### Type Promotion and Arithmetic
11+
12+
- **Promotion to Double**: For operations that involve a double, the `fixed_t` value is promoted to double precision prior to subtraction, ensuring the operation benefits from the precision of floating-point arithmetic.
13+
14+
- **Promotion to Fixed**: When an arithmetic operation includes types other than `fixed_t`, the non-fixed type is elevated to `fixed_t` using `promote_to_fixed`. This enables the operation to proceed with fixed-point accuracy.
15+
16+
### Subtraction Operator Overloads
17+
18+
- **Operator `-=`**: Adjusts the left-hand operand by subtracting the right-hand operand from it. The right operand can be any arithmetic type, with the operation performed after suitable type promotions to ensure accuracy.
19+
20+
- **Operator `-`**: Implements subtraction between two operands of potentially mixed types. The outcome is either a `fixed_t` or a double, depending on whether any of the operands is a double, to optimize the operation's precision for the given operand types.
21+
22+
### Specialized Subtraction Functions
23+
24+
- **`promoted_double_substract`**: Specially caters to subtraction operations where at least one of the operands is a double, elevating the operation to double precision.
25+
26+
- **`promoted_fixed_substract`**: Facilitates the subtraction of two arithmetic values, promoting them to `fixed_t` as necessary, to ensure the operation is executed within the fixed-point realm.
27+
28+
### Safety and Precision
29+
30+
Subtraction operations in the FixedMath library are crafted with a focus on safety, ensuring that conditions like potential overflows or underflows are managed adeptly, returning NaN in situations where accurate results cannot be guaranteed.
31+
32+
### Usage Example
33+
34+
```cpp
35+
fixed_t a = ...; // Initialize with some value
36+
fixed_t b = ...; // Another fixed_t value
37+
fixed_t result = a - b; // Subtraction of two fixed_t values
38+
39+
int scalar = 5;
40+
fixed_t result2 = a - scalar; // Subtraction with an integer scalar
41+
42+
double d = 2.0;
43+
auto result3 = a - d; // Subtraction with a double, result is promoted to double
44+
```

fixed_lib/include/fixedmath/math.h

+11-9
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ namespace fixedmath
743743

744744
rad = detail::sin_range(rad);
745745

746-
// on arm64 condition is compiled as substraction with csel instruction without jump
746+
// on arm64 condition is compiled as subtraction with csel instruction without jump
747747
// mov w9, #9279
748748
// movk w9, #3, lsl #16
749749
// cmp x0, x8
@@ -761,14 +761,16 @@ namespace fixedmath
761761
fixed_internal result{ mul_<prec_>(x,( one__ - mul_<prec_+1>(x2,( one__ - mul_<prec_+2>(x2,( one__-x2/42))/5))/3)) };
762762
#else
763763
// reduce number of divisions
764-
// { x left ( { 1 - x ^ 2 left ( { 1 - x ^ 2 left ( { 1 - x ^ 2 cdot { 1 over 42 } } right ) cdot { 1 over 20 } } right ) { 1 over 6 } } right ) }
765-
// { x left ( { 1 - x ^ 2 left ( { 1 - x ^ 2 left ( { 1 - x ^ 2 cdot { 1 over 2 } { 1 over 21 } } right ) cdot { 1 over 4 } cdot { 1 over 5 } } right ) { 1 over 2 } cdot { 1 over 3 } } right ) }
766-
// { x left ( { 1 - x ^ 2 left ( { 1 - x ^ 2 { 1 over 21 } left ( { 21 - x ^ 2 cdot { 1 over 2 } } right ) cdot { 1 over 4 } cdot { 1 over 5 } } right ) { 1 over 2 } cdot { 1 over 3 } } right ) }
767-
// { x left ( { 1 - x ^ 2 left ( { 1 - x ^ 2 { 1 over { 5 cdot 21 } } left ( { 21 - x ^ 2 cdot { 1 over 2 } } right ) cdot { 1 over 4 } } right ) { 1 over 2 } cdot { 1 over 3 } } right ) }
768-
// { x left ( { 1 - x ^ 2 { 1 over { 3 cdot 5 cdot 21 } } left ( { 5 cdot 21 - x ^ 2 left ( { 21 - x ^ 2 cdot { 1 over 2 } } right ) cdot { 1 over 4 } } right ) { 1 over 2 } } right ) }
769-
// { x left ( { 3 cdot 5 cdot 21 - x ^ 2 left ( { 5 cdot 21 - x ^ 2 left ( { 21 - x ^ 2 cdot { 1 over 2 } } right ) cdot { 1 over 4 } } right ) { 1 over 2 } } right ) { 1 over { 3 cdot 5 cdot 21 } } }
770-
// { x left ( { 315 - x ^ 2 left ( { 105 - x ^ 2 left ( { 21 - x ^ 2 cdot { 1 over 2 } } right ) cdot { 1 over 4 } } right ) { 1 over 2 } } right ) :315 }
771-
// { x left ( { 315 - x ^ 2 left ( { 105 - x ^ 2 left ( { 42 - x ^ 2 } right ) cdot { 1 over 8 } } right ) { 1 over 2 } } right ) :315 }
764+
/*
765+
{ x left ( { 1 - x ^ 2 left ( { 1 - x ^ 2 left ( { 1 - x ^ 2 cdot { 1 over 42 } } right ) cdot { 1 over 20 } } right ) { 1 over 6 } } right ) }
766+
{ x left ( { 1 - x ^ 2 left ( { 1 - x ^ 2 left ( { 1 - x ^ 2 cdot { 1 over 2 } { 1 over 21 } } right ) cdot { 1 over 4 } cdot { 1 over 5 } } right ) { 1 over 2 } cdot { 1 over 3 } } right ) }
767+
{ x left ( { 1 - x ^ 2 left ( { 1 - x ^ 2 { 1 over 21 } left ( { 21 - x ^ 2 cdot { 1 over 2 } } right ) cdot { 1 over 4 } cdot { 1 over 5 } } right ) { 1 over 2 } cdot { 1 over 3 } } right ) }
768+
{ x left ( { 1 - x ^ 2 left ( { 1 - x ^ 2 { 1 over { 5 cdot 21 } } left ( { 21 - x ^ 2 cdot { 1 over 2 } } right ) cdot { 1 over 4 } } right ) { 1 over 2 } cdot { 1 over 3 } } right ) }
769+
{ x left ( { 1 - x ^ 2 { 1 over { 3 cdot 5 cdot 21 } } left ( { 5 cdot 21 - x ^ 2 left ( { 21 - x ^ 2 cdot { 1 over 2 } } right ) cdot { 1 over 4 } } right ) { 1 over 2 } } right ) }
770+
{ x left ( { 3 cdot 5 cdot 21 - x ^ 2 left ( { 5 cdot 21 - x ^ 2 left ( { 21 - x ^ 2 cdot { 1 over 2 } } right ) cdot { 1 over 4 } } right ) { 1 over 2 } } right ) { 1 over { 3 cdot 5 cdot 21 } } }
771+
{ x left ( { 315 - x ^ 2 left ( { 105 - x ^ 2 left ( { 21 - x ^ 2 cdot { 1 over 2 } } right ) cdot { 1 over 4 } } right ) { 1 over 2 } } right ) :315 }
772+
{ x left ( { 315 - x ^ 2 left ( { 105 - x ^ 2 left ( { 42 - x ^ 2 } right ) cdot { 1 over 8 } } right ) { 1 over 2 } } right ) :315 }
773+
*/
772774
constexpr fixed_internal _42{ fixed_internal{42}<<prec_};
773775
constexpr fixed_internal _105{ fixed_internal{105}<<(prec_+prec_+3)};
774776
constexpr fixed_internal _315{ fixed_internal{315}<<prec_};

0 commit comments

Comments
 (0)