33#ifndef SVF_NUMERICVALUE_H
34#define SVF_NUMERICVALUE_H
41#define epsilon std::numeric_limits<double>::epsilon();
151 return expr._iVal == 0;
172 return rhs.is_plus_infinity();
181 return rhs.is_plus_infinity();
200 return rhs.is_minus_infinity();
209 return rhs.is_minus_infinity();
284 if ((
lhs.is_plus_infinity() &&
rhs.is_minus_infinity()) ||
285 (
lhs.is_minus_infinity() &&
rhs.is_plus_infinity()))
287 assert(
false &&
"invalid add");
292 if (
lhs.is_plus_infinity() ||
rhs.is_plus_infinity())
299 if (
lhs.is_minus_infinity() ||
rhs.is_minus_infinity())
306 if (
lhs._iVal > 0 &&
rhs._iVal > 0 &&
307 (std::numeric_limits<s64_t>::max() -
lhs._iVal) <
rhs._iVal)
314 if (
lhs._iVal < 0 &&
rhs._iVal < 0 &&
315 (-std::numeric_limits<s64_t>::max() -
lhs._iVal) >
rhs._iVal)
322 return lhs._iVal +
rhs._iVal;
367 if (
lhs._iVal == 0 ||
rhs._iVal == 0)
372 if (
lhs.is_infinity() ||
rhs.is_infinity())
377 if (
lhs._iVal *
rhs._iVal > 0)
389 if (
lhs._iVal > 0 &&
rhs._iVal > 0 &&
390 (std::numeric_limits<s64_t>::max() /
lhs._iVal) <
rhs._iVal)
397 if (
lhs._iVal < 0 &&
rhs._iVal < 0 &&
398 (std::numeric_limits<s64_t>::max() /
lhs._iVal) >
rhs._iVal)
406 if ((
lhs._iVal > 0 &&
rhs._iVal < 0 &&
407 (-std::numeric_limits<s64_t>::max() /
lhs._iVal) >
rhs._iVal) ||
408 (
lhs._iVal < 0 &&
rhs._iVal > 0 &&
409 (-std::numeric_limits<s64_t>::max() /
rhs._iVal) >
lhs._iVal))
416 return lhs._iVal *
rhs._iVal;
423 assert(
false &&
"divide by zero");
424 else if (!
lhs.is_infinity() && !
rhs.is_infinity())
425 return lhs._iVal %
rhs._iVal;
426 else if (!
lhs.is_infinity() &&
rhs.is_infinity())
429 else if (
lhs.is_infinity() && !
rhs.is_infinity())
450 assert(
false &&
"divide by zero");
453 else if (!
lhs.is_infinity() && !
rhs.is_infinity())
454 return lhs._iVal /
rhs._iVal;
455 else if (!
lhs.is_infinity() &&
rhs.is_infinity())
457 else if (
lhs.is_infinity() && !
rhs.is_infinity())
514 assert(
rhs.geq(0) &&
"rhs should be greater or equal than 0");
517 else if (
lhs.is_infinity())
519 else if (
rhs.is_infinity())
520 return lhs.geq(0) ? 0 : -1;
522 return lhs._iVal >>
rhs._iVal;
532 assert(
rhs.geq(0) &&
"rhs should be greater or equal than 0");
535 else if (
lhs.is_infinity())
537 else if (
rhs.is_infinity())
540 return lhs._iVal <<
rhs._iVal;
566 return lhs._iVal ==
rhs._iVal &&
lhs._isInf ==
rhs._isInf;
574 if (
lhs.is_minus_infinity() ||
rhs.is_minus_infinity())
576 else if(
lhs.is_plus_infinity())
578 else if(
rhs.is_plus_infinity())
590 if (
lhs.is_plus_infinity() ||
rhs.is_plus_infinity())
592 else if(
lhs.is_minus_infinity())
594 else if(
rhs.is_minus_infinity())
607 for (
const auto&
it :
_l)
609 if (
it.is_minus_infinity())
611 else if (!
it.geq(ret))
625 for (
const auto&
it :
_l)
627 if (
it.is_plus_infinity())
629 else if (!
it.leq(ret))
670 return std::numeric_limits<s64_t>::min();
676 return std::numeric_limits<s64_t>::max();
696 return std::to_string(
_iVal);
713 assert(
false &&
"cannot get real number for integer!");
719 assert(
false &&
"cannot get real number for integer!");
756 if (std::isinf(
a) && std::isinf(
b))
768 return _fVal == std::numeric_limits<double>::infinity();
773 return _fVal == -std::numeric_limits<double>::infinity();
793 return std::numeric_limits<double>::infinity();
798 return -std::numeric_limits<double>::infinity();
826 return rhs.is_plus_infinity();
834 return rhs.is_plus_infinity();
850 return rhs.is_minus_infinity();
858 return rhs.is_minus_infinity();
913 if ((
lhs == std::numeric_limits<double>::infinity() &&
914 rhs == -std::numeric_limits<double>::infinity()) ||
915 (
lhs == -std::numeric_limits<double>::infinity() &&
916 rhs == std::numeric_limits<double>::infinity()))
918 assert(
false &&
"invalid add");
924 if (res == std::numeric_limits<double>::infinity())
932 if (res == -std::numeric_limits<double>::infinity())
941 (std::numeric_limits<double>::max() -
lhs) <
rhs)
943 res = std::numeric_limits<double>::infinity();
952 (-std::numeric_limits<double>::max() -
lhs) >
rhs)
954 res = -std::numeric_limits<
997 if (res == std::numeric_limits<double>::infinity())
1005 if (res == -std::numeric_limits<double>::infinity())
1011 if (
lhs > 0 &&
rhs > 0 &&
1012 lhs > std::numeric_limits<double>::max() /
rhs)
1014 return std::numeric_limits<double>::infinity();
1016 if (
lhs < 0 &&
rhs < 0 &&
1017 lhs < std::numeric_limits<double>::max() /
rhs)
1019 return std::numeric_limits<double>::infinity();
1023 if (
lhs > 0 &&
rhs < 0 &&
1024 rhs < std::numeric_limits<double>::lowest() /
lhs)
1026 return -std::numeric_limits<double>::infinity();
1029 lhs < std::numeric_limits<double>::lowest() /
rhs)
1031 return -std::numeric_limits<double>::infinity();
1057 return (
lhs >= 0.0f) ? std::numeric_limits<double>::infinity()
1058 : -std::numeric_limits<double>::infinity();
1062 if (res == std::numeric_limits<double>::infinity())
1070 if (res == -std::numeric_limits<double>::infinity())
1077 if (
rhs > 0 &&
rhs < std::numeric_limits<double>::min() &&
1078 lhs > std::numeric_limits<double>::max() *
rhs)
1080 return std::numeric_limits<double>::infinity();
1083 lhs > std::numeric_limits<double>::max() *
rhs)
1085 return -std::numeric_limits<double>::infinity();
1101 assert(
false &&
"divide by zero");
1102 else if (!
lhs.is_infinity() && !
rhs.is_infinity())
1103 return std::fmod(
lhs._fVal,
rhs._fVal);
1104 else if (!
lhs.is_infinity() &&
rhs.is_infinity())
1107 else if (
lhs.is_infinity() && !
rhs.is_infinity())
1165 assert(
rhs.geq(0) &&
"rhs should be greater or equal than 0");
1168 else if (
lhs.is_infinity())
1170 else if (
rhs.is_infinity())
1171 return lhs.geq(0) ? 0 : -1;
1179 assert(
rhs.geq(0) &&
"rhs should be greater or equal than 0");
1182 else if (
lhs.is_infinity())
1184 else if (
rhs.is_infinity())
1193 return cond.
_fVal != 0.0f ?
lhs._fVal :
rhs._fVal;
1210 return std::min(
lhs._fVal,
rhs._fVal);
1215 return std::max(
lhs._fVal,
rhs._fVal);
1221 for (
const auto&
it :
_l)
1223 if (
it.is_minus_infinity())
1225 else if (!
it.geq(ret))
1236 for (
const auto&
it :
_l)
1238 if (
it.is_plus_infinity())
1240 else if (!
it.leq(ret))
1255 return _fVal != 0.0f;
1271 return std::round(
_fVal);
1287 return std::to_string(
_fVal);
BoundedDouble & operator=(const BoundedDouble &rhs)
friend BoundedDouble max(const BoundedDouble &lhs, const BoundedDouble &rhs)
friend BoundedDouble operator<(const BoundedDouble &lhs, const BoundedDouble &rhs)
friend BoundedDouble operator%(const BoundedDouble &lhs, const BoundedDouble &rhs)
const double getFVal() const
friend BoundedDouble operator>>(const BoundedDouble &lhs, const BoundedDouble &rhs)
static double safeDiv(double lhs, double rhs)
friend BoundedDouble operator*(const BoundedDouble &lhs, const BoundedDouble &rhs)
friend BoundedDouble operator==(const BoundedDouble &lhs, const BoundedDouble &rhs)
Reload operator.
static double safeMul(double lhs, double rhs)
static BoundedDouble minus_infinity()
friend BoundedDouble operator!(const BoundedDouble &lhs)
friend BoundedDouble ite(const BoundedDouble &cond, const BoundedDouble &lhs, const BoundedDouble &rhs)
friend BoundedDouble operator>(const BoundedDouble &lhs, const BoundedDouble &rhs)
static BoundedDouble plus_infinity()
friend BoundedDouble operator&&(const BoundedDouble &lhs, const BoundedDouble &rhs)
bool equal(const BoundedDouble &rhs) const
BoundedDouble & operator=(BoundedDouble &&rhs)
void set_minus_infinity()
s64_t getIntNumeral() const
friend BoundedDouble operator<=(const BoundedDouble &lhs, const BoundedDouble &rhs)
static bool isZero(const BoundedDouble &expr)
static bool doubleEqual(double a, double b)
bool geq(const BoundedDouble &rhs) const
friend BoundedDouble operator-(const BoundedDouble &lhs)
friend BoundedDouble operator-(const BoundedDouble &lhs, const BoundedDouble &rhs)
s64_t getNumeral() const
Return Numeral.
friend BoundedDouble operator|(const BoundedDouble &lhs, const BoundedDouble &rhs)
friend BoundedDouble min(const BoundedDouble &lhs, const BoundedDouble &rhs)
friend BoundedDouble operator^(const BoundedDouble &lhs, const BoundedDouble &rhs)
friend BoundedDouble operator>=(const BoundedDouble &lhs, const BoundedDouble &rhs)
static double safeAdd(double lhs, double rhs)
friend BoundedDouble abs(const BoundedDouble &lhs)
friend BoundedDouble operator<<(const BoundedDouble &lhs, const BoundedDouble &rhs)
friend BoundedDouble operator/(const BoundedDouble &lhs, const BoundedDouble &rhs)
friend BoundedDouble operator!=(const BoundedDouble &lhs, const BoundedDouble &rhs)
friend bool eq(const BoundedDouble &lhs, const BoundedDouble &rhs)
static BoundedDouble min(std::vector< BoundedDouble > &_l)
friend BoundedDouble operator+(const BoundedDouble &lhs, const BoundedDouble &rhs)
BoundedDouble(const BoundedDouble &rhs)
bool is_minus_infinity() const
BoundedDouble(BoundedDouble &&rhs)
bool leq(const BoundedDouble &rhs) const
bool is_plus_infinity() const
virtual const std::string to_string() const
static BoundedDouble max(std::vector< BoundedDouble > &_l)
friend BoundedDouble operator&(const BoundedDouble &lhs, const BoundedDouble &rhs)
double getRealNumeral() const
BoundedDouble(double fVal)
friend BoundedDouble operator||(const BoundedDouble &lhs, const BoundedDouble &rhs)
friend std::ostream & operator<<(std::ostream &out, const BoundedDouble &expr)
A class representing a bounded 64-bit integer.
friend BoundedInt operator>=(const BoundedInt &lhs, const BoundedInt &rhs)
static BoundedInt plus_infinity()
friend BoundedInt operator||(const BoundedInt &lhs, const BoundedInt &rhs)
friend BoundedInt operator<=(const BoundedInt &lhs, const BoundedInt &rhs)
friend BoundedInt ite(const BoundedInt &cond, const BoundedInt &lhs, const BoundedInt &rhs)
bool is_minus_infinity() const
friend BoundedInt operator!=(const BoundedInt &lhs, const BoundedInt &rhs)
s64_t getNumeral() const
Retrieves the numeral value of the BoundedInt object.
bool is_plus_infinity() const
friend BoundedInt operator%(const BoundedInt &lhs, const BoundedInt &rhs)
friend BoundedInt operator<<(const BoundedInt &lhs, const BoundedInt &rhs)
static BoundedInt min(std::vector< BoundedInt > &_l)
friend BoundedInt operator&(const BoundedInt &lhs, const BoundedInt &rhs)
static BoundedInt safeMul(const BoundedInt &lhs, const BoundedInt &rhs)
Performs safe multiplication of two BoundedInt objects.
const double getFVal() const
friend BoundedInt operator*(const BoundedInt &lhs, const BoundedInt &rhs)
friend BoundedInt abs(const BoundedInt &lhs)
BoundedInt(BoundedInt &&rhs)
friend BoundedInt operator|(const BoundedInt &lhs, const BoundedInt &rhs)
friend BoundedInt operator/(const BoundedInt &lhs, const BoundedInt &rhs)
friend BoundedInt max(const BoundedInt &lhs, const BoundedInt &rhs)
s64_t getIntNumeral() const
friend BoundedInt operator+(const BoundedInt &lhs, const BoundedInt &rhs)
friend BoundedInt operator>>(const BoundedInt &lhs, const BoundedInt &rhs)
friend BoundedInt operator!(const BoundedInt &lhs)
friend BoundedInt operator^(const BoundedInt &lhs, const BoundedInt &rhs)
friend BoundedInt operator&&(const BoundedInt &lhs, const BoundedInt &rhs)
BoundedInt & operator=(const BoundedInt &rhs)
friend std::ostream & operator<<(std::ostream &out, const BoundedInt &expr)
static BoundedInt max(std::vector< BoundedInt > &_l)
friend bool eq(const BoundedInt &lhs, const BoundedInt &rhs)
static BoundedInt safeAdd(const BoundedInt &lhs, const BoundedInt &rhs)
static BoundedInt minus_infinity()
friend BoundedInt min(const BoundedInt &lhs, const BoundedInt &rhs)
bool geq(const BoundedInt &rhs) const
friend BoundedInt operator<(const BoundedInt &lhs, const BoundedInt &rhs)
bool equal(const BoundedInt &rhs) const
friend BoundedInt operator==(const BoundedInt &lhs, const BoundedInt &rhs)
Reload operator.
BoundedInt & operator=(BoundedInt &&rhs)
bool leq(const BoundedInt &rhs) const
static bool isZero(const BoundedInt &expr)
double getRealNumeral() const
friend BoundedInt operator>(const BoundedInt &lhs, const BoundedInt &rhs)
BoundedInt(s64_t fVal, bool isInf)
void set_minus_infinity()
friend BoundedInt operator-(const BoundedInt &lhs)
friend BoundedInt operator-(const BoundedInt &lhs, const BoundedInt &rhs)
BoundedInt(const BoundedInt &rhs)
virtual const std::string to_string() const
llvm::IRBuilder IRBuilder