00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
00077
00078
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
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 }