Home | History | Annotate | Line # | Download | only in gcc
double-int.h revision 1.5.4.2
      1      1.1     mrg /* Operations with long integers.
      2  1.5.4.2  martin    Copyright (C) 2006-2017 Free Software Foundation, Inc.
      3      1.1     mrg 
      4      1.1     mrg This file is part of GCC.
      5      1.1     mrg 
      6      1.1     mrg GCC is free software; you can redistribute it and/or modify it
      7      1.1     mrg under the terms of the GNU General Public License as published by the
      8      1.1     mrg Free Software Foundation; either version 3, or (at your option) any
      9      1.1     mrg later version.
     10      1.1     mrg 
     11      1.1     mrg GCC is distributed in the hope that it will be useful, but WITHOUT
     12      1.1     mrg ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13      1.1     mrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14      1.1     mrg for more details.
     15      1.1     mrg 
     16      1.1     mrg You should have received a copy of the GNU General Public License
     17      1.1     mrg along with GCC; see the file COPYING3.  If not see
     18      1.1     mrg <http://www.gnu.org/licenses/>.  */
     19      1.1     mrg 
     20      1.1     mrg #ifndef DOUBLE_INT_H
     21      1.1     mrg #define DOUBLE_INT_H
     22      1.1     mrg 
     23      1.1     mrg /* A large integer is currently represented as a pair of HOST_WIDE_INTs.
     24      1.1     mrg    It therefore represents a number with precision of
     25      1.1     mrg    2 * HOST_BITS_PER_WIDE_INT bits (it is however possible that the
     26      1.1     mrg    internal representation will change, if numbers with greater precision
     27      1.1     mrg    are needed, so the users should not rely on it).  The representation does
     28      1.1     mrg    not contain any information about signedness of the represented value, so
     29      1.1     mrg    it can be used to represent both signed and unsigned numbers.  For
     30      1.1     mrg    operations where the results depend on signedness (division, comparisons),
     31      1.1     mrg    it must be specified separately.  For each such operation, there are three
     32      1.1     mrg    versions of the function -- double_int_op, that takes an extra UNS argument
     33      1.1     mrg    giving the signedness of the values, and double_int_sop and double_int_uop
     34      1.1     mrg    that stand for its specializations for signed and unsigned values.
     35      1.1     mrg 
     36      1.1     mrg    You may also represent with numbers in smaller precision using double_int.
     37      1.1     mrg    You however need to use double_int_ext (that fills in the bits of the
     38      1.1     mrg    number over the prescribed precision with zeros or with the sign bit) before
     39      1.1     mrg    operations that do not perform arithmetics modulo 2^precision (comparisons,
     40      1.1     mrg    division), and possibly before storing the results, if you want to keep
     41      1.1     mrg    them in some canonical form).  In general, the signedness of double_int_ext
     42      1.1     mrg    should match the signedness of the operation.
     43      1.1     mrg 
     44      1.1     mrg    ??? The components of double_int differ in signedness mostly for
     45      1.1     mrg    historical reasons (they replace an older structure used to represent
     46      1.1     mrg    numbers with precision higher than HOST_WIDE_INT).  It might be less
     47      1.1     mrg    confusing to have them both signed or both unsigned.  */
     48      1.1     mrg 
     49      1.3     mrg struct double_int
     50      1.1     mrg {
     51      1.3     mrg   /* Normally, we would define constructors to create instances.
     52      1.3     mrg      Two things prevent us from doing so.
     53      1.3     mrg      First, defining a constructor makes the class non-POD in C++03,
     54      1.3     mrg      and we certainly want double_int to be a POD.
     55      1.3     mrg      Second, the GCC conding conventions prefer explicit conversion,
     56      1.3     mrg      and explicit conversion operators are not available until C++11.  */
     57      1.3     mrg 
     58      1.3     mrg   static double_int from_uhwi (unsigned HOST_WIDE_INT cst);
     59      1.3     mrg   static double_int from_shwi (HOST_WIDE_INT cst);
     60      1.3     mrg   static double_int from_pair (HOST_WIDE_INT high, unsigned HOST_WIDE_INT low);
     61      1.3     mrg 
     62      1.3     mrg   /* Construct from a fuffer of length LEN.  BUFFER will be read according
     63  1.5.4.2  martin      to byte endianness and word endianness.  */
     64      1.3     mrg   static double_int from_buffer (const unsigned char *buffer, int len);
     65      1.3     mrg 
     66      1.3     mrg   /* No copy assignment operator or destructor to keep the type a POD.  */
     67      1.3     mrg 
     68      1.3     mrg   /* There are some special value-creation static member functions.  */
     69      1.3     mrg 
     70      1.3     mrg   static double_int mask (unsigned prec);
     71      1.3     mrg   static double_int max_value (unsigned int prec, bool uns);
     72      1.3     mrg   static double_int min_value (unsigned int prec, bool uns);
     73      1.3     mrg 
     74      1.3     mrg   /* The following functions are mutating operations.  */
     75      1.3     mrg 
     76      1.3     mrg   double_int &operator ++ (); // prefix
     77      1.3     mrg   double_int &operator -- (); // prefix
     78      1.3     mrg   double_int &operator *= (double_int);
     79      1.3     mrg   double_int &operator += (double_int);
     80      1.3     mrg   double_int &operator -= (double_int);
     81      1.3     mrg   double_int &operator &= (double_int);
     82      1.3     mrg   double_int &operator ^= (double_int);
     83      1.3     mrg   double_int &operator |= (double_int);
     84      1.3     mrg 
     85      1.3     mrg   /* The following functions are non-mutating operations.  */
     86      1.3     mrg 
     87      1.3     mrg   /* Conversion functions.  */
     88      1.3     mrg 
     89      1.3     mrg   HOST_WIDE_INT to_shwi () const;
     90      1.3     mrg   unsigned HOST_WIDE_INT to_uhwi () const;
     91      1.3     mrg 
     92      1.3     mrg   /* Conversion query functions.  */
     93      1.3     mrg 
     94      1.3     mrg   bool fits_uhwi () const;
     95      1.3     mrg   bool fits_shwi () const;
     96      1.3     mrg   bool fits_hwi (bool uns) const;
     97      1.3     mrg 
     98      1.3     mrg   /* Attribute query functions.  */
     99      1.3     mrg 
    100      1.3     mrg   int trailing_zeros () const;
    101      1.3     mrg   int popcount () const;
    102      1.3     mrg 
    103      1.3     mrg   /* Arithmetic query operations.  */
    104      1.3     mrg 
    105      1.3     mrg   bool multiple_of (double_int, bool, double_int *) const;
    106      1.3     mrg 
    107      1.3     mrg   /* Arithmetic operation functions.  */
    108      1.3     mrg 
    109      1.3     mrg   /* The following operations perform arithmetics modulo 2^precision, so you
    110      1.3     mrg      do not need to call .ext between them, even if you are representing
    111      1.3     mrg      numbers with precision less than HOST_BITS_PER_DOUBLE_INT bits.  */
    112      1.3     mrg 
    113      1.3     mrg   double_int set_bit (unsigned) const;
    114      1.3     mrg   double_int mul_with_sign (double_int, bool unsigned_p, bool *overflow) const;
    115      1.3     mrg   double_int wide_mul_with_sign (double_int, bool unsigned_p,
    116      1.3     mrg 				 double_int *higher, bool *overflow) const;
    117      1.3     mrg   double_int add_with_sign (double_int, bool unsigned_p, bool *overflow) const;
    118      1.3     mrg   double_int sub_with_overflow (double_int, bool *overflow) const;
    119      1.3     mrg   double_int neg_with_overflow (bool *overflow) const;
    120      1.3     mrg 
    121      1.3     mrg   double_int operator * (double_int) const;
    122      1.3     mrg   double_int operator + (double_int) const;
    123      1.3     mrg   double_int operator - (double_int) const;
    124      1.3     mrg   double_int operator - () const;
    125      1.3     mrg   double_int operator ~ () const;
    126      1.3     mrg   double_int operator & (double_int) const;
    127      1.3     mrg   double_int operator | (double_int) const;
    128      1.3     mrg   double_int operator ^ (double_int) const;
    129      1.3     mrg   double_int and_not (double_int) const;
    130      1.3     mrg 
    131      1.5     mrg   double_int lshift (HOST_WIDE_INT count) const;
    132      1.3     mrg   double_int lshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const;
    133      1.5     mrg   double_int rshift (HOST_WIDE_INT count) const;
    134      1.3     mrg   double_int rshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const;
    135      1.3     mrg   double_int alshift (HOST_WIDE_INT count, unsigned int prec) const;
    136      1.3     mrg   double_int arshift (HOST_WIDE_INT count, unsigned int prec) const;
    137      1.3     mrg   double_int llshift (HOST_WIDE_INT count, unsigned int prec) const;
    138      1.3     mrg   double_int lrshift (HOST_WIDE_INT count, unsigned int prec) const;
    139      1.3     mrg   double_int lrotate (HOST_WIDE_INT count, unsigned int prec) const;
    140      1.3     mrg   double_int rrotate (HOST_WIDE_INT count, unsigned int prec) const;
    141      1.3     mrg 
    142      1.3     mrg   /* You must ensure that double_int::ext is called on the operands
    143      1.3     mrg      of the following operations, if the precision of the numbers
    144      1.3     mrg      is less than HOST_BITS_PER_DOUBLE_INT bits.  */
    145      1.3     mrg 
    146      1.3     mrg   double_int div (double_int, bool, unsigned) const;
    147      1.3     mrg   double_int sdiv (double_int, unsigned) const;
    148      1.3     mrg   double_int udiv (double_int, unsigned) const;
    149      1.3     mrg   double_int mod (double_int, bool, unsigned) const;
    150      1.3     mrg   double_int smod (double_int, unsigned) const;
    151      1.3     mrg   double_int umod (double_int, unsigned) const;
    152      1.3     mrg   double_int divmod_with_overflow (double_int, bool, unsigned,
    153      1.3     mrg 				   double_int *, bool *) const;
    154      1.3     mrg   double_int divmod (double_int, bool, unsigned, double_int *) const;
    155      1.3     mrg   double_int sdivmod (double_int, unsigned, double_int *) const;
    156      1.3     mrg   double_int udivmod (double_int, unsigned, double_int *) const;
    157      1.3     mrg 
    158      1.3     mrg   /* Precision control functions.  */
    159      1.3     mrg 
    160      1.3     mrg   double_int ext (unsigned prec, bool uns) const;
    161      1.3     mrg   double_int zext (unsigned prec) const;
    162      1.3     mrg   double_int sext (unsigned prec) const;
    163      1.3     mrg 
    164      1.3     mrg   /* Comparative functions.  */
    165      1.3     mrg 
    166      1.3     mrg   bool is_zero () const;
    167      1.3     mrg   bool is_one () const;
    168      1.3     mrg   bool is_minus_one () const;
    169      1.3     mrg   bool is_negative () const;
    170      1.3     mrg 
    171      1.3     mrg   int cmp (double_int b, bool uns) const;
    172      1.3     mrg   int ucmp (double_int b) const;
    173      1.3     mrg   int scmp (double_int b) const;
    174      1.3     mrg 
    175      1.3     mrg   bool ult (double_int b) const;
    176      1.3     mrg   bool ule (double_int b) const;
    177      1.3     mrg   bool ugt (double_int b) const;
    178      1.3     mrg   bool slt (double_int b) const;
    179      1.3     mrg   bool sle (double_int b) const;
    180      1.3     mrg   bool sgt (double_int b) const;
    181      1.3     mrg 
    182      1.3     mrg   double_int max (double_int b, bool uns);
    183      1.3     mrg   double_int smax (double_int b);
    184      1.3     mrg   double_int umax (double_int b);
    185      1.3     mrg 
    186      1.3     mrg   double_int min (double_int b, bool uns);
    187      1.3     mrg   double_int smin (double_int b);
    188      1.3     mrg   double_int umin (double_int b);
    189      1.3     mrg 
    190      1.3     mrg   bool operator == (double_int cst2) const;
    191      1.3     mrg   bool operator != (double_int cst2) const;
    192      1.3     mrg 
    193      1.5     mrg   /* Please migrate away from using these member variables publicly.  */
    194      1.3     mrg 
    195      1.1     mrg   unsigned HOST_WIDE_INT low;
    196      1.1     mrg   HOST_WIDE_INT high;
    197      1.1     mrg 
    198      1.3     mrg };
    199      1.3     mrg 
    200      1.3     mrg #define HOST_BITS_PER_DOUBLE_INT (2 * HOST_BITS_PER_WIDE_INT)
    201      1.1     mrg 
    202      1.1     mrg /* Constructors and conversions.  */
    203      1.1     mrg 
    204      1.1     mrg /* Constructs double_int from integer CST.  The bits over the precision of
    205      1.1     mrg    HOST_WIDE_INT are filled with the sign bit.  */
    206      1.1     mrg 
    207      1.3     mrg inline double_int
    208      1.3     mrg double_int::from_shwi (HOST_WIDE_INT cst)
    209      1.1     mrg {
    210      1.1     mrg   double_int r;
    211      1.1     mrg   r.low = (unsigned HOST_WIDE_INT) cst;
    212      1.1     mrg   r.high = cst < 0 ? -1 : 0;
    213      1.1     mrg   return r;
    214      1.1     mrg }
    215      1.1     mrg 
    216      1.1     mrg /* Some useful constants.  */
    217      1.3     mrg /* FIXME(crowl): Maybe remove after converting callers?
    218      1.3     mrg    The problem is that a named constant would not be as optimizable,
    219      1.3     mrg    while the functional syntax is more verbose.  */
    220      1.3     mrg 
    221      1.3     mrg #define double_int_minus_one (double_int::from_shwi (-1))
    222      1.3     mrg #define double_int_zero (double_int::from_shwi (0))
    223      1.3     mrg #define double_int_one (double_int::from_shwi (1))
    224      1.3     mrg #define double_int_two (double_int::from_shwi (2))
    225      1.3     mrg #define double_int_ten (double_int::from_shwi (10))
    226      1.1     mrg 
    227      1.1     mrg /* Constructs double_int from unsigned integer CST.  The bits over the
    228      1.1     mrg    precision of HOST_WIDE_INT are filled with zeros.  */
    229      1.1     mrg 
    230      1.3     mrg inline double_int
    231      1.3     mrg double_int::from_uhwi (unsigned HOST_WIDE_INT cst)
    232      1.1     mrg {
    233      1.1     mrg   double_int r;
    234      1.1     mrg   r.low = cst;
    235      1.1     mrg   r.high = 0;
    236      1.3     mrg   return r;
    237      1.3     mrg }
    238      1.1     mrg 
    239      1.3     mrg inline double_int
    240      1.3     mrg double_int::from_pair (HOST_WIDE_INT high, unsigned HOST_WIDE_INT low)
    241      1.3     mrg {
    242      1.3     mrg   double_int r;
    243      1.3     mrg   r.low = low;
    244      1.3     mrg   r.high = high;
    245      1.1     mrg   return r;
    246      1.1     mrg }
    247      1.1     mrg 
    248      1.3     mrg inline double_int &
    249      1.3     mrg double_int::operator ++ ()
    250      1.3     mrg {
    251      1.3     mrg   *this += double_int_one;
    252      1.3     mrg   return *this;
    253      1.3     mrg }
    254      1.3     mrg 
    255      1.3     mrg inline double_int &
    256      1.3     mrg double_int::operator -- ()
    257      1.3     mrg {
    258      1.3     mrg   *this -= double_int_one;
    259      1.3     mrg   return *this;
    260      1.3     mrg }
    261      1.3     mrg 
    262      1.3     mrg inline double_int &
    263      1.3     mrg double_int::operator &= (double_int b)
    264      1.3     mrg {
    265      1.3     mrg   *this = *this & b;
    266      1.3     mrg   return *this;
    267      1.3     mrg }
    268      1.3     mrg 
    269      1.3     mrg inline double_int &
    270      1.3     mrg double_int::operator ^= (double_int b)
    271      1.3     mrg {
    272      1.3     mrg   *this = *this ^ b;
    273      1.3     mrg   return *this;
    274      1.3     mrg }
    275      1.3     mrg 
    276      1.3     mrg inline double_int &
    277      1.3     mrg double_int::operator |= (double_int b)
    278      1.3     mrg {
    279      1.3     mrg   *this = *this | b;
    280      1.3     mrg   return *this;
    281      1.3     mrg }
    282      1.3     mrg 
    283      1.3     mrg /* Returns value of CST as a signed number.  CST must satisfy
    284      1.3     mrg    double_int::fits_signed.  */
    285      1.3     mrg 
    286      1.3     mrg inline HOST_WIDE_INT
    287      1.3     mrg double_int::to_shwi () const
    288      1.3     mrg {
    289      1.3     mrg   return (HOST_WIDE_INT) low;
    290      1.3     mrg }
    291      1.3     mrg 
    292      1.3     mrg /* Returns value of CST as an unsigned number.  CST must satisfy
    293      1.3     mrg    double_int::fits_unsigned.  */
    294      1.3     mrg 
    295      1.3     mrg inline unsigned HOST_WIDE_INT
    296      1.3     mrg double_int::to_uhwi () const
    297      1.3     mrg {
    298      1.3     mrg   return low;
    299      1.3     mrg }
    300      1.3     mrg 
    301      1.3     mrg /* Returns true if CST fits in unsigned HOST_WIDE_INT.  */
    302      1.3     mrg 
    303      1.3     mrg inline bool
    304      1.3     mrg double_int::fits_uhwi () const
    305      1.3     mrg {
    306      1.3     mrg   return high == 0;
    307      1.3     mrg }
    308      1.3     mrg 
    309      1.3     mrg /* Logical operations.  */
    310      1.3     mrg 
    311      1.3     mrg /* Returns ~A.  */
    312      1.3     mrg 
    313      1.3     mrg inline double_int
    314      1.3     mrg double_int::operator ~ () const
    315      1.3     mrg {
    316      1.3     mrg   double_int result;
    317      1.3     mrg   result.low = ~low;
    318      1.3     mrg   result.high = ~high;
    319      1.3     mrg   return result;
    320      1.3     mrg }
    321      1.3     mrg 
    322      1.3     mrg /* Returns A | B.  */
    323      1.3     mrg 
    324      1.3     mrg inline double_int
    325      1.3     mrg double_int::operator | (double_int b) const
    326      1.3     mrg {
    327      1.3     mrg   double_int result;
    328      1.3     mrg   result.low = low | b.low;
    329      1.3     mrg   result.high = high | b.high;
    330      1.3     mrg   return result;
    331      1.3     mrg }
    332      1.3     mrg 
    333      1.3     mrg /* Returns A & B.  */
    334      1.3     mrg 
    335      1.3     mrg inline double_int
    336      1.3     mrg double_int::operator & (double_int b) const
    337      1.3     mrg {
    338      1.3     mrg   double_int result;
    339      1.3     mrg   result.low = low & b.low;
    340      1.3     mrg   result.high = high & b.high;
    341      1.3     mrg   return result;
    342      1.3     mrg }
    343      1.3     mrg 
    344      1.3     mrg /* Returns A & ~B.  */
    345      1.3     mrg 
    346      1.3     mrg inline double_int
    347      1.3     mrg double_int::and_not (double_int b) const
    348      1.3     mrg {
    349      1.3     mrg   double_int result;
    350      1.3     mrg   result.low = low & ~b.low;
    351      1.3     mrg   result.high = high & ~b.high;
    352      1.3     mrg   return result;
    353      1.3     mrg }
    354      1.1     mrg 
    355      1.3     mrg /* Returns A ^ B.  */
    356      1.1     mrg 
    357      1.3     mrg inline double_int
    358      1.3     mrg double_int::operator ^ (double_int b) const
    359      1.3     mrg {
    360      1.3     mrg   double_int result;
    361      1.3     mrg   result.low = low ^ b.low;
    362      1.3     mrg   result.high = high ^ b.high;
    363      1.3     mrg   return result;
    364      1.3     mrg }
    365      1.3     mrg 
    366      1.3     mrg void dump_double_int (FILE *, double_int, bool);
    367      1.1     mrg 
    368  1.5.4.2  martin #define ALL_ONES HOST_WIDE_INT_M1U
    369      1.1     mrg 
    370      1.1     mrg /* The operands of the following comparison functions must be processed
    371      1.1     mrg    with double_int_ext, if their precision is less than
    372      1.3     mrg    HOST_BITS_PER_DOUBLE_INT bits.  */
    373      1.1     mrg 
    374      1.1     mrg /* Returns true if CST is zero.  */
    375      1.1     mrg 
    376      1.3     mrg inline bool
    377      1.3     mrg double_int::is_zero () const
    378      1.1     mrg {
    379      1.3     mrg   return low == 0 && high == 0;
    380      1.1     mrg }
    381      1.1     mrg 
    382      1.1     mrg /* Returns true if CST is one.  */
    383      1.1     mrg 
    384      1.3     mrg inline bool
    385      1.3     mrg double_int::is_one () const
    386      1.1     mrg {
    387      1.3     mrg   return low == 1 && high == 0;
    388      1.1     mrg }
    389      1.1     mrg 
    390      1.1     mrg /* Returns true if CST is minus one.  */
    391      1.1     mrg 
    392      1.3     mrg inline bool
    393      1.3     mrg double_int::is_minus_one () const
    394      1.1     mrg {
    395      1.3     mrg   return low == ALL_ONES && high == -1;
    396      1.3     mrg }
    397      1.3     mrg 
    398      1.3     mrg /* Returns true if CST is negative.  */
    399      1.3     mrg 
    400      1.3     mrg inline bool
    401      1.3     mrg double_int::is_negative () const
    402      1.3     mrg {
    403      1.3     mrg   return high < 0;
    404      1.1     mrg }
    405      1.1     mrg 
    406      1.1     mrg /* Returns true if CST1 == CST2.  */
    407      1.1     mrg 
    408      1.3     mrg inline bool
    409      1.3     mrg double_int::operator == (double_int cst2) const
    410      1.3     mrg {
    411      1.3     mrg   return low == cst2.low && high == cst2.high;
    412      1.3     mrg }
    413      1.3     mrg 
    414      1.3     mrg /* Returns true if CST1 != CST2.  */
    415      1.3     mrg 
    416      1.3     mrg inline bool
    417      1.3     mrg double_int::operator != (double_int cst2) const
    418      1.1     mrg {
    419      1.3     mrg   return low != cst2.low || high != cst2.high;
    420      1.1     mrg }
    421      1.1     mrg 
    422      1.3     mrg /* Return number of set bits of CST.  */
    423      1.3     mrg 
    424      1.3     mrg inline int
    425      1.3     mrg double_int::popcount () const
    426      1.3     mrg {
    427      1.3     mrg   return popcount_hwi (high) + popcount_hwi (low);
    428      1.3     mrg }
    429      1.3     mrg 
    430      1.3     mrg 
    431      1.1     mrg #ifndef GENERATOR_FILE
    432      1.1     mrg /* Conversion to and from GMP integer representations.  */
    433      1.1     mrg 
    434      1.1     mrg void mpz_set_double_int (mpz_t, double_int, bool);
    435      1.1     mrg double_int mpz_get_double_int (const_tree, mpz_t, bool);
    436      1.1     mrg #endif
    437      1.1     mrg 
    438      1.5     mrg namespace wi
    439      1.5     mrg {
    440      1.5     mrg   template <>
    441      1.5     mrg   struct int_traits <double_int>
    442      1.5     mrg   {
    443      1.5     mrg     static const enum precision_type precision_type = CONST_PRECISION;
    444      1.5     mrg     static const bool host_dependent_precision = true;
    445      1.5     mrg     static const unsigned int precision = HOST_BITS_PER_DOUBLE_INT;
    446      1.5     mrg     static unsigned int get_precision (const double_int &);
    447      1.5     mrg     static wi::storage_ref decompose (HOST_WIDE_INT *, unsigned int,
    448      1.5     mrg 				      const double_int &);
    449      1.5     mrg   };
    450      1.5     mrg }
    451      1.5     mrg 
    452      1.5     mrg inline unsigned int
    453      1.5     mrg wi::int_traits <double_int>::get_precision (const double_int &)
    454      1.5     mrg {
    455      1.5     mrg   return precision;
    456      1.5     mrg }
    457      1.5     mrg 
    458      1.5     mrg inline wi::storage_ref
    459      1.5     mrg wi::int_traits <double_int>::decompose (HOST_WIDE_INT *scratch, unsigned int p,
    460      1.5     mrg 					const double_int &x)
    461      1.5     mrg {
    462      1.5     mrg   gcc_checking_assert (precision == p);
    463      1.5     mrg   scratch[0] = x.low;
    464      1.5     mrg   if ((x.high == 0 && scratch[0] >= 0) || (x.high == -1 && scratch[0] < 0))
    465      1.5     mrg     return wi::storage_ref (scratch, 1, precision);
    466      1.5     mrg   scratch[1] = x.high;
    467      1.5     mrg   return wi::storage_ref (scratch, 2, precision);
    468      1.5     mrg }
    469      1.5     mrg 
    470      1.1     mrg #endif /* DOUBLE_INT_H */
    471