-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Artur Bać
committed
Mar 6, 2024
1 parent
aeb7b3e
commit 8dbe4d6
Showing
6 changed files
with
242 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
|
||
## Bitwise Operations in FixedMath | ||
|
||
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. | ||
|
||
### Right Shift Operator | ||
|
||
- **`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. | ||
|
||
### Left Shift Operator | ||
|
||
- **`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: | ||
- Shifting the unsigned representation of the value left by `r` bits. | ||
- Clearing any bits that overflow into the sign bit area to avoid corrupting the sign. | ||
- Preserving the original sign bit of the `fixed_t` value. | ||
|
||
### Safety and Correctness | ||
|
||
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. | ||
|
||
### Usage Example | ||
|
||
```cpp | ||
fixed_t a = ...; // Initialize with some value | ||
|
||
// Right shift operation | ||
fixed_t result_right_shift = a >> 2; // Shifts `a` right by 2 bits | ||
|
||
// Left shift operation | ||
fixed_t result_left_shift = a << 3; // Shifts `a` left by 3 bits, maintaining the sign bit | ||
``` | ||
|
||
### Note on Bitwise Operations | ||
|
||
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
|
||
## Conversion between Fixed and Arithmetic Types in FixedMath | ||
|
||
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. | ||
|
||
### Conversion from `fixed_t` to Arithmetic Types | ||
|
||
- **`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: | ||
- For integral types, it converts the `fixed_t` value to the corresponding integral conversion. | ||
- For floating-point types, it converts the `fixed_t` value to the corresponding floating-point conversion. | ||
|
||
- **`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. | ||
|
||
### Conversion from Arithmetic Types to `fixed_t` | ||
|
||
- **`arithmetic_to_fixed<arithmetic_type>(arithmetic_type value) noexcept`**: Provides a clear interface for converting arithmetic types to `fixed_t`. | ||
|
||
### Examples of Use | ||
|
||
Conversion from `fixed_t` to arithmetic types: | ||
|
||
```cpp | ||
fixed_t fixedValue = 2.5_fix; // Initialize with some fixed-point value | ||
|
||
// Convert to an integer | ||
int intValue = fixed_to_arithmetic<int>(fixedValue); | ||
|
||
// Convert to a floating-point | ||
double doubleValue = fixedValue; // Implicitly uses fixed_t::operator double() const | ||
``` | ||
|
||
Conversion from arithmetic types to `fixed_t`: | ||
|
||
```cpp | ||
int intInput = 5; | ||
// Convert from integer to fixed_t | ||
fixed_t fixedFromInt = arithmetic_to_fixed(intInput); | ||
|
||
double doubleInput = 2.5; | ||
// Convert from floating-point to fixed_t | ||
fixed_t fixedFromDouble = arithmetic_to_fixed(doubleInput); | ||
|
||
fixedFromDouble = static_cast<double>(arithmetic_to_fixed(doubleInput)); | ||
``` | ||
|
||
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
|
||
## Sine Function in FixedMath | ||
|
||
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. | ||
|
||
### Implementation Details | ||
|
||
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: | ||
|
||
- **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. | ||
|
||
- **Maclaurin Series for Sine**: The sine of the angle is computed as: | ||
|
||
\[ \sin(x) = x - \frac{x^3}{3!} + \frac{x^5}{5!} - \frac{x^7}{7!} + \cdots \] | ||
|
||
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: | ||
|
||
\[ x \left( 1 - x^2 \left( \frac{1}{6} - \frac{x^2}{120} \left( 1 - \frac{x^2}{42} \right) \right) \right) \] | ||
|
||
This approximation not only simplifies the computation but also significantly reduces the computational overhead by minimizing the number of division operations required. | ||
|
||
### Key Functions | ||
|
||
- **`sin_range(fixed_t rad) noexcept`**: Normalizes the input angle into the correct range for the sine calculation. | ||
|
||
- **`sin(fixed_t rad) noexcept`**: Calculates the sine of the given angle in radians using the optimized Maclaurin series expansion. | ||
|
||
### Example Usage | ||
|
||
```cpp | ||
fixed_t rad = ...; // some angle in radians | ||
fixed_t sin_value = sin(rad); // calculates sine of rad | ||
``` | ||
|
||
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. | ||
|
||
## Optimization Process: Reduction of Divisions | ||
|
||
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. | ||
|
||
The sine function's optimization involves a step-by-step transformation of the Maclaurin series to reduce the number of division operations required. | ||
|
||
The series of transformations applied to the sine function calculation is as follows: | ||
|
||
1. Initial Equation: | ||
\[ x \left( 1 - x^2 \left( 1 - x^2 \left( 1 - x^2 \cdot rac{1}{42} | ||
ight) \cdot rac{1}{20} | ||
ight) \cdot rac{1}{6} | ||
ight) \] | ||
|
||
2. Reduction of Division Operations 1: | ||
\[ x \left( 1 - x^2 \left( 1 - x^2 \left( 1 - x^2 \cdot \left( rac{1}{2} \cdot rac{1}{21} | ||
ight) | ||
ight) \cdot \left( rac{1}{4} \cdot rac{1}{5} | ||
ight) | ||
ight) \cdot \left( rac{1}{2} \cdot rac{1}{3} | ||
ight) | ||
ight) \] | ||
|
||
3. Reduction of Division Operations 2: | ||
\[ x \left( 1 - x^2 \left( 1 - x^2 \cdot rac{1}{21} \left( 21 - x^2 \cdot rac{1}{2} | ||
ight) \cdot rac{1}{4} \cdot rac{1}{5} | ||
ight) \cdot rac{1}{2} \cdot rac{1}{3} | ||
ight) \] | ||
|
||
4. Reduction of Division Operations 3: | ||
\[ x \left( 1 - x^2 \left( 1 - x^2 \cdot rac{1}{105} \left( 21 - x^2 \cdot rac{1}{2} | ||
ight) \cdot rac{1}{4} | ||
ight) \cdot rac{1}{2} \cdot rac{1}{3} | ||
ight) \] | ||
|
||
5. Consolidation of Terms: | ||
\[ x \left( 1 - x^2 \cdot rac{1}{630} \left( 105 - x^2 \left( 21 - x^2 \cdot rac{1}{2} | ||
ight) \cdot rac{1}{4} | ||
ight) \cdot rac{1}{2} | ||
ight) \] | ||
|
||
6. Further Consolidation: | ||
\[ x \left( rac{3 \cdot 5 \cdot 21 - x^2 \left( 5 \cdot 21 - x^2 \left( 21 - x^2 \cdot rac{1}{2} | ||
ight) \cdot rac{1}{4} | ||
ight) \cdot rac{1}{2} }{3 \cdot 5 \cdot 21} | ||
ight) \] | ||
|
||
7. Final Equation before Simplification: | ||
\[ x \left( rac{315 - x^2 \left( 105 - x^2 \left( 21 - x^2 \cdot rac{1}{2} | ||
ight) \cdot rac{1}{4} | ||
ight) \cdot rac{1}{2} }{315} | ||
ight) \] | ||
|
||
8. Simplified Final Equation: | ||
\[ x \left( rac{315 - x^2 \left( 105 - x^2 \left( 42 - x^2 | ||
ight) \cdot rac{1}{8} | ||
ight) \cdot rac{1}{2} }{315} | ||
ight) \] | ||
|
||
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
|
||
## Subtraction in FixedMath | ||
|
||
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. | ||
|
||
### Core Subtraction Functionality | ||
|
||
- **`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. | ||
|
||
### Type Promotion and Arithmetic | ||
|
||
- **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. | ||
|
||
- **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. | ||
|
||
### Subtraction Operator Overloads | ||
|
||
- **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. | ||
|
||
- **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. | ||
|
||
### Specialized Subtraction Functions | ||
|
||
- **`promoted_double_substract`**: Specially caters to subtraction operations where at least one of the operands is a double, elevating the operation to double precision. | ||
|
||
- **`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. | ||
|
||
### Safety and Precision | ||
|
||
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. | ||
|
||
### Usage Example | ||
|
||
```cpp | ||
fixed_t a = ...; // Initialize with some value | ||
fixed_t b = ...; // Another fixed_t value | ||
fixed_t result = a - b; // Subtraction of two fixed_t values | ||
|
||
int scalar = 5; | ||
fixed_t result2 = a - scalar; // Subtraction with an integer scalar | ||
|
||
double d = 2.0; | ||
auto result3 = a - d; // Subtraction with a double, result is promoted to double | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters