From 94dca6133d9b3f56292089ba246425a9ba6b7e6c Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 May 2005 20:06:49 +0500 Subject: A lot of fixes to Precision math Mostly about precision/decimals of the results of the operations include/decimal.h: decimal interface changed a little sql/field.cc: a lot of precision/decimals related changes to the Field_new_decimal sql/field.h: Field_new_decimal interface changed sql/ha_ndbcluster.cc: f->precision should be used here sql/item.cc: precision/decimals counting related changes sql/item.h: precision/decimals counting related changes sql/item_cmpfunc.cc: precision/decimals counting related changes sql/item_cmpfunc.h: precision/decimals counting related changes sql/item_func.cc: precision/decimals counting related changes sql/item_func.h: precision/decimals counting related changes sql/item_sum.cc: precision/decimals counting related changes sql/item_sum.h: precision/decimals counting related changes sql/my_decimal.cc: precision/decimals counting related changes sql/my_decimal.h: precision/decimals counting related changes sql/mysqld.cc: precision/decimals counting related changes sql/set_var.cc: precision/decimals counting related changes sql/sp_head.cc: dbug_decimal_print was replaced with dbug_decimal_as_string sql/sql_class.h: div_precincrement variable added sql/sql_parse.cc: precision/decimals counting related changes sql/sql_select.cc: precision/decimals counting related changes sql/sql_show.cc: Field::representation_length was removed strings/decimal.c: decimal_actual_fraction was introduced BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- sql/my_decimal.h | 46 +++++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 13 deletions(-) (limited to 'sql/my_decimal.h') diff --git a/sql/my_decimal.h b/sql/my_decimal.h index 03801390d82..27fd33cffbe 100644 --- a/sql/my_decimal.h +++ b/sql/my_decimal.h @@ -35,27 +35,27 @@ C_MODE_END #define DECIMAL_LONG_DIGITS 10 #define DECIMAL_LONG3_DIGITS 8 -/* number of digits on which we increase scale of devision result */ -#define DECIMAL_DIV_SCALE_INCREASE 5 - /* maximum length of buffer in our big digits (uint32) */ -#define DECIMAL_BUFF_LENGTH 8 +#define DECIMAL_BUFF_LENGTH 9 /* - maximum guaranteed length of number in decimal digits (number of our + maximum guaranteed precision of number in decimal digits (number of our digits * number of decimal digits in one our big digit - number of decimal digits in one our big digit decreased on 1 (because we always put decimal point on the border of our big digits)) */ -#define DECIMAL_MAX_LENGTH ((8 * 9) - 8) +#define DECIMAL_MAX_PRECISION ((DECIMAL_BUFF_LENGTH * 9) - 8*2) +#define DECIMAL_MAX_SCALE 30 +#define DECIMAL_NOT_SPECIFIED 31 + /* maximum length of string representation (number of maximum decimal digits + 1 position for sign + 1 position for decimal point) */ -#define DECIMAL_MAX_STR_LENGTH (DECIMAL_MAX_LENGTH + 2) +#define DECIMAL_MAX_STR_LENGTH (DECIMAL_MAX_PRECISION + 2) /* maximum size of packet length */ -#define DECIMAL_MAX_FIELD_SIZE DECIMAL_MAX_LENGTH +#define DECIMAL_MAX_FIELD_SIZE DECIMAL_MAX_PRECISION inline uint my_decimal_size(uint precision, uint scale) @@ -68,6 +68,12 @@ inline uint my_decimal_size(uint precision, uint scale) } +inline int my_decimal_int_part(uint precision, uint decimals) +{ + return precision - ((decimals == DECIMAL_NOT_SPECIFIED) ? 0 : decimals); +} + + /* my_decimal class limits 'decimal_t' type to what we need in MySQL It contains internally all necessary space needed by the instance so @@ -99,15 +105,16 @@ public: bool sign() const { return decimal_t::sign; } void sign(bool s) { decimal_t::sign= s; } + uint precision() const { return intg + frac; } }; #ifndef DBUG_OFF void print_decimal(const my_decimal *dec); void print_decimal_buff(const my_decimal *dec, const byte* ptr, int length); -void dbug_print_decimal(const char *tag, const char *format, my_decimal *val); +const char *dbug_decimal_as_string(char *buff, const my_decimal *val); #else -#define dbug_print_decimal(A,B,C) +#define dbug_decimal_as_string(A) NULL #endif #ifndef MYSQL_CLIENT @@ -126,6 +133,18 @@ inline int check_result(uint mask, int result) return result; } +inline uint my_decimal_length_to_precision(uint length, uint scale, + bool unsigned_flag) +{ + return (uint) (length - (scale>0 ? 1:0) - (unsigned_flag ? 0:1)); +} + +inline uint32 my_decimal_precision_to_length(uint precision, uint8 scale, + bool unsigned_flag) +{ + set_if_smaller(precision, DECIMAL_MAX_PRECISION); + return (uint32)(precision + (scale>0 ? 1:0) + (unsigned_flag ? 0:1)); +} inline int my_decimal_string_length(const my_decimal *d) @@ -209,8 +228,8 @@ int my_decimal_ceiling(uint mask, const my_decimal *from, my_decimal *to) #ifndef MYSQL_CLIENT -int my_decimal2string(uint mask, const my_decimal *d, int fixed_prec, - int fixed_dec, char filler, String *str); +int my_decimal2string(uint mask, const my_decimal *d, uint fixed_prec, + uint fixed_dec, char filler, String *str); #endif inline @@ -326,7 +345,8 @@ int my_decimal_cmp(const my_decimal *a, const my_decimal *b) inline void max_my_decimal(my_decimal *to, int precision, int frac) { - DBUG_ASSERT(precision <= DECIMAL_MAX_LENGTH); + DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION)&& + (frac <= DECIMAL_MAX_SCALE)); max_decimal(precision, frac, (decimal_t*) to); } -- cgit v1.2.1