-
-
Notifications
You must be signed in to change notification settings - Fork 60
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
1 parent
b3a3c2d
commit 80a8e49
Showing
9 changed files
with
758 additions
and
0 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,40 @@ | ||
#pragma once | ||
// attributes.hpp: information functions for two-parameter number and value attributes | ||
// | ||
// Copyright (C) 2017 Stillwater Supercomputing, Inc. | ||
// | ||
// This file is part of the universal numbers project, which is released under an MIT Open Source license. | ||
#include <cmath> // for std:pow() | ||
|
||
namespace sw { namespace universal { | ||
|
||
// functions to provide details about | ||
// the properties of the number system configuration | ||
// in terms of native types. | ||
// Since many number system configurations cannot be represented by | ||
// native types, these are all convenience functions. | ||
// They should not be used for the core algorithms. | ||
|
||
// free function sign | ||
template<unsigned nbits, unsigned es, typename bt> | ||
bool sign(const twoparam<nbits, bt>& v) { | ||
return v.sign(); | ||
} | ||
|
||
// generate the maxneg through maxpos value range of a logarithmic number system configuration | ||
// the type of arithmetic, Modulo or Saturating, does not affect the range | ||
template<unsigned nbits, unsigned es, typename bt> | ||
std::string twoparam_range(const twoparam<nbits, bt) { | ||
using TWOPARAM = twoparam<nbits, bt>; | ||
std::stringstream s; | ||
TWOPARAM l; | ||
s << std::setw(45) << type_tag(v) << " : [ " | ||
<< l.maxneg() << " ... " | ||
<< l.minneg() << " " | ||
<< "0 " | ||
<< l.minpos() << " ... " | ||
<< l.maxpos() << " ]"; | ||
return s.str(); | ||
} | ||
|
||
}} // namespace sw::universal |
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,74 @@ | ||
#pragma once | ||
// exceptions.hpp: exception hierarchy for exceptions during posit calculations | ||
// | ||
// Copyright (C) 2017 Stillwater Supercomputing, Inc. | ||
// | ||
// This file is part of the universal numbers project, which is released under an MIT Open Source license. | ||
#include <universal/common/exceptions.hpp> | ||
|
||
namespace sw { namespace universal { | ||
|
||
/////////////////////////////////////////////////////////////////////////////////////////////////// | ||
/// POSIT ARITHMETIC EXCEPTIONS | ||
|
||
// base class for posit arithmetic exceptions | ||
struct posit_arithmetic_exception : public universal_arithmetic_exception { | ||
posit_arithmetic_exception(const std::string& error) | ||
: universal_arithmetic_exception(std::string("posit arithmetic exception: ") + error) {}; | ||
}; | ||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////// | ||
/// specialized exceptions to aid application level exception handling | ||
|
||
// not_a_real is thrown when a rvar is NaR | ||
struct posit_nar : public posit_arithmetic_exception { | ||
posit_nar() : posit_arithmetic_exception("nar (not a real)") {} | ||
}; | ||
|
||
// divide_by_zero is thrown when the denominator in a division operator is 0 | ||
struct posit_divide_by_zero : public posit_arithmetic_exception { | ||
posit_divide_by_zero() : posit_arithmetic_exception("divide by zero") {} | ||
}; | ||
|
||
// divide_by_nar is thrown when the denominator in a division operator is NaR | ||
struct posit_divide_by_nar : public posit_arithmetic_exception { | ||
posit_divide_by_nar() : posit_arithmetic_exception("divide by nar") {} | ||
}; | ||
|
||
// numerator_is_nar is thrown when the numerator in a division operator is NaR | ||
struct posit_numerator_is_nar : public posit_arithmetic_exception { | ||
posit_numerator_is_nar() : posit_arithmetic_exception("numerator is nar") {} | ||
}; | ||
|
||
// operand_is_nar is thrown when an rvar in a binary operator is NaR | ||
struct posit_operand_is_nar : public posit_arithmetic_exception { | ||
posit_operand_is_nar() : posit_arithmetic_exception("operand is nar") {} | ||
}; | ||
|
||
// thrown when division yields no signficant fraction bits | ||
struct posit_division_result_is_zero : public posit_arithmetic_exception { | ||
posit_division_result_is_zero() : posit_arithmetic_exception("division yielded no significant bits") {} | ||
}; | ||
|
||
// thrown when division yields NaR | ||
struct posit_division_result_is_infinite : public posit_arithmetic_exception { | ||
posit_division_result_is_infinite() : posit_arithmetic_exception("division yielded infinite") {} | ||
}; | ||
|
||
/////////////////////////////////////////////////////////////////////////////////////////////////// | ||
/// POSIT INTERNAL OPERATION EXCEPTIONS | ||
|
||
struct posit_internal_exception : public universal_internal_exception { | ||
posit_internal_exception(const std::string& error) | ||
: universal_internal_exception(std::string("posit internal exception: ") + error) {}; | ||
}; | ||
|
||
struct posit_hpos_too_large : public posit_internal_exception { | ||
posit_hpos_too_large() : posit_internal_exception("position of hidden bit too large for given posit") {} | ||
}; | ||
|
||
struct posit_rbits_too_large : public posit_internal_exception { | ||
posit_rbits_too_large() :posit_internal_exception("number of remaining bits too large for this fraction") {} | ||
}; | ||
|
||
}} // namespace sw::universal |
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,75 @@ | ||
#pragma once | ||
// exceptions.hpp: exception hierarchy for exceptions during arithmetic calculations | ||
// | ||
// Copyright (C) 2017 Stillwater Supercomputing, Inc. | ||
// | ||
// This file is part of the universal numbers project, which is released under an MIT Open Source license. | ||
#include <universal/common/exceptions.hpp> | ||
|
||
namespace sw { namespace universal { | ||
|
||
/////////////////////////////////////////////////////////////////////////////////////////////////// | ||
/// BASE ARITHMETIC EXCEPTIONS | ||
|
||
// base class for twoparam arithmetic exceptions | ||
struct twoparam_arithmetic_exception : public universal_arithmetic_exception { | ||
twoparam_arithmetic_exception(const std::string& error) | ||
: universal_arithmetic_exception(std::string("twoparam arithmetic exception: ") + error) {}; | ||
}; | ||
|
||
////////////////////////////////////////////////////////////////////////////////////////////////// | ||
/// specialized exceptions to aid application level exception handling | ||
|
||
// not_a_real is thrown when a rvar is NaR | ||
struct twoparam_nar : public twoparam_arithmetic_exception { | ||
twoparam_nar() : twoparam_arithmetic_exception("nar (not a real)") {} | ||
}; | ||
|
||
// divide_by_zero is thrown when the denominator in a division operator is 0 | ||
struct twoparam_divide_by_zero : public twoparam_arithmetic_exception { | ||
twoparam_divide_by_zero() : twoparam_arithmetic_exception("divide by zero") {} | ||
}; | ||
|
||
// divide_by_nar is thrown when the denominator in a division operator is NaR | ||
struct twoparam_divide_by_nar : public twoparam_arithmetic_exception { | ||
twoparam_divide_by_nar() : twoparam_arithmetic_exception("divide by nar") {} | ||
}; | ||
|
||
// numerator_is_nar is thrown when the numerator in a division operator is NaR | ||
struct twoparam_numerator_is_nar : public twoparam_arithmetic_exception { | ||
twoparam_numerator_is_nar() : twoparam_arithmetic_exception("numerator is nar") {} | ||
}; | ||
|
||
// operand_is_nar is thrown when an rvar in a binary operator is NaR | ||
struct twoparam_operand_is_nar : public twoparam_arithmetic_exception { | ||
twoparam_operand_is_nar() : twoparam_arithmetic_exception("operand is nar") {} | ||
}; | ||
|
||
// thrown when division yields no signficant fraction bits | ||
struct twoparam_division_result_is_zero : public twoparam_arithmetic_exception { | ||
twoparam_division_result_is_zero() : twoparam_arithmetic_exception("division yielded no significant bits") {} | ||
}; | ||
|
||
// thrown when division yields NaR | ||
struct twoparam_division_result_is_nar : public twoparam_arithmetic_exception { | ||
twoparam_division_result_is_nar() : twoparam_arithmetic_exception("division yielded nar") {} | ||
}; | ||
|
||
/////////////////////////////////////////////////////////////////////////////////////////////////// | ||
/// INTERNAL OPERATION EXCEPTIONS | ||
|
||
struct twoparam_internal_exception : public universal_internal_exception { | ||
twoparam_internal_exception(const std::string& error) | ||
: universal_internal_exception(std::string("twoparam internal exception: ") + error) {}; | ||
}; | ||
|
||
struct twoparam_hpos_too_large : public twoparam_internal_exception { | ||
twoparam_hpos_too_large() : twoparam_internal_exception("twoparamion of hidden bit too large for given twoparam") {} | ||
}; | ||
|
||
struct twoparam_rbits_too_large : public twoparam_internal_exception { | ||
twoparam_rbits_too_large() :twoparam_internal_exception("number of remaining bits too large for this fraction") {} | ||
}; | ||
|
||
|
||
}} // namespace sw::universal |
87 changes: 87 additions & 0 deletions
87
include/universal/number/skeleton_2params/manipulators.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,87 @@ | ||
#pragma once | ||
// manipulators.hpp: definitions of helper functions for twoparam numbers manipulation | ||
// | ||
// Copyright (C) 2017-2023 Stillwater Supercomputing, Inc. | ||
// | ||
// This file is part of the universal numbers project, which is released under an MIT Open Source license. | ||
#include <iostream> | ||
#include <iomanip> | ||
#include <typeinfo> // for typeid() | ||
|
||
// pull in the color printing for shells utility | ||
#include <universal/utility/color_print.hpp> | ||
|
||
namespace sw { namespace universal { | ||
|
||
// Generate a type tag for this twoparam | ||
template<typename TwoParamType, | ||
std::enable_if_t< is_twoparam<TwoParamType>, bool> = true | ||
> | ||
inline std::string type_tag(const TwoParamType & = {}) { | ||
std::stringstream s; | ||
typename TwoParamType::BlockType bt{0}; | ||
s << "twoparam<" | ||
<< std::setw(3) << TwoParamType::nbits << ", " | ||
<< std::setw(3) << TwoParamType::es << ", " | ||
<< type_tag(bt) << ", " | ||
<< std::setw(10) << type_tag(Behavior{ TwoParamType::behavior }) << '>'; | ||
return s.str(); | ||
} | ||
|
||
template<typename TwoParamType, | ||
std::enable_if_t< is_twoparam<TwoParamType>, bool> = true | ||
> | ||
inline std::string range(const TwoParamType & = {}) { | ||
std::stringstream s; | ||
TwoParamType b(SpecificValue::maxneg), c(SpecificValue::minneg), d(SpecificValue::minpos), e(SpecificValue::maxpos); | ||
s << "[" << b << " ... " << c << ", 0, " << d << " ... " << e << "]\n"; | ||
return s.str(); | ||
} | ||
|
||
// report if a native floating-point value is within the dynamic range of the twoparam configuration | ||
template<typename TwoParamType, | ||
std::enable_if_t< is_twoparam<TwoParamType>, bool> = true | ||
> | ||
inline bool isInRange(double v) { | ||
TwoParamType a{}; | ||
|
||
bool inside = true; | ||
if (v > double(a.maxpos()) || v < double(a.maxneg())) inside = false; | ||
return inside; | ||
} | ||
|
||
template<typename TwoParamType, | ||
std::enable_if_t< is_twoparam<TwoParamType>, bool> = true | ||
> | ||
inline std::string color_print(const TwoParamType& l, bool nibbleMarker = false) { | ||
|
||
std::stringstream s; | ||
|
||
Color red(ColorCode::FG_RED); | ||
Color yellow(ColorCode::FG_YELLOW); | ||
Color blue(ColorCode::FG_BLUE); | ||
Color magenta(ColorCode::FG_MAGENTA); | ||
Color cyan(ColorCode::FG_CYAN); | ||
Color white(ColorCode::FG_WHITE); | ||
Color def(ColorCode::FG_DEFAULT); | ||
s << red << (l.sign() ? "1" : "0"); | ||
|
||
// integer bits | ||
for (int i = static_cast<int>(TwoParamType::nbits) - 2; i >= static_cast<int>(TwoParamType::rbits); --i) { | ||
s << cyan << (l.at(static_cast<unsigned>(i)) ? '1' : '0'); | ||
if ((i - TwoParamType::rbits) > 0 && ((i - TwoParamType::rbits) % 4) == 0 && nibbleMarker) s << yellow << '\''; | ||
} | ||
|
||
// fraction bits | ||
if constexpr (TwoParamType::rbits > 0) { | ||
s << magenta << '.'; | ||
for (int i = static_cast<int>(TwoParamType::rbits) - 1; i >= 0; --i) { | ||
s << magenta << (l.at(static_cast<unsigned>(i)) ? '1' : '0'); | ||
if (i > 0 && (i % 4) == 0 && nibbleMarker) s << yellow << '\''; | ||
} | ||
} | ||
s << def; | ||
return s.str(); | ||
} | ||
|
||
}} // namespace sw::universal |
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,72 @@ | ||
#pragma once | ||
// mathlib.hpp: elementary functions for the twoparam number system | ||
// | ||
// Copyright (C) 2017 Stillwater Supercomputing, Inc. | ||
// | ||
// This file is part of the universal numbers project, which is released under an MIT Open Source license. | ||
|
||
/* | ||
https://en.wikipedia.org/wiki/Elementary_function | ||
In mathematics, an elementary function is a function of one variable which is a finite sum, | ||
product, and/or comtwoparamion of the rational functions (P(x)/Q(x) for polynomials P and Q), | ||
sin, cos, exp, and their inverse functions (including arcsin, log, x^(1/n)). | ||
Elementary functions were introduced by Joseph Liouville in a series of papers from 1833 to 1841. | ||
An algebraic treatment of elementary functions was started by Joseph Fels Ritt in the 1930s. | ||
*/ | ||
#include <universal/number/twoparam/math/classify.hpp> | ||
#include <universal/number/twoparam/math/complex.hpp> | ||
#include <universal/number/twoparam/math/error_and_gamma.hpp> | ||
#include <universal/number/twoparam/math/exponent.hpp> | ||
#include <universal/number/twoparam/math/fractional.hpp> | ||
#include <universal/number/twoparam/math/hyperbolic.hpp> | ||
#include <universal/number/twoparam/math/hypot.hpp> | ||
#include <universal/number/twoparam/math/logarithm.hpp> | ||
#include <universal/number/twoparam/math/minmax.hpp> | ||
#include <universal/number/twoparam/math/next.hpp> | ||
#include <universal/number/twoparam/math/pow.hpp> | ||
#include <universal/number/twoparam/math/sqrt.hpp> | ||
#include <universal/number/twoparam/math/trigonometry.hpp> | ||
#include <universal/number/twoparam/math/truncate.hpp> | ||
|
||
namespace sw { namespace universal { | ||
////////////////////////////////////////////////////////////////////////// | ||
|
||
// calculate the integer power a ^ b | ||
// exponentiation by squaring is the standard method for modular exponentiation of large numbers in asymmetric cryptography | ||
template<unsigned nbits, unsigned es, typename BlockType> | ||
twoparam<nbits, es, BlockType> ipow(const twoparam<nbits, es, BlockType>& a, const twoparam<nbits, es, BlockType>& b) { | ||
// precondition | ||
if (!a.isinteger() || !b.isinteger()) return twoparam<nbits, es, BlockType>(0); | ||
|
||
// TODO: using uint64_t as ipow constraints dynamic range | ||
uint64_t result(1); | ||
uint64_t base = uint64_t(a); | ||
uint64_t exp = uint64_t(b); | ||
for (;;) { | ||
if (exp & 0x1) result *= base; | ||
exp >>= 1; | ||
if (exp == 0) break; | ||
base *= base; | ||
} | ||
return twoparam<nbits, BlockType>(result); | ||
} | ||
|
||
// clang <complex> implementation is calling these functions so we need implementations for twoparam | ||
|
||
// already defined in math/classify.hpp | ||
//template<unsigned nbits, unsigned es> | ||
//inline bool isnan(const twoparam<nbits, es>& p) { return p.isnar(); } | ||
// | ||
//template<unsigned nbits, unsigned es> | ||
//inline bool isinf(const twoparam<nbits, es>& p) { return p.isnar(); } | ||
|
||
// copysign returns a value with the magnitude of a, and the sign of b | ||
template<unsigned nbits, unsigned es, typename BlockType> | ||
inline twoparam<nbits, es, BlockType> copysign(const twoparam<nbits, es, BlockType>& a, const twoparam<nbits, es, BlockType>& b) { | ||
twoparam<nbits, es, BlockType> c(a); | ||
if (a.sign() == b.sign()) return c; | ||
return -c; | ||
} | ||
}} |
Oops, something went wrong.