Drizzled Public API Documentation

real.cc
00001 /* - mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2008 MySQL
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019  */
00020 
00021 #include <config.h>
00022 #include <drizzled/field/real.h>
00023 #include <drizzled/error.h>
00024 #include <drizzled/table.h>
00025 
00026 #include <math.h>
00027 
00028 #include <limits>
00029 
00030 using namespace std;
00031 
00032 namespace drizzled {
00033 
00034 extern const double log_10[309];
00035 
00036 /*
00037   Floating-point numbers
00038  */
00039 
00040 unsigned char *
00041 Field_real::pack(unsigned char *to, const unsigned char *from,
00042                  uint32_t max_length, bool low_byte_first)
00043 {
00044   assert(max_length >= pack_length());
00045 #ifdef WORDS_BIGENDIAN
00046   if (low_byte_first != getTable()->getShare()->db_low_byte_first)
00047   {
00048     const unsigned char *dptr= from + pack_length();
00049     while (dptr-- > from)
00050       *to++ = *dptr;
00051     return(to);
00052   }
00053   else
00054 #endif
00055     return(Field::pack(to, from, max_length, low_byte_first));
00056 }
00057 
00058 const unsigned char *
00059 Field_real::unpack(unsigned char *to, const unsigned char *from,
00060                    uint32_t param_data, bool low_byte_first)
00061 {
00062 #ifdef WORDS_BIGENDIAN
00063   if (low_byte_first != getTable()->getShare()->db_low_byte_first)
00064   {
00065     const unsigned char *dptr= from + pack_length();
00066     while (dptr-- > from)
00067       *to++ = *dptr;
00068     return(from + pack_length());
00069   }
00070   else
00071 #endif
00072     return(Field::unpack(to, from, param_data, low_byte_first));
00073 }
00074 
00075 /*
00076   If a field has fixed length, truncate the double argument pointed to by 'nr'
00077   appropriately.
00078   Also ensure that the argument is within [-max_value; max_value] range.
00079 */
00080 
00081 int Field_real::truncate(double *nr, double max_value)
00082 {
00083   int error= 1;
00084   double res= *nr;
00085 
00086   if (res == numeric_limits<double>::quiet_NaN())
00087   {
00088     res= 0;
00089     set_null();
00090     set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
00091     goto end;
00092   }
00093 
00094   if (!not_fixed)
00095   {
00096     uint32_t order= field_length - dec;
00097     uint32_t step= array_elements(log_10) - 1;
00098     max_value= 1.0;
00099     for (; order > step; order-= step)
00100       max_value*= log_10[step];
00101     max_value*= log_10[order];
00102     max_value-= 1.0 / log_10[dec];
00103 
00104     /* Check for infinity so we don't get NaN in calculations */
00105     if (res != numeric_limits<double>::infinity())
00106     {
00107       double tmp= rint((res - floor(res)) * log_10[dec]) / log_10[dec];
00108       res= floor(res) + tmp;
00109     }
00110   }
00111 
00112   if (res < -max_value)
00113   {
00114    res= -max_value;
00115    set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
00116   }
00117   else if (res > max_value)
00118   {
00119     res= max_value;
00120     set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
00121   }
00122   else
00123     error= 0;
00124 
00125 end:
00126   *nr= res;
00127   return error;
00128 }
00129 
00130 
00131 int Field_real::store_decimal(const type::Decimal *dm)
00132 {
00133   double dbl;
00134   class_decimal2double(E_DEC_FATAL_ERROR, dm, &dbl);
00135   return store(dbl);
00136 }
00137 
00138 type::Decimal *Field_real::val_decimal(type::Decimal *decimal_value) const
00139 {
00140   ASSERT_COLUMN_MARKED_FOR_READ;
00141 
00142   double2_class_decimal(E_DEC_FATAL_ERROR, val_real(), decimal_value);
00143   return decimal_value;
00144 }
00145 
00146 } /* namespace drizzled */