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 
00035 extern const double log_10[309];
00036 
00037 /*
00038   Floating-point numbers
00039  */
00040 
00041 unsigned char *
00042 Field_real::pack(unsigned char *to, const unsigned char *from,
00043                  uint32_t max_length, bool low_byte_first)
00044 {
00045   assert(max_length >= pack_length());
00046 #ifdef WORDS_BIGENDIAN
00047   if (low_byte_first != getTable()->getShare()->db_low_byte_first)
00048   {
00049     const unsigned char *dptr= from + pack_length();
00050     while (dptr-- > from)
00051       *to++ = *dptr;
00052     return(to);
00053   }
00054   else
00055 #endif
00056     return(Field::pack(to, from, max_length, low_byte_first));
00057 }
00058 
00059 const unsigned char *
00060 Field_real::unpack(unsigned char *to, const unsigned char *from,
00061                    uint32_t param_data, bool low_byte_first)
00062 {
00063 #ifdef WORDS_BIGENDIAN
00064   if (low_byte_first != getTable()->getShare()->db_low_byte_first)
00065   {
00066     const unsigned char *dptr= from + pack_length();
00067     while (dptr-- > from)
00068       *to++ = *dptr;
00069     return(from + pack_length());
00070   }
00071   else
00072 #endif
00073     return(Field::unpack(to, from, param_data, low_byte_first));
00074 }
00075 
00076 /*
00077   If a field has fixed length, truncate the double argument pointed to by 'nr'
00078   appropriately.
00079   Also ensure that the argument is within [-max_value; max_value] range.
00080 */
00081 
00082 int Field_real::truncate(double *nr, double max_value)
00083 {
00084   int error= 1;
00085   double res= *nr;
00086 
00087   if (res == numeric_limits<double>::quiet_NaN())
00088   {
00089     res= 0;
00090     set_null();
00091     set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
00092     goto end;
00093   }
00094 
00095   if (!not_fixed)
00096   {
00097     uint32_t order= field_length - dec;
00098     uint32_t step= array_elements(log_10) - 1;
00099     max_value= 1.0;
00100     for (; order > step; order-= step)
00101       max_value*= log_10[step];
00102     max_value*= log_10[order];
00103     max_value-= 1.0 / log_10[dec];
00104 
00105     /* Check for infinity so we don't get NaN in calculations */
00106     if (res != numeric_limits<double>::infinity())
00107     {
00108       double tmp= rint((res - floor(res)) * log_10[dec]) / log_10[dec];
00109       res= floor(res) + tmp;
00110     }
00111   }
00112 
00113   if (res < -max_value)
00114   {
00115    res= -max_value;
00116    set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
00117   }
00118   else if (res > max_value)
00119   {
00120     res= max_value;
00121     set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
00122   }
00123   else
00124     error= 0;
00125 
00126 end:
00127   *nr= res;
00128   return error;
00129 }
00130 
00131 
00132 int Field_real::store_decimal(const type::Decimal *dm)
00133 {
00134   double dbl;
00135   class_decimal2double(E_DEC_FATAL_ERROR, dm, &dbl);
00136   return store(dbl);
00137 }
00138 
00139 type::Decimal *Field_real::val_decimal(type::Decimal *decimal_value) const
00140 {
00141   ASSERT_COLUMN_MARKED_FOR_READ;
00142 
00143   double2_class_decimal(E_DEC_FATAL_ERROR, val_real(), decimal_value);
00144   return decimal_value;
00145 }
00146 
00147 } /* namespace drizzled */