2436
2432
/****************************************************************************
2437
double precision floating point numbers
2438
****************************************************************************/
2440
int Field_double::store(const char *from,uint len,CHARSET_INFO *cs)
2444
double nr= my_strntod(cs,(char*) from, len, &end, &error);
2445
if (error || (!len || (((uint) (end-from) != len) && table->in_use->count_cuted_fields)))
2447
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
2448
(error ? ER_WARN_DATA_OUT_OF_RANGE : WARN_DATA_TRUNCATED), 1);
2449
error= error ? 1 : 2;
2451
Field_double::store(nr);
2456
int Field_double::store(double nr)
2458
int error= truncate(&nr, DBL_MAX);
2460
#ifdef WORDS_BIGENDIAN
2461
if (table->s->db_low_byte_first)
2463
float8store(ptr,nr);
2467
doublestore(ptr,nr);
2472
int Field_double::store(int64_t nr, bool unsigned_val)
2474
return Field_double::store(unsigned_val ? uint64_t2double((uint64_t) nr) :
2479
If a field has fixed length, truncate the double argument pointed to by 'nr'
2481
Also ensure that the argument is within [-max_value; max_value] range.
2484
int Field_real::truncate(double *nr, double max_value)
2493
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
2496
else if (unsigned_flag && res < 0)
2499
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
2505
uint order= field_length - dec;
2506
uint step= array_elements(log_10) - 1;
2508
for (; order > step; order-= step)
2509
max_value*= log_10[step];
2510
max_value*= log_10[order];
2511
max_value-= 1.0 / log_10[dec];
2513
/* Check for infinity so we don't get NaN in calculations */
2516
double tmp= rint((res - floor(res)) * log_10[dec]) / log_10[dec];
2517
res= floor(res) + tmp;
2521
if (res < -max_value)
2524
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
2526
else if (res > max_value)
2529
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
2540
int Field_real::store_decimal(const my_decimal *dm)
2543
my_decimal2double(E_DEC_FATAL_ERROR, dm, &dbl);
2547
double Field_double::val_real(void)
2550
#ifdef WORDS_BIGENDIAN
2551
if (table->s->db_low_byte_first)
2561
int64_t Field_double::val_int(void)
2565
#ifdef WORDS_BIGENDIAN
2566
if (table->s->db_low_byte_first)
2573
/* Check whether we fit into int64_t range */
2574
if (j <= (double) INT64_MIN)
2576
res= (int64_t) INT64_MIN;
2579
if (j >= (double) (uint64_t) INT64_MAX)
2581
res= (int64_t) INT64_MAX;
2584
return (int64_t) rint(j);
2588
char buf[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE];
2589
String tmp(buf, sizeof(buf), &my_charset_latin1), *str;
2590
str= val_str(&tmp, 0);
2591
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
2592
ER_TRUNCATED_WRONG_VALUE,
2593
ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER",
2600
my_decimal *Field_real::val_decimal(my_decimal *decimal_value)
2602
double2my_decimal(E_DEC_FATAL_ERROR, val_real(), decimal_value);
2603
return decimal_value;
2607
String *Field_double::val_str(String *val_buffer,
2608
String *val_ptr __attribute__((unused)))
2611
#ifdef WORDS_BIGENDIAN
2612
if (table->s->db_low_byte_first)
2620
uint to_length=max(field_length, DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE);
2621
val_buffer->alloc(to_length);
2622
char *to=(char*) val_buffer->ptr();
2625
if (dec >= NOT_FIXED_DEC)
2626
len= my_gcvt(nr, MY_GCVT_ARG_DOUBLE, to_length - 1, to, NULL);
2628
len= my_fcvt(nr, dec, to, NULL);
2630
val_buffer->length((uint) len);
2632
prepend_zeros(val_buffer);
2636
bool Field_double::send_binary(Protocol *protocol)
2638
return protocol->store((double) Field_double::val_real(), dec, (String*) 0);
2642
int Field_double::cmp(const uchar *a_ptr, const uchar *b_ptr)
2645
#ifdef WORDS_BIGENDIAN
2646
if (table->s->db_low_byte_first)
2654
doubleget(a, a_ptr);
2655
doubleget(b, b_ptr);
2657
return (a < b) ? -1 : (a > b) ? 1 : 0;
2661
#define DBL_EXP_DIG (sizeof(double)*8-DBL_MANT_DIG)
2663
/* The following should work for IEEE */
2665
void Field_double::sort_string(uchar *to,uint length __attribute__((unused)))
2668
#ifdef WORDS_BIGENDIAN
2669
if (table->s->db_low_byte_first)
2676
change_double_for_sort(nr, to);
2681
Save the field metadata for double fields.
2683
Saves the pack length in the first byte of the field metadata array
2684
at index of *metadata_ptr.
2686
@param metadata_ptr First byte of field metadata
2688
@returns number of bytes written to metadata_ptr
2690
int Field_double::do_save_field_metadata(uchar *metadata_ptr)
2692
*metadata_ptr= pack_length();
2697
void Field_double::sql_type(String &res) const
2699
CHARSET_INFO *cs=res.charset();
2700
if (dec == NOT_FIXED_DEC)
2702
res.set_ascii(STRING_WITH_LEN("double"));
2706
res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
2707
"double(%d,%d)",(int) field_length,dec));
2709
add_zerofill_and_unsigned(res);
2713
/****************************************************************************
2715
2434
** A string may be varchar or binary
2716
2435
****************************************************************************/