z3-z3-4.13.0.src.util.hwf.h Maven / Gradle / Ivy
The newest version!
/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
hwf.h
Abstract:
Hardware Floating Point Numbers
Author:
Christoph Wintersteiger (cwinter) 2012-07-30.
Revision History:
--*/
#pragma once
#include
#include
#include "util/mpz.h"
#include "util/mpq.h"
#include "util/mpf.h"
class hwf {
friend class hwf_manager;
double value;
uint64_t get_raw() const {
uint64_t n;
SASSERT(sizeof(n) == sizeof(value));
memcpy(&n, &value, sizeof(value));
return n;
}
public:
void swap(hwf & other) noexcept { std::swap(value, other.value); }
};
class hwf_manager {
unsynch_mpq_manager m_mpq_manager;
unsynch_mpz_manager & m_mpz_manager; // A mpq_manager is a mpz_manager, reusing it.
public:
typedef hwf numeral;
hwf_manager();
~hwf_manager();
void reset(hwf & o) { set(o, 0); }
void set(hwf & o, int value);
void set(hwf & o, mpf_rounding_mode rm, int n, int d);
void set(hwf & o, float value);
void set(hwf & o, double value);
void set(hwf & o, mpf_rounding_mode rm, mpq const & value);
void set(hwf & o, mpf_rounding_mode rm, char const * value);
void set(hwf & o, mpf_rounding_mode rm, mpq const & significand, mpz const & exponent);
void set(hwf & o, bool sign, uint64_t significand, int exponent);
void set(hwf & o, hwf const & x);
// auxiliary methods to make the interface compatible with mpf
void reset(hwf & o, unsigned ebits, unsigned sbits) { set(o, 0); }
void set(hwf & o, unsigned ebits, unsigned sbits, mpf_rounding_mode rm, mpq const & value) { set(o, rm, value); }
void set(hwf & o, unsigned ebits, unsigned sbits, int value) { set(o, value); }
void set(hwf & o, unsigned ebits, unsigned sbits, mpf_rounding_mode rm, int n, int d) { set(o, rm, n, d); }
void set(hwf & o, unsigned ebits, unsigned sbits, float value) { set(o, value); }
void set(hwf & o, unsigned ebits, unsigned sbits, double value) { set(o, value); }
void del(hwf & x) {}
void abs(hwf & o);
void abs(hwf const & x, hwf & o);
void neg(hwf & o);
void neg(hwf const & x, hwf & o);
bool is_zero(hwf const & x);
bool is_neg(hwf const & x);
bool is_pos(hwf const & x);
bool is_nzero(hwf const & x);
bool is_pzero(hwf const & x);
bool is_one(hwf const & x);
bool eq(hwf const & x, hwf const & y);
bool lt(hwf const & x, hwf const & y);
bool lte(hwf const & x, hwf const & y);
bool le(hwf const & x, hwf const & y) { return lte(x, y); }
bool gt(hwf const & x, hwf const & y);
bool gte(hwf const & x, hwf const & y);
bool ge(hwf const & x, hwf const & y) { return gte(x, y); }
void add(mpf_rounding_mode rm, hwf const & x, hwf const & y, hwf & o);
void sub(mpf_rounding_mode rm, hwf const & x, hwf const & y, hwf & o);
void mul(mpf_rounding_mode rm, hwf const & x, hwf const & y, hwf & o);
void div(mpf_rounding_mode rm, hwf const & x, hwf const & y, hwf & o);
void fma(mpf_rounding_mode rm, hwf const & x, hwf const & y, hwf const &z, hwf & o);
void sqrt(mpf_rounding_mode rm, hwf const & x, hwf & o);
void round_to_integral(mpf_rounding_mode rm, hwf const & x, hwf & o);
void rem(hwf const & x, hwf const & y, hwf & o);
void maximum(hwf const & x, hwf const & y, hwf & o);
void minimum(hwf const & x, hwf const & y, hwf & o);
std::string to_string(hwf const & a);
std::string to_rational_string(hwf const & a);
void display_decimal(std::ostream & out, hwf const & a, unsigned k);
void display_smt2(std::ostream & out, hwf const & a, bool decimal);
double to_double(hwf const & x) { return x.value; }
float to_float(hwf const & x) { return (float) x.value; }
void to_rational(hwf const & x, unsynch_mpq_manager & qm, mpq & o);
void to_rational(hwf const & x, scoped_mpq & o) { to_rational(x, o.m(), o); }
bool sgn(hwf const & x) const {
return (x.get_raw() & 0x8000000000000000ull) != 0;
}
uint64_t sig(hwf const & x) const {
return x.get_raw() & 0x000FFFFFFFFFFFFFull;
}
int exp(hwf const & x) const {
return ((x.get_raw() & 0x7FF0000000000000ull) >> 52) - 1023;
}
bool is_nan(hwf const & x);
bool is_inf(hwf const & x);
bool is_pinf(hwf const & x);
bool is_ninf(hwf const & x);
bool is_normal(hwf const & x);
bool is_denormal(hwf const & x);
bool is_regular(hwf const & x);
bool is_int(hwf const & x);
void mk_zero(bool sign, hwf & o);
void mk_nzero(hwf & o);
void mk_pzero(hwf & o);
void mk_nan(hwf & o);
void mk_inf(bool sign, hwf & o);
void mk_pinf(hwf & o);
void mk_ninf(hwf & o);
unsigned hash(hwf const & a) { return hash_ull(a.get_raw()); }
inline void set_rounding_mode(mpf_rounding_mode rm);
/**
\brief Return the biggest k s.t. 2^k <= a.
\remark Return 0 if a is not positive.
*/
unsigned prev_power_of_two(hwf const & a);
protected:
#ifdef _WINDOWS
unsigned x86_state, sse2_state;
#endif
};
typedef _scoped_numeral scoped_hwf;
typedef _scoped_numeral_vector scoped_hwf_vector;