comparison liboctave/oct-inttypes.h @ 4953:7a3a480e8645

[project @ 2004-09-01 21:10:28 by jwe]
author jwe
date Wed, 01 Sep 2004 21:10:28 +0000
parents bfd57b466752
children 573d23f9c9cf
comparison
equal deleted inserted replaced
4952:bfd57b466752 4953:7a3a480e8645
26 #include <limits> 26 #include <limits>
27 27
28 #include <iostream> 28 #include <iostream>
29 29
30 #include "data-conv.h" 30 #include "data-conv.h"
31 #include "lo-ieee.h"
31 32
32 typedef signed char octave_int8_t; 33 typedef signed char octave_int8_t;
33 typedef TWO_BYTE_INT octave_int16_t; 34 typedef TWO_BYTE_INT octave_int16_t;
34 typedef FOUR_BYTE_INT octave_int32_t; 35 typedef FOUR_BYTE_INT octave_int32_t;
35 typedef EIGHT_BYTE_INT octave_int64_t; 36 typedef EIGHT_BYTE_INT octave_int64_t;
244 245
245 octave_int<T> operator + (void) const { return *this; } 246 octave_int<T> operator + (void) const { return *this; }
246 247
247 octave_int<T> operator - (void) const 248 octave_int<T> operator - (void) const
248 { 249 {
249 return std::numeric_limits<T>::is_signed ? -ival : 0; 250 // Can't just return -ival because signed types are not
251 // symmetric, which causes things like -intmin("int32") to be the
252 // same as intmin("int32") instead of intmax("int32") (which is
253 // what we should get with saturation semantics).
254
255 return std::numeric_limits<T>::is_signed ?
256 OCTAVE_INT_FIT_TO_RANGE (- static_cast<double> (ival), T) : 0;
250 } 257 }
251 258
252 operator double (void) const { return static_cast<double> (value ()); } 259 operator double (void) const { return static_cast<double> (value ()); }
253 260
254 octave_int<T>& operator += (const octave_int<T>& x) 261 octave_int<T>& operator += (const octave_int<T>& x)
277 284
278 octave_int<T>& operator /= (const octave_int<T>& x) 285 octave_int<T>& operator /= (const octave_int<T>& x)
279 { 286 {
280 double t = static_cast<double> (value ()); 287 double t = static_cast<double> (value ());
281 double tx = static_cast<double> (x.value ()); 288 double tx = static_cast<double> (x.value ());
282 ival = OCTAVE_INT_FIT_TO_RANGE (t / tx, T); 289 double r = (t == 0 && tx == 0) ? 0 : round (t / tx);
290 ival = OCTAVE_INT_FIT_TO_RANGE (r, T);
283 return *this; 291 return *this;
284 } 292 }
285 293
286 template <class T2> 294 template <class T2>
287 octave_int<T>& operator <<= (const T2& x) 295 octave_int<T>& operator <<= (const T2& x)
308 316
309 T ival; 317 T ival;
310 }; 318 };
311 319
312 template <class T> 320 template <class T>
313 T 321 octave_int<T>
314 pow (const T& a, const T& b) 322 pow (const octave_int<T>& a, const octave_int<T>& b)
315 { 323 {
316 T retval; 324 octave_int<T> retval;
317 325
318 T zero = T (0); 326 octave_int<T> zero = octave_int<T> (0);
319 T one = T (1); 327 octave_int<T> one = octave_int<T> (1);
320 328
321 if (b == zero) 329 if (b == zero)
322 retval = one; 330 retval = one;
323 else if (b < zero) 331 else if (b < zero)
324 retval = zero; 332 retval = zero;
325 else 333 else
326 { 334 {
327 T a_val = a; 335 octave_int<T> a_val = a;
328 T b_val = b; 336 octave_int<T> b_val = b;
329 337
330 retval = a; 338 retval = a;
331 339
332 b_val -= 1; 340 b_val -= 1;
333 341
342 a_val = a_val * a_val; 350 a_val = a_val * a_val;
343 } 351 }
344 } 352 }
345 353
346 return retval; 354 return retval;
355 }
356
357 template <class T>
358 octave_int<T>
359 pow (double a, const octave_int<T>& b)
360 {
361 double tb = static_cast<double> (b.value ());
362 double r = pow (a, tb);
363 r = lo_ieee_isnan (r) ? 0 : round (r);
364 return OCTAVE_INT_FIT_TO_RANGE (r, T);
365 }
366
367 template <class T>
368 octave_int<T>
369 pow (const octave_int<T>& a, double b)
370 {
371 double ta = static_cast<double> (a.value ());
372 double r = pow (ta, b);
373 r = lo_ieee_isnan (r) ? 0 : round (r);
374 return OCTAVE_INT_FIT_TO_RANGE (r, T);
347 } 375 }
348 376
349 template <class T> 377 template <class T>
350 std::ostream& 378 std::ostream&
351 operator << (std::ostream& os, const octave_int<T>& ival) 379 operator << (std::ostream& os, const octave_int<T>& ival)
387 } 415 }
388 416
389 OCTAVE_INT_BIN_OP(+) 417 OCTAVE_INT_BIN_OP(+)
390 OCTAVE_INT_BIN_OP(-) 418 OCTAVE_INT_BIN_OP(-)
391 OCTAVE_INT_BIN_OP(*) 419 OCTAVE_INT_BIN_OP(*)
392 OCTAVE_INT_BIN_OP(/) 420
421 template <class T1, class T2>
422 octave_int<typename octave_int_binop_traits<T1, T2>::TR>
423 operator / (const octave_int<T1>& x, const octave_int<T2>& y)
424 {
425 double tx = static_cast<double> (x.value ());
426 double ty = static_cast<double> (y.value ());
427 double r = (tx == 0 && ty == 0) ? 0 : tx / ty;
428 return OCTAVE_INT_FIT_TO_RANGE2 (r, T1, T2);
429 }
430
431 #define OCTAVE_INT_DOUBLE_BIN_OP(OP) \
432 \
433 template <class T> \
434 octave_int<T> \
435 operator OP (const octave_int<T>& x, double y) \
436 { \
437 double tx = static_cast<double> (x.value ()); \
438 double r = round (tx OP y); \
439 r = lo_ieee_isnan (r) ? 0 : round (r); \
440 return OCTAVE_INT_FIT_TO_RANGE (r, T); \
441 }
442
443 OCTAVE_INT_DOUBLE_BIN_OP(+)
444 OCTAVE_INT_DOUBLE_BIN_OP(-)
445 OCTAVE_INT_DOUBLE_BIN_OP(*)
446 OCTAVE_INT_DOUBLE_BIN_OP(/)
447
448 #define OCTAVE_DOUBLE_INT_BIN_OP(OP) \
449 \
450 template <class T> \
451 octave_int<T> \
452 operator OP (double x, const octave_int<T>& y) \
453 { \
454 double ty = static_cast<double> (y.value ()); \
455 double r = x OP ty; \
456 r = lo_ieee_isnan (r) ? 0 : round (r); \
457 return OCTAVE_INT_FIT_TO_RANGE (r, T); \
458 }
459
460 OCTAVE_DOUBLE_INT_BIN_OP(+)
461 OCTAVE_DOUBLE_INT_BIN_OP(-)
462 OCTAVE_DOUBLE_INT_BIN_OP(*)
463 OCTAVE_DOUBLE_INT_BIN_OP(/)
393 464
394 #define OCTAVE_INT_BITCMP_OP(OP) \ 465 #define OCTAVE_INT_BITCMP_OP(OP) \
395 \ 466 \
396 template <class T> \ 467 template <class T> \
397 octave_int<T> \ 468 octave_int<T> \