-
Notifications
You must be signed in to change notification settings - Fork 143
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
Showing
7 changed files
with
464 additions
and
280 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
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 |
---|---|---|
|
@@ -11,118 +11,114 @@ | |
*/ | ||
// ---------------------------------------------------------------------------- | ||
|
||
#ifndef MODM_SATURATED_HPP | ||
#define MODM_SATURATED_HPP | ||
#ifndef MODM_SATURATED_HPP | ||
#define MODM_SATURATED_HPP | ||
|
||
#include <modm/math/utils/arithmetic_traits.hpp> | ||
#include <algorithm> | ||
|
||
namespace modm | ||
{ | ||
/** | ||
* \brief Saturated arithmetics | ||
* | ||
* \see http://www.mikrocontroller.net/articles/AVR_Arithmetik/Saturierung | ||
* | ||
* \author Fabian Greif <[email protected]> | ||
* | ||
* \todo extend implementation (multiplication etc.) | ||
* \todo add 16-bit datetype assembler implementations for AVRs | ||
* \todo documentation | ||
* \ingroup modm_math_saturated | ||
*/ | ||
template<std::integral T> | ||
class Saturated | ||
{ | ||
using WideSignedType = modm::WideType<std::make_signed_t<T>>; | ||
|
||
void | ||
setValue(WideSignedType unsaturated) | ||
/** | ||
* \brief Saturated arithmetics | ||
* | ||
* \see http://www.mikrocontroller.net/articles/AVR_Arithmetik/Saturierung | ||
* | ||
* \author Fabian Greif <[email protected]> | ||
* | ||
* \todo extend implementation (multiplication etc.) | ||
* \todo add 16-bit datetype assembler implementations for AVRs | ||
* \todo documentation | ||
* \ingroup modm_math_saturated | ||
*/ | ||
template<typename T> | ||
class Saturated | ||
{ | ||
value = std::clamp<WideSignedType>(unsaturated, std::numeric_limits<T>::min(), std::numeric_limits<T>::max()); | ||
} | ||
typedef modm::SignedType<T> SignedType; | ||
typedef modm::WideType<SignedType> WideType; | ||
|
||
T value{0}; | ||
public: | ||
Saturated(); | ||
|
||
public: | ||
Saturated() = default; | ||
Saturated(const T& initialValue); | ||
|
||
Saturated(const T initialValue) : value(initialValue) {} | ||
inline const T& | ||
getValue() const | ||
{ | ||
return value; | ||
} | ||
|
||
inline const T | ||
getValue() const | ||
{ | ||
return value; | ||
} | ||
Saturated& | ||
operator += (const Saturated& other); | ||
|
||
Saturated& | ||
operator -= (const Saturated& other); | ||
|
||
void | ||
absolute(); | ||
|
||
Saturated& | ||
operator+=(const Saturated& other); | ||
public: | ||
template<typename U> | ||
friend Saturated<U> | ||
operator - (const Saturated<U>& x); | ||
|
||
Saturated& | ||
operator-=(const Saturated& other); | ||
template<typename U> | ||
friend Saturated<U> | ||
abs(const Saturated<U>& x); | ||
|
||
void | ||
absolute(); | ||
template<typename U> | ||
friend Saturated<U> | ||
operator - (const Saturated<U>& a, const Saturated<U>& b); | ||
|
||
// public: | ||
// template<std::integral U> | ||
// friend Saturated<U> | ||
// operator-(const Saturated<U>& x); | ||
template<typename U> | ||
friend Saturated<U> | ||
operator + (const Saturated<U>& a, const Saturated<U>& b); | ||
|
||
// template<std::integral U> | ||
// friend Saturated<U> | ||
// abs(const Saturated<U>& x); | ||
template<typename U> | ||
friend bool | ||
operator == (const Saturated<U>& a, const Saturated<U>& b); | ||
|
||
// template<std::integral U> | ||
// friend Saturated<U> | ||
// operator-(const Saturated<U>& a, const Saturated<U>& b); | ||
template<typename U> | ||
friend bool | ||
operator != (const Saturated<U>& a, const Saturated<U>& b); | ||
|
||
// template<std::integral U> | ||
// friend Saturated<U> | ||
// operator+(const Saturated<U>& a, const Saturated<U>& b); | ||
// TODO > >= < <= | ||
|
||
// template<std::integral U> | ||
// friend bool | ||
// operator==(const Saturated<U>& a, const Saturated<U>& b); | ||
private: | ||
void | ||
setValue(WideType value); | ||
|
||
// template<std::integral U> | ||
// friend bool | ||
// operator!=(const Saturated<U>& a, const Saturated<U>& b); | ||
T value; | ||
}; | ||
|
||
// TODO > >= < <= | ||
}; | ||
// ------------------------------------------------------------------------ | ||
|
||
// /** | ||
// * \brief Invert value | ||
// */ | ||
// template<std::integral U> | ||
// Saturated<U> | ||
// operator-(const Saturated<U>& x); | ||
/// \brief Invert value | ||
template<typename U> | ||
Saturated<U> | ||
operator - (const Saturated<U>& x); | ||
|
||
// /** | ||
// * \brief Calculate the absolute value | ||
// */ | ||
// template<std::integral U> | ||
// Saturated<U> | ||
// abs(const Saturated<U>& x); | ||
/// \brief Calculate the absolute value | ||
template<typename U> | ||
Saturated<U> | ||
abs(const Saturated<U>& x); | ||
|
||
// template<std::integral U> | ||
// Saturated<U> | ||
// operator-(const Saturated<U>& a, const Saturated<U>& b); | ||
template<typename U> | ||
Saturated<U> | ||
operator - (const Saturated<U>& a, const Saturated<U>& b); | ||
|
||
// template<std::integral U> | ||
// Saturated<U> | ||
// operator+(const Saturated<U>& a, const Saturated<U>& b); | ||
template<typename U> | ||
Saturated<U> | ||
operator + (const Saturated<U>& a, const Saturated<U>& b); | ||
|
||
// template<std::integral U> | ||
// inline bool | ||
// operator==(const Saturated<U>& a, const Saturated<U>& b); | ||
template<typename U> | ||
inline bool | ||
operator == (const Saturated<U>& a, const Saturated<U>& b); | ||
|
||
// template<std::integral U> | ||
// inline bool | ||
// operator!=(const Saturated<U>& a, const Saturated<U>& b); | ||
} // namespace modm | ||
template<typename U> | ||
inline bool | ||
operator != (const Saturated<U>& a, const Saturated<U>& b); | ||
} | ||
|
||
#include "saturated_impl.hpp" | ||
|
||
#endif // MODM_SATURATED_HPP | ||
#endif // MODM_SATURATED_HPP |
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,128 @@ | ||
/* | ||
* Copyright (c) 2009, Fabian Greif | ||
* Copyright (c) 2010, Martin Rosekeit | ||
* Copyright (c) 2012, Niklas Hauser | ||
* | ||
* This file is part of the modm project. | ||
* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
*/ | ||
// ---------------------------------------------------------------------------- | ||
|
||
#ifndef MODM_SATURATED_HPP | ||
#error "Don't include this file directly use 'math/saturated.hpp' instead!" | ||
#endif | ||
|
||
namespace modm | ||
{ | ||
// ------------------------------------------------------------------------ | ||
template<> | ||
Saturated<int8_t>& | ||
Saturated<int8_t>::operator+=(const Saturated& other) { | ||
asm ( | ||
"add %[x], %[y]" "\n\t" | ||
"brvc 0f" "\n\t" // Falls es einen signed Überlauf gab | ||
// (V=1) Maximalwert laden | ||
"ldi %[x], 0x7f" "\n\t" | ||
"sbrc %[y], 7" "\n\t" // y ist negativ, daher muss der | ||
// Minimalwert geladen werden | ||
"ldi %[x], 0x80" "\n\t" | ||
"0:" | ||
: [x] "+d" (this->value) | ||
: [y] "r" (other.value) | ||
); | ||
|
||
return *this; | ||
} | ||
|
||
// ------------------------------------------------------------------------ | ||
// TODO testen | ||
/*template<> | ||
Saturated<int8_t>& | ||
Saturated<int8_t>::operator+=(const Saturated<UnsignedType>& other) { | ||
asm ( | ||
"add %[x], %[y]" "\n\t" | ||
"brvc 0f" "\n\t" // Falls es einen signed Überlauf gab | ||
// (V=1) Maximalwert laden | ||
"ldi %[x], 0xff" "\n\t" | ||
"0:" | ||
: [x] "+d" (this->value) | ||
: [y] "r" (other.value) | ||
); | ||
return *this; | ||
}*/ | ||
|
||
// ------------------------------------------------------------------------ | ||
template<> | ||
Saturated<int8_t>& | ||
Saturated<int8_t>::operator-=(const Saturated& other) { | ||
asm ( | ||
"sub %[x], %[y]" "\n\t" | ||
"brvc 0f" "\n\t" // Falls es einen signed Überlauf gab | ||
// (V=1) Minimalwert laden | ||
"ldi %[x], 0x80" "\n\t" | ||
"sbrc %[y], 7" "\n\t" // y ist negativ, daher muss der | ||
// Maximalwert geladen werden | ||
"ldi %[x], 0x7f" "\n\t" | ||
"0:" | ||
: [x] "+d" (this->value) | ||
: [y] "r" (other.value) | ||
); | ||
|
||
return *this; | ||
} | ||
|
||
// ------------------------------------------------------------------------ | ||
// TODO testen | ||
/*template<> | ||
Saturated<int8_t>& | ||
Saturated<int8_t>::operator-=(const Saturated<UnsignedType>& other) { | ||
asm ( | ||
"sub %[x], %[y]" "\n\t" | ||
"brvc 0f" "\n\t" // Falls es einen signed Überlauf gab | ||
// (V=1) Minimalwert laden | ||
"ldi %[x], 0x80" "\n\t" | ||
"0:" | ||
: [x] "+d" (this->value) | ||
: [y] "r" (other.value) | ||
); | ||
return *this; | ||
}*/ | ||
|
||
// ------------------------------------------------------------------------ | ||
// FIXME warum funktioniert das nicht??? | ||
template<> | ||
Saturated<int8_t> | ||
operator - (const Saturated<int8_t>& a) { | ||
Saturated<int8_t> temp(a); | ||
asm ( | ||
"neg %[x]" "\n\t" | ||
"brvc 0f" "\n\t" // Signed Überlauf (V=1): Das Ergebnis | ||
// ist 0x80 und wird verändert zu 0x7f | ||
"dec %[x]" "\n\t" | ||
"0:" | ||
: [x] "+d" (temp.value) | ||
); | ||
return temp; | ||
} | ||
|
||
// ------------------------------------------------------------------------ | ||
template<> | ||
Saturated<int8_t> | ||
abs(const Saturated<int8_t>& a) { | ||
Saturated<int8_t> temp(a); | ||
asm ( | ||
"sbrc %[x], 7" "\n\t" | ||
"neg %[x]" "\n\t" // x < 0: negieren | ||
"sbrc %[x], 7" "\n\t" | ||
"dec %[x]" "\n\t" // R0 ist immer noch < 0 (also 0x80), | ||
// lade 0x7f | ||
: [x] "+d" (temp.value) | ||
); | ||
return temp; | ||
} | ||
} |
Oops, something went wrong.