Mercurial > hg > octave-jordi
view liboctave/oct-inttypes.cc @ 8169:66bc6f9b4f72
rewrite integer arithmetics and conversions
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Wed, 01 Oct 2008 11:05:13 -0400 |
parents | 6f10bbb2854a |
children | 69c5cce38c29 |
line wrap: on
line source
/* Copyright (C) 2004, 2005, 2006, 2007 John W. Eaton This file is part of Octave. Octave is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. Octave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Octave; see the file COPYING. If not, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include "lo-error.h" #include "oct-inttypes.h" // define type names. #define DECLARE_OCTAVE_INT_TYPENAME(TYPE, TYPENAME) \ template <> \ const char * \ octave_int<TYPE>::type_name () { return TYPENAME; } DECLARE_OCTAVE_INT_TYPENAME (int8_t, "int8") DECLARE_OCTAVE_INT_TYPENAME (int16_t, "int16") DECLARE_OCTAVE_INT_TYPENAME (int32_t, "int32") DECLARE_OCTAVE_INT_TYPENAME (int64_t, "int64") DECLARE_OCTAVE_INT_TYPENAME (uint8_t, "uint8") DECLARE_OCTAVE_INT_TYPENAME (uint16_t, "uint16") DECLARE_OCTAVE_INT_TYPENAME (uint32_t, "uint32") DECLARE_OCTAVE_INT_TYPENAME (uint64_t, "uint64") static void gripe_64bit_mul() { (*current_liboctave_error_handler) ("64-bit integer multiplication is not implemented"); } template <> uint64_t octave_int_arith_base<uint64_t, false>::mul (uint64_t, uint64_t) { gripe_64bit_mul (); return static_cast<uint64_t> (0); } template <> int64_t octave_int_arith_base<int64_t, true>::mul (int64_t, int64_t) { gripe_64bit_mul (); return static_cast<int64_t> (0); } static void gripe_64bit_mixed() { (*current_liboctave_error_handler) ("mixed double - 64-bit integer operations are not implemented"); } #define DEFINE_DOUBLE_INT64_OP0(OP,ARGT,RETT) \ template <> \ OCTAVE_API RETT \ operator OP (const double&, const ARGT&) \ { gripe_64bit_mixed (); return 0.0; } \ template <> \ OCTAVE_API RETT \ operator OP (const ARGT&, const double&) \ { gripe_64bit_mixed (); return 0.0; } \ #define DEFINE_DOUBLE_INT64_BIN_OP(OP) \ DEFINE_DOUBLE_INT64_OP0(OP,octave_int64,octave_int64) \ DEFINE_DOUBLE_INT64_OP0(OP,octave_uint64,octave_uint64) DEFINE_DOUBLE_INT64_BIN_OP(+) DEFINE_DOUBLE_INT64_BIN_OP(-) DEFINE_DOUBLE_INT64_BIN_OP(*) DEFINE_DOUBLE_INT64_BIN_OP(/) #define DEFINE_DOUBLE_INT64_CMP_OP(OP) \ DEFINE_DOUBLE_INT64_OP0(OP,octave_int64,bool) \ DEFINE_DOUBLE_INT64_OP0(OP,octave_uint64,bool) DEFINE_DOUBLE_INT64_CMP_OP(<) DEFINE_DOUBLE_INT64_CMP_OP(<=) DEFINE_DOUBLE_INT64_CMP_OP(>) DEFINE_DOUBLE_INT64_CMP_OP(>=) DEFINE_DOUBLE_INT64_CMP_OP(==) DEFINE_DOUBLE_INT64_CMP_OP(!=) //template <class T> //bool //xisnan (const octave_int<T>&) //{ // return false; //} template <class T> octave_int<T> pow (const octave_int<T>& a, const octave_int<T>& b) { octave_int<T> retval; octave_int<T> zero = octave_int<T> (0); octave_int<T> one = octave_int<T> (1); if (b == zero || a == one) retval = one; else if (b < zero) { if (std::numeric_limits<T>::is_signed && a.value () == -1) retval = (b.value () % 2) ? a : one; else retval = zero; } else { octave_int<T> a_val = a; T b_val = b; // no need to do saturation on b retval = a; b_val -= 1; while (b_val != 0) { if (b_val & 1) retval = retval * a_val; b_val = b_val >> 1; if (b_val) a_val = a_val * a_val; } } return retval; } template <class T> octave_int<T> pow (const double& a, const octave_int<T>& b) { return octave_int<T> (pow (a, b.double_value ())); } template <class T> octave_int<T> pow (const octave_int<T>& a, const double& b) { return octave_int<T> (pow (a.double_value (), b)); } template <class T> octave_int<T> powf (const float& a, const octave_int<T>& b) { return octave_int<T> (pow (a, b.float_value ())); } template <class T> octave_int<T> powf (const octave_int<T>& a, const float& b) { return octave_int<T> (pow (a.float_value (), b)); } #define INSTANTIATE_INTTYPE(T) \ template class OCTAVE_API octave_int<T>; \ template OCTAVE_API octave_int<T> pow (const octave_int<T>&, const octave_int<T>&); \ template OCTAVE_API octave_int<T> pow (const double&, const octave_int<T>&); \ template OCTAVE_API octave_int<T> pow (const octave_int<T>&, const double&); \ template OCTAVE_API octave_int<T> powf (const float&, const octave_int<T>&); \ template OCTAVE_API octave_int<T> powf (const octave_int<T>&, const float&); \ template OCTAVE_API std::ostream& operator << (std::ostream&, const octave_int<T>&); \ template OCTAVE_API std::istream& operator >> (std::istream&, octave_int<T>&); \ template OCTAVE_API octave_int<T> \ bitshift (const octave_int<T>&, int, const octave_int<T>&); \ INSTANTIATE_INTTYPE (int8_t); INSTANTIATE_INTTYPE (int16_t); INSTANTIATE_INTTYPE (int32_t); INSTANTIATE_INTTYPE (int64_t); INSTANTIATE_INTTYPE (uint8_t); INSTANTIATE_INTTYPE (uint16_t); INSTANTIATE_INTTYPE (uint32_t); INSTANTIATE_INTTYPE (uint64_t); /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */