OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Int128 Class Reference

#include </home/runner/work/OrcaSlicer/OrcaSlicer/src/libslic3r/Int128.hpp>

Static Public Member Functions

static int sign_determinant_2x2_filtered (int64_t a11, int64_t a12, int64_t a21, int64_t a22)
static int compare_rationals_filtered (int64_t p1, int64_t q1, int64_t p2, int64_t q2)

Private Member Functions

 Int128 (int64_t lo=0)
 Int128 (const int64_t &hi, const uint64_t &lo)
Int128 & operator= (const int64_t &val)
uint64_t lo () const
int64_t hi () const
int sign () const
bool operator== (const Int128 &val) const
bool operator!= (const Int128 &val) const
bool operator> (const Int128 &val) const
bool operator< (const Int128 &val) const
bool operator>= (const Int128 &val) const
bool operator<= (const Int128 &val) const
Int128 & operator+= (const Int128 &rhs)
Int128 operator+ (const Int128 &rhs) const
Int128 & operator-= (const Int128 &rhs)
Int128 operator- (const Int128 &rhs) const
Int128 operator- () const
 operator double () const

Static Private Member Functions

static Int128 multiply (int64_t lhs, int64_t rhs)
static int sign_determinant_2x2 (int64_t a11, int64_t a12, int64_t a21, int64_t a22)
static int compare_rationals (int64_t p1, int64_t q1, int64_t p2, int64_t q2)

Private Attributes

uint64_t m_lo
int64_t m_hi

Detailed Description

Constructor & Destructor Documentation

◆ Int128() [1/2]

Int128::Int128 ( int64_t lo = 0)
inlineprivate
127: m_lo((uint64_t)lo), m_hi((lo < 0) ? -1 : 0) {}
uint64_t m_lo
Definition Int128.hpp:248
uint64_t lo() const
Definition Int128.hpp:137
int64_t m_hi
Definition Int128.hpp:249

References lo(), m_hi, and m_lo.

Referenced by compare_rationals(), multiply(), operator!=(), operator+(), operator+=(), operator-(), operator-(), operator-=(), operator<(), operator<=(), operator=(), operator==(), operator>(), and operator>=().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Int128() [2/2]

Int128::Int128 ( const int64_t & hi,
const uint64_t & lo )
inlineprivate
128: m_lo(lo), m_hi(hi) {}
int64_t hi() const
Definition Int128.hpp:138

References hi(), lo(), m_hi, and m_lo.

Here is the call graph for this function:

Member Function Documentation

◆ compare_rationals()

int Int128::compare_rationals ( int64_t p1,
int64_t q1,
int64_t p2,
int64_t q2 )
inlinestaticprivate
241 {
242 int invert = ((q1 < 0) == (q2 < 0)) ? 1 : -1;
243 Int128 det = Int128::multiply(p1, q2) - Int128::multiply(p2, q1);
244 return det.sign() * invert;
245 }
int sign() const
Definition Int128.hpp:139
static Int128 multiply(int64_t lhs, int64_t rhs)
Definition Int128.hpp:188
Int128(int64_t lo=0)
Definition Int128.hpp:127

References Int128(), multiply(), and sign().

Referenced by compare_rationals_filtered().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ compare_rationals_filtered()

int Int128::compare_rationals_filtered ( int64_t p1,
int64_t q1,
int64_t p2,
int64_t q2 )
inlinestatic
280 {
281 // First try to calculate the determinant over the upper 31 bits.
282 // Round p1, p2, q1, q2 to 31 bits.
283 int invert = ((q1 < 0) == (q2 < 0)) ? 1 : -1;
284 int64_t q1s = (q1 + (1 << 31)) >> 32;
285 int64_t q2s = (q2 + (1 << 31)) >> 32;
286 if (q1s != 0 && q2s != 0) {
287 int64_t p1s = (p1 + (1 << 31)) >> 32;
288 int64_t p2s = (p2 + (1 << 31)) >> 32;
289 // Result fits 63 bits, it is an approximate of the determinant divided by 2^64.
290 int64_t det = p1s * q2s - p2s * q1s;
291 // Maximum absolute of the remainder of the exact determinant, divided by 2^64.
292 int64_t err = ((std::abs(p1s) + std::abs(q1s) + std::abs(p2s) + std::abs(q2s)) << 1) + 1;
293 assert(std::abs(det) <= err || ((det > 0) ? 1 : -1) * invert == compare_rationals(p1, q1, p2, q2));
294 if (std::abs(det) > err)
295 return ((det > 0) ? 1 : -1) * invert;
296 }
297 return sign_determinant_2x2(p1, q1, p2, q2) * invert;
298 }
static int sign_determinant_2x2(int64_t a11, int64_t a12, int64_t a21, int64_t a22)
Definition Int128.hpp:234
static int compare_rationals(int64_t p1, int64_t q1, int64_t p2, int64_t q2)
Definition Int128.hpp:240

References compare_rationals(), and sign_determinant_2x2().

Here is the call graph for this function:

◆ hi()

int64_t Int128::hi ( ) const
inlineprivate
138{ return m_hi; }

References m_hi.

Referenced by Int128().

Here is the caller graph for this function:

◆ lo()

uint64_t Int128::lo ( ) const
inlineprivate
137{ return m_lo; }

References m_lo.

Referenced by Int128(), and Int128().

Here is the caller graph for this function:

◆ multiply()

Int128 Int128::multiply ( int64_t lhs,
int64_t rhs )
inlinestaticprivate
189 {
190#if defined(_MSC_VER) && defined(_M_X64)
191 // On Visual Studio x64, use the _mul128() intrinsic function.
192 // (ARM64 MSVC has no _mul128; it falls through to the portable path.)
193 Int128 result;
194 result.m_lo = (uint64_t)_mul128(lhs, rhs, &result.m_hi);
195 return result;
196#else
197 // This branch should only be executed in case there is neither __int16 type nor _mul128 intrinsic
198 // function available. This is mostly on 32bit operating systems.
199 // Use a pure C implementation of _mul128().
200
201 int negate = (lhs < 0) != (rhs < 0);
202
203 if (lhs < 0)
204 lhs = -lhs;
205 uint64_t int1Hi = uint64_t(lhs) >> 32;
206 uint64_t int1Lo = uint64_t(lhs & 0xFFFFFFFF);
207
208 if (rhs < 0)
209 rhs = -rhs;
210 uint64_t int2Hi = uint64_t(rhs) >> 32;
211 uint64_t int2Lo = uint64_t(rhs & 0xFFFFFFFF);
212
213 //because the high (sign) bits in both int1Hi & int2Hi have been zeroed,
214 //there's no risk of 64 bit overflow in the following assignment
215 //(ie: $7FFFFFFF*$FFFFFFFF + $7FFFFFFF*$FFFFFFFF < 64bits)
216 uint64_t a = int1Hi * int2Hi;
217 uint64_t b = int1Lo * int2Lo;
218 //Result = A shl 64 + C shl 32 + B ...
219 uint64_t c = int1Hi * int2Lo + int1Lo * int2Hi;
220
221 Int128 tmp;
222 tmp.m_hi = int64_t(a + (c >> 32));
223 tmp.m_lo = int64_t(c << 32);
224 tmp.m_lo += int64_t(b);
225 if (tmp.m_lo < b)
226 ++ tmp.m_hi;
227 if (negate)
228 tmp = - tmp;
229 return tmp;
230#endif
231 }

References Int128(), m_hi, and m_lo.

Referenced by compare_rationals(), and sign_determinant_2x2().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ operator double()

Int128::operator double ( ) const
inlineprivate
179 {
180 const double shift64 = 18446744073709551616.0; //2^64
181 return (m_hi < 0) ?
182 ((m_lo == 0) ?
183 (double)m_hi * shift64 :
184 -(double)(~m_lo + ~m_hi * shift64)) :
185 (double)(m_lo + m_hi * shift64);
186 }

References m_hi, and m_lo.

◆ operator!=()

bool Int128::operator!= ( const Int128 & val) const
inlineprivate
142{ return ! (*this == val); }

References Int128().

Here is the call graph for this function:

◆ operator+()

Int128 Int128::operator+ ( const Int128 & rhs) const
inlineprivate
157 {
158 Int128 result(*this);
159 result+= rhs;
160 return result;
161 }

References Int128().

Here is the call graph for this function:

◆ operator+=()

Int128 & Int128::operator+= ( const Int128 & rhs)
inlineprivate
149 {
150 m_hi += rhs.m_hi;
151 m_lo += rhs.m_lo;
152 if (m_lo < rhs.m_lo) m_hi++;
153 return *this;
154 }

References Int128(), m_hi, and m_lo.

Here is the call graph for this function:

◆ operator-() [1/2]

Int128 Int128::operator- ( ) const
inlineprivate
176{ return (m_lo == 0) ? Int128(-m_hi, 0) : Int128(~m_hi, ~m_lo + 1); }

References Int128(), m_hi, and m_lo.

Here is the call graph for this function:

◆ operator-() [2/2]

Int128 Int128::operator- ( const Int128 & rhs) const
inlineprivate
170 {
171 Int128 result(*this);
172 result -= rhs;
173 return result;
174 }

References Int128().

Here is the call graph for this function:

◆ operator-=()

Int128 & Int128::operator-= ( const Int128 & rhs)
inlineprivate
164 {
165 *this += -rhs;
166 return *this;
167 }

References Int128().

Here is the call graph for this function:

◆ operator<()

bool Int128::operator< ( const Int128 & val) const
inlineprivate
144{ return (m_hi == val.m_hi) ? m_lo < val.m_lo : m_hi < val.m_hi; }

References Int128(), m_hi, and m_lo.

Here is the call graph for this function:

◆ operator<=()

bool Int128::operator<= ( const Int128 & val) const
inlineprivate
146{ return ! (*this > val); }

References Int128().

Here is the call graph for this function:

◆ operator=()

Int128 & Int128::operator= ( const int64_t & val)
inlineprivate
131 {
132 m_lo = (uint64_t)val;
133 m_hi = (val < 0) ? -1 : 0;
134 return *this;
135 }

References Int128(), m_hi, and m_lo.

Here is the call graph for this function:

◆ operator==()

bool Int128::operator== ( const Int128 & val) const
inlineprivate
141{ return m_hi == val.m_hi && m_lo == val.m_lo; }

References Int128(), m_hi, and m_lo.

Here is the call graph for this function:

◆ operator>()

bool Int128::operator> ( const Int128 & val) const
inlineprivate
143{ return (m_hi == val.m_hi) ? m_lo > val.m_lo : m_hi > val.m_hi; }

References Int128(), m_hi, and m_lo.

Here is the call graph for this function:

◆ operator>=()

bool Int128::operator>= ( const Int128 & val) const
inlineprivate
145{ return ! (*this < val); }

References Int128().

Here is the call graph for this function:

◆ sign()

int Int128::sign ( ) const
inlineprivate
139{ return (m_hi == 0) ? (m_lo > 0) : (m_hi > 0) - (m_hi < 0); }

References m_hi, and m_lo.

Referenced by compare_rationals().

Here is the caller graph for this function:

◆ sign_determinant_2x2()

int Int128::sign_determinant_2x2 ( int64_t a11,
int64_t a12,
int64_t a21,
int64_t a22 )
inlinestaticprivate
235 {
236 return (Int128::multiply(a11, a22) - Int128::multiply(a12, a21)).sign();
237 }

References multiply().

Referenced by compare_rationals_filtered(), and sign_determinant_2x2_filtered().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sign_determinant_2x2_filtered()

int Int128::sign_determinant_2x2_filtered ( int64_t a11,
int64_t a12,
int64_t a21,
int64_t a22 )
inlinestatic
261 {
262 // First try to calculate the determinant over the upper 31 bits.
263 // Round p1, p2, q1, q2 to 31 bits.
264 int64_t a11s = (a11 + (1 << 31)) >> 32;
265 int64_t a12s = (a12 + (1 << 31)) >> 32;
266 int64_t a21s = (a21 + (1 << 31)) >> 32;
267 int64_t a22s = (a22 + (1 << 31)) >> 32;
268 // Result fits 63 bits, it is an approximate of the determinant divided by 2^64.
269 int64_t det = a11s * a22s - a12s * a21s;
270 // Maximum absolute of the remainder of the exact determinant, divided by 2^64.
271 int64_t err = ((std::abs(a11s) + std::abs(a12s) + std::abs(a21s) + std::abs(a22s)) << 1) + 1;
272 assert(std::abs(det) <= err || ((det > 0) ? 1 : -1) == sign_determinant_2x2(a11, a12, a21, a22));
273 return (std::abs(det) > err) ?
274 ((det > 0) ? 1 : -1) :
275 sign_determinant_2x2(a11, a12, a21, a22);
276 }

References sign_determinant_2x2().

Referenced by Slic3r::int128::cross(), and Slic3r::int128::orient().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ m_hi

◆ m_lo


The documentation for this class was generated from the following file:
  • /home/runner/work/OrcaSlicer/OrcaSlicer/src/libslic3r/Int128.hpp