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