36template<
typename ValueType>
127 if (first.kind != second.kind) {
130 return !first.
isFinite() || first.value == second.value;
134 return !(first == second);
138 if (first.kind != second.kind) {
139 return first.kind < second.kind;
141 return first.
isFinite() && first.value < second.value;
145 return !(second < first);
149 return second < first;
153 return !(first < second);
163 return first.
isFinite() && first.value == second;
167 return second.
isFinite() && first == second.value;
171 return !(first == second);
175 return !(first == second);
188 return !(second < first);
192 return !(second < first);
196 return second < first;
200 return second < first;
204 return !(first < second);
208 return !(first < second);
231 STORM_LOG_THROW(first.kind == second.kind, storm::exceptions::InvalidOperationException,
"Tried to compute " << first <<
" + " << second <<
".");
238 return first + (-second);
246 int const signs = first.sign() * second.sign();
247 STORM_LOG_THROW(signs != 0, storm::exceptions::InvalidOperationException,
"Tried to compute " << first <<
" * " << second <<
".");
253 "Tried to compute " << first <<
" / " << second <<
".");
258 int const divisorSign = second.sign();
259 STORM_LOG_THROW(divisorSign != 0, storm::exceptions::InvalidOperationException,
"Tried to compute " << first <<
" / " << second <<
".");
267 return *
this = *
this + other;
271 return *
this = *
this - other;
275 return *
this = *
this * other;
279 return *
this = *
this / other;
283 switch (number.kind) {
315 return value < storm::utility::zero<ValueType>() ? -1 : 1;
330template<
typename ValueType>
356template<
typename ValueType>
362template<
typename ValueType>
374template<
typename ValueType>
388template<
typename ValueType>
393template<
typename ValueType>
394 requires(!detail::IsExtendedNumber<ValueType>::value)
402template<
typename ValueType>
407template<
typename ValueType>
408 requires(!detail::IsExtendedNumber<ValueType>::value)
423template<
typename ValueType>
425 if constexpr (std::is_same_v<ExtendedValueType<ValueType>, ValueType>) {
426 return std::move(values);
428 std::vector<ValueType> result;
429 result.reserve(values.size());
430 for (
auto& value : values) {
431 STORM_LOG_THROW(value.isFinite(), storm::exceptions::InvalidOperationException,
"Tried to narrow " << value <<
" to a type that cannot hold it.");
432 result.push_back(std::move(value.getFinite()));
442template<
typename ValueType>
444 if constexpr (std::is_same_v<ExtendedValueType<ValueType>, ValueType>) {
447 std::vector<ValueType> result;
448 result.reserve(values.size());
449 for (
auto const& value : values) {
450 STORM_LOG_THROW(value.isFinite(), storm::exceptions::InvalidOperationException,
"Tried to narrow " << value <<
" to a type that cannot hold it.");
451 result.push_back(value.getFinite());
461template<
typename ValueType>
463 std::vector<ValueType> result;
464 result.reserve(values.size());
465 for (
auto& value : values) {
466 if constexpr (std::is_same_v<ExtendedValueType<ValueType>, ValueType>) {
469 result.push_back(value.isFinite() ? std::move(value.getFinite()) : defaultValue);
480template<
typename ValueType>
483 STORM_LOG_THROW(!value.isInfinite(), storm::exceptions::NotSupportedException,
484 "There is no representation of " << value <<
" in the value type it would have to be narrowed to.");
485 return value.getFinite();
495template<
typename ValueType>
496std::vector<ExtendedValueType<ValueType>>
widen(std::vector<ValueType>&& values) {
497 if constexpr (std::is_same_v<ExtendedValueType<ValueType>, ValueType>) {
498 return std::move(values);
500 std::vector<ExtendedValueType<ValueType>> result;
501 result.reserve(values.size());
502 for (
auto& value : values) {
516template<
typename ValueType>
517 requires(!std::is_reference_v<ValueType>)
520 "storm::utility::fromSentinel, which exists only for as long as parts of Storm still produce the sentinel that storm::utility::infinity yields.");
525 return std::forward<ValueType>(value);
533template<
typename ValueType>
534std::vector<ExtendedValueType<ValueType>>
fromSentinel(std::vector<ValueType>&& values) {
536 "storm::utility::fromSentinel, which exists only for as long as parts of Storm still produce the sentinel that storm::utility::infinity yields.");
537 if constexpr (std::is_same_v<ExtendedValueType<ValueType>, ValueType>) {
538 return std::move(values);
540 std::vector<ExtendedValueType<ValueType>> result;
541 result.reserve(values.size());
543 for (
auto& value : values) {
544 if (value == sentinel) {
547 result.push_back(std::move(value));
554template<
typename ValueType>
557 "storm::utility::fromSentinel, which exists only for as long as parts of Storm still produce the sentinel that storm::utility::infinity yields.");
569template<
typename ValueType>
572 "storm::utility::toSentinel, which exists only for as long as parts of Storm still expect the sentinel that storm::utility::infinity yields.");
574 if (value.isInfinite()) {
575 STORM_LOG_THROW(value.isPositiveInfinity(), storm::exceptions::NotSupportedException,
"There is no representation of " << value <<
" here.");
578 return value.getFinite();
589template<
typename ValueType>
590 requires(detail::IsExtendedNumber<ValueType>::value)
595template<
typename ValueType>
596 requires(detail::IsExtendedNumber<ValueType>::value)
601template<
typename ValueType>
602 requires(detail::IsExtendedNumber<ValueType>::value)
604 return ValueType::infinity();
611template<
typename ValueType>
620template<
typename ValueType>
625template<
typename ValueType>
626 requires(!detail::IsExtendedNumber<ValueType>::value)
635template<
typename ValueType>
640template<
typename ValueType>
645template<
typename ValueType>
650template<
typename ValueType>
663template<
typename TargetType,
typename SourceType>
669 return number.
isPositiveInfinity() ? TargetType::infinity() : TargetType::negativeInfinity();
680template<
typename TargetType,
typename SourceType>
681 requires(detail::IsExtendedNumber<TargetType>::value && !detail::IsExtendedNumber<SourceType>::value)
686 return TargetType::infinity();
689 return TargetType::negativeInfinity();
714template<
typename ValueType>
723template<
typename ValueType>
724struct hash<
storm::utility::ExtendedNumber<ValueType>> {
733 return std::hash<ValueType>()(number.
getFinite());
742template<
typename ValueType>
743struct numeric_limits<
storm::utility::ExtendedNumber<ValueType>> {
761 return type(std::numeric_limits<ValueType>::lowest());
765 return type(std::numeric_limits<ValueType>::min());
769 return type(std::numeric_limits<ValueType>::max());
773 return type(std::numeric_limits<ValueType>::epsilon());
A value of ValueType extended with the two infinities -infinity and +infinity.
friend ExtendedNumber operator+(ExtendedNumber const &first, ExtendedNumber const &second)
static ExtendedNumber negativeInfinity()
friend bool operator<(ValueType const &first, ExtendedNumber const &second)
friend bool operator==(ExtendedNumber const &first, ExtendedNumber const &second)
ExtendedNumber & operator+=(ExtendedNumber const &other)
friend bool operator<(ExtendedNumber const &first, ExtendedNumber const &second)
ExtendedNumber & operator=(ExtendedNumber &&)=default
friend bool operator!=(ExtendedNumber const &first, ValueType const &second)
ExtendedNumber(ExtendedNumber const &)=default
friend std::ostream & operator<<(std::ostream &out, ExtendedNumber const &number)
bool isNegativeInfinity() const
ExtendedNumber(ValueType &&value)
ExtendedNumber & operator-=(ExtendedNumber const &other)
friend bool operator<=(ValueType const &first, ExtendedNumber const &second)
ExtendedNumber(ExtendedNumber &&)=default
friend bool operator>=(ExtendedNumber const &first, ExtendedNumber const &second)
friend bool operator!=(ValueType const &first, ExtendedNumber const &second)
ValueType const & getFinite() const
friend bool operator>(ExtendedNumber const &first, ValueType const &second)
friend bool operator>=(ValueType const &first, ExtendedNumber const &second)
friend bool operator>=(ExtendedNumber const &first, ValueType const &second)
ExtendedNumber & operator=(ExtendedNumber const &)=default
ExtendedNumber(ValueType const &value)
Creates a finite value.
ExtendedNumber()
Creates a finite value that is zero.
friend bool operator>(ExtendedNumber const &first, ExtendedNumber const &second)
friend ExtendedNumber operator-(ExtendedNumber const &first, ExtendedNumber const &second)
ExtendedNumber operator-() const
~ExtendedNumber()=default
bool isPositiveInfinity() const
ExtendedNumber const & operator+() const
friend bool operator<=(ExtendedNumber const &first, ExtendedNumber const &second)
friend ExtendedNumber operator/(ExtendedNumber const &first, ExtendedNumber const &second)
friend bool operator!=(ExtendedNumber const &first, ExtendedNumber const &second)
friend bool operator<=(ExtendedNumber const &first, ValueType const &second)
friend bool operator<(ExtendedNumber const &first, ValueType const &second)
friend bool operator==(ExtendedNumber const &first, ValueType const &second)
The comparisons against a plain value.
friend bool operator==(ValueType const &first, ExtendedNumber const &second)
ExtendedNumber & operator*=(ExtendedNumber const &other)
ExtendedNumber & operator/=(ExtendedNumber const &other)
friend bool operator>(ValueType const &first, ExtendedNumber const &second)
friend ExtendedNumber operator*(ExtendedNumber const &first, ExtendedNumber const &second)
static ExtendedNumber infinity()
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
#define STORM_LOG_DEPRECATED(message)
SFTBDDChecker::ValueType ValueType
ExtendedValueType< ValueType > positiveInfinity()
bool isOne(ValueType const &a)
bool isFinite(ExtendedNumber< ValueType > const &value)
bool isConstant(ValueType const &)
ExtendedValueType< ValueType > fromSentinel(ValueType &&value)
Recognises the value that storm::utility::infinity still yields for the value types that have no infi...
std::vector< ExtendedValueType< ValueType > > widen(std::vector< ValueType > &&values)
Widens a vector of finite values into the extended value type.
ExtendedValueType< ValueType > negativeInfinity()
bool isNegativeInfinity(ExtendedNumber< ValueType > const &number)
bool isZero(ValueType const &a)
ValueType abs(ValueType const &number)
std::conditional_t< storm::NumberTraits< ValueType >::HasInfinity, ValueType, ExtendedNumber< ValueType > > ExtendedValueType
The type to use for values that may be infinite.
bool isNan(ValueType const &)
ValueType narrow(ExtendedValueType< ValueType > const &value)
Narrows an extended value back into the plain value type, for the interfaces that cannot hold an infi...
std::vector< ValueType > narrowFinite(std::vector< ExtendedValueType< ValueType > > &&values)
The counterpart of widen for a vector all of whose values are finite.
ValueType toSentinel(ExtendedValueType< ValueType > const &value)
The counterpart of fromSentinel: hands an extended value back to a part of Storm that still expects t...
typename detail::FiniteValueType< ValueType >::type FiniteValueType
The finite value type underlying a (possibly extended) type.
bool isInfinity(ValueType const &a)
ValueType const & getFinite(ExtendedNumber< ValueType > const &value)
TargetType convertNumber(SourceType const &number)
storm::utility::ExtendedValueType< RationalNumber > ExtendedRationalNumber
The rational number type extended with the two infinities.
storm::utility::ExtendedValueType< RationalFunction > ExtendedRationalFunction
The rational function type extended with the two infinities.
size_t operator()(storm::utility::ExtendedNumber< ValueType > const &number) const
static constexpr bool is_exact
static constexpr bool is_bounded
static constexpr bool is_integer
static constexpr bool is_specialized
static constexpr bool has_quiet_NaN
static constexpr bool has_signaling_NaN
static constexpr bool is_signed
static constexpr bool is_iec559
storm::utility::ExtendedNumber< ValueType > type
static constexpr bool has_infinity
static const bool HasInfinity
static const bool IsExact
static const bool SupportsExponential
static const bool SupportsExponential
static const bool HasInfinity
Whether the type can represent +/- infinity itself.
static const bool IsExact
The finite value type underlying a (possibly extended) type.