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())
449 assert(
false &&
"divide by zero");
450 else if (!
lhs.is_infinity() && !
rhs.is_infinity())
451 return lhs._iVal /
rhs._iVal;
452 else if (!
lhs.is_infinity() &&
rhs.is_infinity())
454 else if (
lhs.is_infinity() && !
rhs.is_infinity())
511 assert(
rhs.geq(0) &&
"rhs should be greater or equal than 0");
514 else if (
lhs.is_infinity())
516 else if (
rhs.is_infinity())
517 return lhs.geq(0) ? 0 : -1;
519 return lhs._iVal >>
rhs._iVal;
529 assert(
rhs.geq(0) &&
"rhs should be greater or equal than 0");
532 else if (
lhs.is_infinity())
534 else if (
rhs.is_infinity())
537 return lhs._iVal <<
rhs._iVal;
563 return lhs._iVal ==
rhs._iVal &&
lhs._isInf ==
rhs._isInf;
571 if (
lhs.is_minus_infinity() ||
rhs.is_minus_infinity())
573 else if(
lhs.is_plus_infinity())
575 else if(
rhs.is_plus_infinity())
587 if (
lhs.is_plus_infinity() ||
rhs.is_plus_infinity())
589 else if(
lhs.is_minus_infinity())
591 else if(
rhs.is_minus_infinity())
604 for (
const auto&
it :
_l)
606 if (
it.is_minus_infinity())
608 else if (!
it.geq(ret))
622 for (
const auto&
it :
_l)
624 if (
it.is_plus_infinity())
626 else if (!
it.leq(ret))
667 return std::numeric_limits<s64_t>::min();
673 return std::numeric_limits<s64_t>::max();
693 return std::to_string(
_iVal);
710 assert(
false &&
"cannot get real number for integer!");
716 assert(
false &&
"cannot get real number for integer!");
753 if (std::isinf(
a) && std::isinf(
b))
765 return _fVal == std::numeric_limits<double>::infinity();
770 return _fVal == -std::numeric_limits<double>::infinity();
790 return std::numeric_limits<double>::infinity();
795 return -std::numeric_limits<double>::infinity();
823 return rhs.is_plus_infinity();
831 return rhs.is_plus_infinity();
847 return rhs.is_minus_infinity();
855 return rhs.is_minus_infinity();
910 if ((
lhs == std::numeric_limits<double>::infinity() &&
911 rhs == -std::numeric_limits<double>::infinity()) ||
912 (
lhs == -std::numeric_limits<double>::infinity() &&
913 rhs == std::numeric_limits<double>::infinity()))
915 assert(
false &&
"invalid add");
921 if (res == std::numeric_limits<double>::infinity())
929 if (res == -std::numeric_limits<double>::infinity())
938 (std::numeric_limits<double>::max() -
lhs) <
rhs)
940 res = std::numeric_limits<double>::infinity();
949 (-std::numeric_limits<double>::max() -
lhs) >
rhs)
951 res = -std::numeric_limits<
994 if (res == std::numeric_limits<double>::infinity())
1002 if (res == -std::numeric_limits<double>::infinity())
1008 if (
lhs > 0 &&
rhs > 0 &&
1009 lhs > std::numeric_limits<double>::max() /
rhs)
1011 return std::numeric_limits<double>::infinity();
1013 if (
lhs < 0 &&
rhs < 0 &&
1014 lhs < std::numeric_limits<double>::max() /
rhs)
1016 return std::numeric_limits<double>::infinity();
1020 if (
lhs > 0 &&
rhs < 0 &&
1021 rhs < std::numeric_limits<double>::lowest() /
lhs)
1023 return -std::numeric_limits<double>::infinity();
1026 lhs < std::numeric_limits<double>::lowest() /
rhs)
1028 return -std::numeric_limits<double>::infinity();
1054 return (
lhs >= 0.0f) ? std::numeric_limits<double>::infinity()
1055 : -std::numeric_limits<double>::infinity();
1059 if (res == std::numeric_limits<double>::infinity())
1067 if (res == -std::numeric_limits<double>::infinity())
1074 if (
rhs > 0 &&
rhs < std::numeric_limits<double>::min() &&
1075 lhs > std::numeric_limits<double>::max() *
rhs)
1077 return std::numeric_limits<double>::infinity();
1080 lhs > std::numeric_limits<double>::max() *
rhs)
1082 return -std::numeric_limits<double>::infinity();
1098 assert(
false &&
"divide by zero");
1099 else if (!
lhs.is_infinity() && !
rhs.is_infinity())
1100 return std::fmod(
lhs._fVal,
rhs._fVal);
1101 else if (!
lhs.is_infinity() &&
rhs.is_infinity())
1104 else if (
lhs.is_infinity() && !
rhs.is_infinity())
1162 assert(
rhs.geq(0) &&
"rhs should be greater or equal than 0");
1165 else if (
lhs.is_infinity())
1167 else if (
rhs.is_infinity())
1168 return lhs.geq(0) ? 0 : -1;
1176 assert(
rhs.geq(0) &&
"rhs should be greater or equal than 0");
1179 else if (
lhs.is_infinity())
1181 else if (
rhs.is_infinity())
1190 return cond.
_fVal != 0.0f ?
lhs._fVal :
rhs._fVal;
1207 return std::min(
lhs._fVal,
rhs._fVal);
1212 return std::max(
lhs._fVal,
rhs._fVal);
1218 for (
const auto&
it :
_l)
1220 if (
it.is_minus_infinity())
1222 else if (!
it.geq(ret))
1233 for (
const auto&
it :
_l)
1235 if (
it.is_plus_infinity())
1237 else if (!
it.leq(ret))
1252 return _fVal != 0.0f;
1268 return std::round(
_fVal);
1284 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