MySQL 8.0.40
Source Code Documentation
decimal.cc File Reference
#include "decimal.h"
#include <limits.h>
#include <math.h>
#include <stdint.h>
#include <string.h>
#include <algorithm>
#include <type_traits>
#include <utility>
#include "integer_digits.h"
#include "m_ctype.h"
#include "m_string.h"
#include "my_compiler.h"
#include "my_dbug.h"
#include "my_sys.h"
#include "myisampack.h"

Namespaces

namespace  anonymous_namespace{decimal.cc}
 

Macros

#define DIG_PER_DEC1   9
 
#define DIG_MASK   100000000
 
#define DIG_BASE   1000000000
 
#define DIG_MAX   (DIG_BASE - 1)
 
#define ROUND_UP(X)   (((X) + DIG_PER_DEC1 - 1) / DIG_PER_DEC1)
 
#define sanity(d)   assert((d)->len > 0)
 
#define ADD(to, from1, from2, carry)
 
#define ADD2(to, from1, from2, carry)
 
#define SUB(to, from1, from2, carry)
 
#define SUB2(to, from1, from2, carry)
 
#define LLDIV_MIN   -1000000000000000000LL
 
#define LLDIV_MAX   1000000000000000000LL
 

Typedefs

using dec1 = decimal_digit_t
 Internally decimal numbers are stored base 10^9 (see DIG_BASE below) So one variable of type decimal_digit_t is limited: More...
 
using dec2 = int64_t
 A wider variant of dec1, to avoid overflow in intermediate results. More...
 
using udec1 = std::make_unsigned< dec1 >::type
 An unsigned type with the same width as dec1. More...
 

Functions

static dec1 div_by_pow10 (dec1 x, int p)
 
static dec1 mod_by_pow10 (dec1 x, int p)
 
void anonymous_namespace{decimal.cc}::fix_intg_frac_error (const int &len, int *intg1, int *frac1, int *error)
 Verifies input arguments len, intg1 and frac1, and sets error output argument to indicate over/under-flow or OK. More...
 
static ALWAYS_INLINE int decimal_bin_size_inline (int precision, int scale)
 
static int count_leading_zeroes (int i, dec1 val)
 
static int count_trailing_zeroes (int i, dec1 val)
 
void max_decimal (int precision, int frac, decimal_t *to)
 
static dec1remove_leading_zeroes (const decimal_t *from, int *intg_result)
 
int decimal_actual_fraction (const decimal_t *from)
 
int decimal2string (const decimal_t *from, char *to, int *to_len, int fixed_precision, int fixed_decimals)
 
static void digits_bounds (const decimal_t *from, int *start_result, int *end_result)
 
static void do_mini_left_shift (decimal_t *dec, int shift, int beg, int last)
 
static void do_mini_right_shift (decimal_t *dec, int shift, int beg, int last)
 
int decimal_shift (decimal_t *dec, int shift)
 
int string2decimal (const char *from, decimal_t *to, const char **end)
 
void widen_fraction (int new_frac, decimal_t *d)
 Add zeros behind comma to increase precision of decimal. More...
 
int decimal2double (const decimal_t *from, double *to)
 
int double2decimal (double from, decimal_t *to)
 
static int ull2dec (ulonglong from, decimal_t *to)
 
int ulonglong2decimal (ulonglong from, decimal_t *to)
 
int longlong2decimal (longlong from, decimal_t *to)
 
int decimal2ulonglong (const decimal_t *from, ulonglong *to)
 
int decimal2longlong (const decimal_t *from, longlong *to)
 
int decimal2lldiv_t (const decimal_t *from, lldiv_t *to)
 Convert decimal to lldiv_t. More...
 
int double2lldiv_t (double nr, lldiv_t *lld)
 Convert double value to lldiv_t value. More...
 
int decimal2bin (const decimal_t *from, uchar *to, int precision, int frac)
 
int bin2decimal (const uchar *from, decimal_t *to, int precision, int scale, bool keep_prec)
 
int decimal_size (int precision, int scale)
 
int decimal_bin_size (int precision, int scale)
 
int decimal_round (const decimal_t *from, decimal_t *to, int scale, decimal_round_mode mode)
 
static int do_add (const decimal_t *from1, const decimal_t *from2, decimal_t *to)
 
static int do_sub (const decimal_t *from1, const decimal_t *from2, decimal_t *to)
 
int decimal_intg (const decimal_t *from)
 Returns the number of decimal digits before the decimal point in a decimal_t, with any insignificant leading zeros removed. More...
 
int decimal_add (const decimal_t *from1, const decimal_t *from2, decimal_t *to)
 
int decimal_sub (const decimal_t *from1, const decimal_t *from2, decimal_t *to)
 
int decimal_cmp (const decimal_t *from1, const decimal_t *from2)
 
int decimal_is_zero (const decimal_t *from)
 
int decimal_mul (const decimal_t *from_1, const decimal_t *from_2, decimal_t *to)
 
static int do_div_mod (const decimal_t *from1, const decimal_t *from2, decimal_t *to, decimal_t *mod, int scale_incr)
 
int decimal_div (const decimal_t *from1, const decimal_t *from2, decimal_t *to, int scale_incr)
 
int decimal_mod (const decimal_t *from1, const decimal_t *from2, decimal_t *to)
 

Variables

static const dec1 powers10 [DIG_PER_DEC1+1]
 
static const int dig2bytes [DIG_PER_DEC1+1] = {0, 1, 1, 2, 2, 3, 3, 4, 4, 4}
 
static const dec1 frac_max [DIG_PER_DEC1 - 1]
 

Macro Definition Documentation

◆ ADD

#define ADD (   to,
  from1,
  from2,
  carry 
)
Value:
/* assume carry <= 1 */ \
do { \
dec1 a = (from1) + (from2) + (carry); \
assert((carry) <= 1); \
if (((carry) = a >= DIG_BASE)) /* no division here! */ \
a -= DIG_BASE; \
(to) = a; \
} while (0)
#define DIG_BASE
Definition: decimal.cc:154

◆ ADD2

#define ADD2 (   to,
  from1,
  from2,
  carry 
)
Value:
do { \
dec2 a = ((dec2)(from1)) + (from2) + (carry); \
if (((carry) = a >= DIG_BASE)) a -= DIG_BASE; \
if (unlikely(a >= DIG_BASE)) { \
a -= DIG_BASE; \
carry++; \
} \
(to) = (dec1)a; \
} while (0)
decimal_digit_t dec1
Internally decimal numbers are stored base 10^9 (see DIG_BASE below) So one variable of type decimal_...
Definition: decimal.cc:146
int64_t dec2
A wider variant of dec1, to avoid overflow in intermediate results.
Definition: decimal.cc:148
constexpr bool unlikely(bool expr)
Definition: my_compiler.h:56

◆ DIG_BASE

#define DIG_BASE   1000000000

◆ DIG_MASK

#define DIG_MASK   100000000

◆ DIG_MAX

#define DIG_MAX   (DIG_BASE - 1)

◆ DIG_PER_DEC1

#define DIG_PER_DEC1   9

◆ LLDIV_MAX

#define LLDIV_MAX   1000000000000000000LL

◆ LLDIV_MIN

#define LLDIV_MIN   -1000000000000000000LL

◆ ROUND_UP

#define ROUND_UP (   X)    (((X) + DIG_PER_DEC1 - 1) / DIG_PER_DEC1)

◆ sanity

#define sanity (   d)    assert((d)->len > 0)

◆ SUB

#define SUB (   to,
  from1,
  from2,
  carry 
)
Value:
/* to=from1-from2 */ \
do { \
dec1 a = (from1) - (from2) - (carry); \
if (((carry) = a < 0)) a += DIG_BASE; \
(to) = a; \
} while (0)

◆ SUB2

#define SUB2 (   to,
  from1,
  from2,
  carry 
)
Value:
/* to=from1-from2 */ \
do { \
dec1 a = (from1) - (from2) - (carry); \
if (((carry) = a < 0)) a += DIG_BASE; \
if (unlikely(a < 0)) { \
a += DIG_BASE; \
carry++; \
} \
(to) = a; \
} while (0)
if(!(yy_init))
Definition: lexyy.cc:1144

Typedef Documentation

◆ dec1

Internally decimal numbers are stored base 10^9 (see DIG_BASE below) So one variable of type decimal_digit_t is limited:

0 < decimal_digit <= DIG_MAX < DIG_BASE

in the decimal_t:

intg is the number of decimal digits (NOT number of decimal_digit_t's !) before the point frac - number of decimal digits after the point buf is an array of decimal_digit_t's len is the length of buf (length of allocated space) in decimal_digit_t's, not in bytes

◆ dec2

using dec2 = int64_t

A wider variant of dec1, to avoid overflow in intermediate results.

◆ udec1

using udec1 = std::make_unsigned<dec1>::type

An unsigned type with the same width as dec1.

Function Documentation

◆ bin2decimal()

int bin2decimal ( const uchar from,
decimal_t to,
int  precision,
int  scale,
bool  keep_prec 
)

◆ count_leading_zeroes()

static int count_leading_zeroes ( int  i,
dec1  val 
)
inlinestatic

◆ count_trailing_zeroes()

static int count_trailing_zeroes ( int  i,
dec1  val 
)
inlinestatic

◆ decimal2bin()

int decimal2bin ( const decimal_t from,
uchar to,
int  precision,
int  frac 
)

◆ decimal2double()

int decimal2double ( const decimal_t from,
double *  to 
)

◆ decimal2lldiv_t()

int decimal2lldiv_t ( const decimal_t from,
lldiv_t *  to 
)

Convert decimal to lldiv_t.

The integer part is stored in to->quot. The fractional part is multiplied to 10^9 and stored to to->rem.

Parameters
fromDecimal value
[out]tolldiv_t value
Return values
0on success
!0in error

◆ decimal2longlong()

int decimal2longlong ( const decimal_t from,
longlong to 
)

◆ decimal2string()

int decimal2string ( const decimal_t from,
char *  to,
int *  to_len,
int  fixed_precision,
int  fixed_decimals 
)

◆ decimal2ulonglong()

int decimal2ulonglong ( const decimal_t from,
ulonglong to 
)

◆ decimal_actual_fraction()

int decimal_actual_fraction ( const decimal_t from)

◆ decimal_add()

int decimal_add ( const decimal_t from1,
const decimal_t from2,
decimal_t to 
)

◆ decimal_bin_size()

int decimal_bin_size ( int  precision,
int  scale 
)

◆ decimal_bin_size_inline()

static ALWAYS_INLINE int decimal_bin_size_inline ( int  precision,
int  scale 
)
static

◆ decimal_cmp()

int decimal_cmp ( const decimal_t from1,
const decimal_t from2 
)

◆ decimal_div()

int decimal_div ( const decimal_t from1,
const decimal_t from2,
decimal_t to,
int  scale_incr 
)

◆ decimal_intg()

int decimal_intg ( const decimal_t from)

Returns the number of decimal digits before the decimal point in a decimal_t, with any insignificant leading zeros removed.

◆ decimal_is_zero()

int decimal_is_zero ( const decimal_t from)

◆ decimal_mod()

int decimal_mod ( const decimal_t from1,
const decimal_t from2,
decimal_t to 
)

◆ decimal_mul()

int decimal_mul ( const decimal_t from_1,
const decimal_t from_2,
decimal_t to 
)

◆ decimal_round()

int decimal_round ( const decimal_t from,
decimal_t to,
int  scale,
decimal_round_mode  mode 
)

◆ decimal_shift()

int decimal_shift ( decimal_t dec,
int  shift 
)

◆ decimal_size()

int decimal_size ( int  precision,
int  scale 
)

◆ decimal_sub()

int decimal_sub ( const decimal_t from1,
const decimal_t from2,
decimal_t to 
)

◆ digits_bounds()

static void digits_bounds ( const decimal_t from,
int *  start_result,
int *  end_result 
)
static

◆ div_by_pow10()

static dec1 div_by_pow10 ( dec1  x,
int  p 
)
inlinestatic

◆ do_add()

static int do_add ( const decimal_t from1,
const decimal_t from2,
decimal_t to 
)
static

◆ do_div_mod()

static int do_div_mod ( const decimal_t from1,
const decimal_t from2,
decimal_t to,
decimal_t mod,
int  scale_incr 
)
static

◆ do_mini_left_shift()

static void do_mini_left_shift ( decimal_t dec,
int  shift,
int  beg,
int  last 
)
static

◆ do_mini_right_shift()

static void do_mini_right_shift ( decimal_t dec,
int  shift,
int  beg,
int  last 
)
static

◆ do_sub()

static int do_sub ( const decimal_t from1,
const decimal_t from2,
decimal_t to 
)
static

◆ double2decimal()

int double2decimal ( double  from,
decimal_t to 
)

◆ double2lldiv_t()

int double2lldiv_t ( double  nr,
lldiv_t *  lld 
)

Convert double value to lldiv_t value.

Parameters
nrThe double value to convert from.
[out]lldThe lldit_t variable to convert to.
Returns
0 on success, error code on error.

Integer part goes into lld.quot. Fractional part multiplied to 1000000000 (10^9) goes to lld.rem. Typically used in datetime calculations to split seconds and nanoseconds.

◆ longlong2decimal()

int longlong2decimal ( longlong  from,
decimal_t to 
)

◆ max_decimal()

void max_decimal ( int  precision,
int  frac,
decimal_t to 
)

◆ mod_by_pow10()

static dec1 mod_by_pow10 ( dec1  x,
int  p 
)
inlinestatic

◆ remove_leading_zeroes()

static dec1 * remove_leading_zeroes ( const decimal_t from,
int *  intg_result 
)
inlinestatic

◆ string2decimal()

int string2decimal ( const char *  from,
decimal_t to,
const char **  end 
)

◆ ull2dec()

static int ull2dec ( ulonglong  from,
decimal_t to 
)
static

◆ ulonglong2decimal()

int ulonglong2decimal ( ulonglong  from,
decimal_t to 
)

◆ widen_fraction()

void widen_fraction ( int  new_frac,
decimal_t d 
)

Add zeros behind comma to increase precision of decimal.

Parameters
new_fracthe new fraction
[in,out]dthe decimal target

new_frac is expected to >= than cd->frac and new fraction is expected to fit in d.

Variable Documentation

◆ dig2bytes

const int dig2bytes[DIG_PER_DEC1+1] = {0, 1, 1, 2, 2, 3, 3, 4, 4, 4}
static

◆ frac_max

const dec1 frac_max[DIG_PER_DEC1 - 1]
static
Initial value:
= {900000000, 990000000, 999000000,
999900000, 999990000, 999999000,
999999900, 999999990}

◆ powers10

const dec1 powers10[DIG_PER_DEC1+1]
static
Initial value:
= {
1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000}