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
00035 extern const double log_10[309];
00036
00037
00038
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
00078
00079
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
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 }