MySQL 8.0.33
Source Code Documentation
decimal.h
Go to the documentation of this file.
1/* Copyright (c) 2000, 2023, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23#ifndef DECIMAL_INCLUDED
24#define DECIMAL_INCLUDED
25
26#ifndef MYSQL_ABI_CHECK
27#include <stdlib.h>
28#endif
29
30#include "my_inttypes.h"
31#include "my_macros.h"
32
33typedef enum {
38 FLOOR
41
42/**
43 intg is the number of *decimal* digits (NOT number of decimal_digit_t's !)
44 before the point
45 frac is the number of decimal digits after the point
46 len is the length of buf (length of allocated space) in decimal_digit_t's,
47 not in bytes
48 sign false means positive, true means negative
49 buf is an array of decimal_digit_t's
50 */
51struct decimal_t {
52 int intg, frac, len;
53 bool sign;
55};
56
57#ifndef MYSQL_ABI_CHECK
58void widen_fraction(int new_frac, decimal_t *d);
59int string2decimal(const char *from, decimal_t *to, const char **end);
60int decimal2string(const decimal_t *from, char *to, int *to_len,
61 int fixed_precision, int fixed_decimals);
62inline int decimal2string(const decimal_t *from, char *to, int *to_len) {
63 return decimal2string(from, to, to_len, 0, 0);
64}
65int decimal2ulonglong(const decimal_t *from, ulonglong *to);
67int decimal2longlong(const decimal_t *from, longlong *to);
69int decimal2double(const decimal_t *from, double *to);
70int double2decimal(double from, decimal_t *to);
71int decimal_actual_fraction(const decimal_t *from);
72int decimal2bin(const decimal_t *from, uchar *to, int precision, int scale);
73int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale,
74 bool keep_prec = false);
75
76/**
77 Convert decimal to lldiv_t.
78 The integer part is stored in to->quot.
79 The fractional part is multiplied to 10^9 and stored to to->rem.
80 @param from Decimal value
81 @param [out] to lldiv_t value
82 @retval 0 on success
83 @retval !0 in error
84*/
85int decimal2lldiv_t(const decimal_t *from, lldiv_t *to);
86
87/**
88 Convert double value to lldiv_t value.
89 @param nr The double value to convert from.
90 @param [out] lld The lldit_t variable to convert to.
91 @return 0 on success, error code on error.
92
93 Integer part goes into lld.quot.
94 Fractional part multiplied to 1000000000 (10^9) goes to lld.rem.
95 Typically used in datetime calculations to split seconds
96 and nanoseconds.
97 */
98int double2lldiv_t(double nr, lldiv_t *lld);
99int decimal_size(int precision, int scale);
100int decimal_bin_size(int precision, int scale);
101
102int decimal_intg(const decimal_t *from);
103int decimal_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to);
104int decimal_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to);
105int decimal_cmp(const decimal_t *from1, const decimal_t *from2);
106int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to);
107int decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to,
108 int scale_incr);
109int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to);
110int decimal_round(const decimal_t *from, decimal_t *to, int new_scale,
112int decimal_is_zero(const decimal_t *from);
113void max_decimal(int precision, int frac, decimal_t *to);
114int decimal_shift(decimal_t *dec, int shift);
115
116/* set a decimal_t to zero */
117static inline void decimal_make_zero(decimal_t *dec) {
118 dec->buf[0] = 0;
119 dec->intg = 1;
120 dec->frac = 0;
121 dec->sign = false;
122}
123
124/**
125 Returns the length of the buffer to hold string representation
126 of the decimal (including decimal dot, possible sign and \0)
127*/
128static inline int decimal_string_size(const decimal_t *dec) {
129 return (dec->intg ? dec->intg : 1) + dec->frac + (dec->frac > 0) + 2;
130}
131
132/*
133 conventions:
134
135 decimal_smth() == 0 -- everything's ok
136 decimal_smth() <= 1 -- result is usable, but precision loss is
137 possible decimal_smth() <= 2 -- result can be unusable, most significant
138 digits could've been lost decimal_smth() > 2 -- no result was generated
139*/
140
141#define E_DEC_OK 0
142#define E_DEC_TRUNCATED 1
143#define E_DEC_OVERFLOW 2
144#define E_DEC_DIV_ZERO 4
145#define E_DEC_BAD_NUM 8
146#define E_DEC_OOM 16
147
148#define E_DEC_FATAL_ERROR \
149 (E_DEC_OVERFLOW | E_DEC_DIV_ZERO | E_DEC_BAD_NUM | E_DEC_OOM)
150#define E_DEC_ERROR (E_DEC_FATAL_ERROR | E_DEC_TRUNCATED)
151
152static constexpr int DECIMAL_MAX_SCALE{30};
153static constexpr int DECIMAL_NOT_SPECIFIED{DECIMAL_MAX_SCALE + 1};
154
155#endif // MYSQL_ABI_CHECK
156
157#endif // DECIMAL_INCLUDED
int decimal_round(const decimal_t *from, decimal_t *to, int new_scale, decimal_round_mode mode)
Definition: decimal.cc:1656
int decimal_bin_size(int precision, int scale)
Definition: decimal.cc:1634
int decimal2longlong(const decimal_t *from, longlong *to)
Definition: decimal.cc:1177
int ulonglong2decimal(ulonglong from, decimal_t *to)
Definition: decimal.cc:1141
int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
Definition: decimal.cc:2086
static int decimal_string_size(const decimal_t *dec)
Returns the length of the buffer to hold string representation of the decimal (including decimal dot,...
Definition: decimal.h:128
int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale, bool keep_prec=false)
Definition: decimal.cc:1488
int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
Definition: decimal.cc:2512
int double2lldiv_t(double nr, lldiv_t *lld)
Convert double value to lldiv_t value.
Definition: decimal.cc:1246
decimal_round_mode
Definition: decimal.h:33
@ CEILING
Definition: decimal.h:37
@ FLOOR
Definition: decimal.h:38
@ HALF_UP
Definition: decimal.h:36
@ TRUNCATE
Definition: decimal.h:34
@ HALF_EVEN
Definition: decimal.h:35
int decimal_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
Definition: decimal.cc:2037
int decimal_is_zero(const decimal_t *from)
Definition: decimal.cc:2057
int longlong2decimal(longlong from, decimal_t *to)
Definition: decimal.cc:1146
int decimal_actual_fraction(const decimal_t *from)
Definition: decimal.cc:482
int decimal2lldiv_t(const decimal_t *from, lldiv_t *to)
Convert decimal to lldiv_t.
Definition: decimal.cc:1224
static constexpr int DECIMAL_NOT_SPECIFIED
Definition: decimal.h:153
void max_decimal(int precision, int frac, decimal_t *to)
Definition: decimal.cc:428
int32 decimal_digit_t
Definition: decimal.h:40
int decimal2ulonglong(const decimal_t *from, ulonglong *to)
Definition: decimal.cc:1153
int decimal2bin(const decimal_t *from, uchar *to, int precision, int scale)
Definition: decimal.cc:1353
int decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to, int scale_incr)
Definition: decimal.cc:2480
int decimal_shift(decimal_t *dec, int shift)
Definition: decimal.cc:756
int decimal_size(int precision, int scale)
Definition: decimal.cc:1609
int string2decimal(const char *from, decimal_t *to, const char **end)
Definition: decimal.cc:928
static void decimal_make_zero(decimal_t *dec)
Definition: decimal.h:117
int decimal2double(const decimal_t *from, double *to)
Definition: decimal.cc:1071
int decimal2string(const decimal_t *from, char *to, int *to_len, int fixed_precision, int fixed_decimals)
Definition: decimal.cc:522
int decimal_cmp(const decimal_t *from1, const decimal_t *from2)
Definition: decimal.cc:2047
void widen_fraction(int new_frac, decimal_t *d)
Add zeros behind comma to increase precision of decimal.
Definition: decimal.cc:1044
int decimal_intg(const decimal_t *from)
Returns the number of decimal digits before the decimal point in a decimal_t, with any insignificant ...
Definition: decimal.cc:2031
int double2decimal(double from, decimal_t *to)
Definition: decimal.cc:1100
int decimal_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
Definition: decimal.cc:2042
static constexpr int DECIMAL_MAX_SCALE
Definition: decimal.h:152
static const std::string dec("DECRYPTION")
Some integer typedefs for easier portability.
unsigned long long int ulonglong
Definition: my_inttypes.h:55
unsigned char uchar
Definition: my_inttypes.h:51
long long int longlong
Definition: my_inttypes.h:54
int32_t int32
Definition: my_inttypes.h:65
Some common macros.
Cursor end()
A past-the-end Cursor.
Definition: rules_table_service.cc:191
mode
Definition: file_handle.h:59
intg is the number of decimal digits (NOT number of decimal_digit_t's !) before the point frac is the...
Definition: decimal.h:51
int frac
Definition: decimal.h:52
decimal_digit_t * buf
Definition: decimal.h:54
int intg
Definition: decimal.h:52
bool sign
Definition: decimal.h:53
int len
Definition: decimal.h:52