~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/function/math/round.cc

  • Committer: Lee
  • Date: 2009-01-01 17:36:53 UTC
  • mto: (758.1.3 devel)
  • mto: This revision was merged to the branch mainline in revision 759.
  • Revision ID: lbieber@lbieber-desktop-20090101173653-qo5945pnje5j3vuu
more header file cleanup

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
#include "config.h"
21
 
 
22
 
#include <math.h>
23
 
#include <limits.h>
24
 
 
25
 
#include <limits>
26
 
#include <algorithm>
27
 
 
28
 
#include "drizzled/function/math/round.h"
29
 
#include "drizzled/util/test.h"
30
 
 
31
 
namespace drizzled
32
 
{
33
 
 
34
 
extern const double log_10[309];
35
 
 
36
 
 
 
20
#include <drizzled/server_includes.h>
 
21
#include CSTDINT_H
 
22
#include <drizzled/function/math/round.h>
 
23
#include CMATH_H
 
24
#include <drizzled/util/math.h>
 
25
 
 
26
#if defined(CMATH_NAMESPACE)
 
27
using namespace CMATH_NAMESPACE;
 
28
#endif
37
29
using namespace std;
38
30
 
39
31
void Item_func_round::fix_length_and_dec()
67
59
  if (args[0]->decimals == NOT_FIXED_DEC)
68
60
  {
69
61
    max_length= args[0]->max_length;
70
 
    decimals= min(decimals_to_set, (int)NOT_FIXED_DEC);
 
62
    decimals= cmin(decimals_to_set, NOT_FIXED_DEC);
71
63
    hybrid_type= REAL_RESULT;
72
64
    return;
73
65
  }
76
68
  case REAL_RESULT:
77
69
  case STRING_RESULT:
78
70
    hybrid_type= REAL_RESULT;
79
 
    decimals= min(decimals_to_set, (int)NOT_FIXED_DEC);
 
71
    decimals= cmin(decimals_to_set, NOT_FIXED_DEC);
80
72
    max_length= float_length(decimals);
81
73
    break;
82
74
  case INT_RESULT:
93
85
  case DECIMAL_RESULT:
94
86
  {
95
87
    hybrid_type= DECIMAL_RESULT;
96
 
    decimals_to_set= min(DECIMAL_MAX_SCALE, decimals_to_set);
 
88
    decimals_to_set= cmin(DECIMAL_MAX_SCALE, decimals_to_set);
97
89
    int decimals_delta= args[0]->decimals - decimals_to_set;
98
90
    int precision= args[0]->decimal_precision();
99
91
    int length_increase= ((decimals_delta <= 0) || truncate) ? 0:1;
100
92
 
101
93
    precision-= decimals_delta - length_increase;
102
 
    decimals= min(decimals_to_set, DECIMAL_MAX_SCALE);
 
94
    decimals= cmin(decimals_to_set, DECIMAL_MAX_SCALE);
103
95
    max_length= my_decimal_precision_to_length(precision, decimals,
104
96
                                               unsigned_flag);
105
97
    break;
119
111
    tmp2 is here to avoid return the value with 80 bit precision
120
112
    This will fix that the test round(0.1,1) = round(0.1,1) is true
121
113
  */
122
 
  double tmp2;
 
114
  volatile double tmp2;
123
115
 
124
116
  tmp=(abs_dec < array_elements(log_10) ?
125
117
       log_10[abs_dec] : pow(10.0,(double) abs_dec));
126
118
 
127
 
  double value_times_tmp= value * tmp;
128
 
 
129
 
  /*
130
 
    NOTE: This is a workaround for a gcc 4.3 bug on Intel x86 32bit
131
 
    See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39228
132
 
    See http://bugs.mysql.com/bug.php?id=42965
133
 
 
134
 
    This forces the compiler to store/load the value as 64bit and avoids
135
 
    an optimisation that *could* have the infinite check be done on the 80bit
136
 
    representation.
137
 
   */
138
 
  if(sizeof(double) < sizeof(double_t))
139
 
  {
140
 
    volatile double t= value_times_tmp;
141
 
    value_times_tmp= t;
142
 
  }
143
 
 
144
 
  double infinity= numeric_limits<double>::infinity();
145
 
  if (dec_negative && (tmp == infinity))
 
119
  if (dec_negative && isinf(tmp))
146
120
    tmp2= 0;
147
 
  else if (!dec_negative && (value_times_tmp == infinity))
 
121
  else if (!dec_negative && isinf(value * tmp))
148
122
    tmp2= value;
149
123
  else if (truncate)
150
124
  {
203
177
 
204
178
  if (truncate)
205
179
    value= (unsigned_flag) ?
206
 
      (int64_t)(((uint64_t) value / tmp) * tmp) : (value / tmp) * tmp;
 
180
      ((uint64_t) value / tmp) * tmp : (value / tmp) * tmp;
207
181
  else
208
182
    value= (unsigned_flag || value >= 0) ?
209
 
      (int64_t)(my_unsigned_round((uint64_t) value, tmp)) :
 
183
      my_unsigned_round((uint64_t) value, tmp) :
210
184
      -(int64_t) my_unsigned_round((uint64_t) -value, tmp);
211
185
  return value;
212
186
}
216
190
{
217
191
  my_decimal val, *value= args[0]->val_decimal(&val);
218
192
  int64_t dec= args[1]->val_int();
219
 
 
220
193
  if (dec >= 0 || args[1]->unsigned_flag)
221
 
    dec= min(dec, (int64_t) decimals);
 
194
    dec= cmin(dec, (int64_t) decimals);
222
195
  else if (dec < INT_MIN)
223
196
    dec= INT_MIN;
224
197
 
232
205
  return 0;
233
206
}
234
207
 
235
 
} /* namespace drizzled */