MySQL 9.0.0
Source Code Documentation
decimal.h
Go to the documentation of this file.
1/* Copyright (c) 2000, 2024, 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 designed to work 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 either included with
13 the program or referenced in the documentation.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24#ifndef DECIMAL_INCLUDED
25#define DECIMAL_INCLUDED
26
27#ifndef MYSQL_ABI_CHECK
28#include <stdlib.h>
29#endif
30
31#include "my_inttypes.h"
32#include "my_macros.h"
33
34typedef enum {
39 FLOOR
42
43/**
44 Base struct used to represent decimal data type.
45
46 As stated in my_decimal::init, we do not initialize these members,
47 even though clang-tidy complains, as we want to catch uninitialized use.
48*/
49struct decimal_t {
50 /// The number of *decimal* digits (NOT number of decimal_digit_t's !)
51 /// before the point.
52 int intg;
53 /// The number of decimal digits after the point.
54 int frac;
55 /// The length of buf (length of allocated space) in decimal_digit_t's,
56 /// not in bytes.
57 int len;
58 /// False means positive, true means negative.
59 bool sign;
60 /// An array of decimal_digit_t's.
62};
63
64#ifndef MYSQL_ABI_CHECK
65void widen_fraction(int new_frac, decimal_t *d);
66int string2decimal(const char *from, decimal_t *to, const char **end);
67int decimal2string(const decimal_t *from, char *to, int *to_len,
68 int fixed_precision, int fixed_decimals);
69inline int decimal2string(const decimal_t *from, char *to, int *to_len) {
70 return decimal2string(from, to, to_len, 0, 0);
71}
72int decimal2ulonglong(const decimal_t *from, ulonglong *to);
74int decimal2longlong(const decimal_t *from, longlong *to);
76int decimal2double(const decimal_t *from, double *to);
77int double2decimal(double from, decimal_t *to);
78int decimal_actual_fraction(const decimal_t *from);
79int decimal2bin(const decimal_t *from, uchar *to, int precision, int scale);
80int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale,
81 bool keep_prec = false);
82
83/**
84 Convert decimal to lldiv_t.
85 The integer part is stored in to->quot.
86 The fractional part is multiplied to 10^9 and stored to to->rem.
87 @param from Decimal value
88 @param [out] to lldiv_t value
89 @retval 0 on success
90 @retval !0 in error
91*/
92int decimal2lldiv_t(const decimal_t *from, lldiv_t *to);
93
94/**
95 Convert double value to lldiv_t value.
96 @param nr The double value to convert from.
97 @param [out] lld The lldit_t variable to convert to.
98 @return 0 on success, error code on error.
99
100 Integer part goes into lld.quot.
101 Fractional part multiplied to 1000000000 (10^9) goes to lld.rem.
102 Typically used in datetime calculations to split seconds
103 and nanoseconds.
104 */
105int double2lldiv_t(double nr, lldiv_t *lld);
106int decimal_size(int precision, int scale);
107int decimal_bin_size(int precision, int scale);
108
109int decimal_intg(const decimal_t *from);
110int decimal_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to);
111int decimal_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to);
112int decimal_cmp(const decimal_t *from1, const decimal_t *from2);
113int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to);
114int decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to,
115 int scale_incr);
116int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to);
117int decimal_round(const decimal_t *from, decimal_t *to, int new_scale,
119int decimal_is_zero(const decimal_t *from);
120void max_decimal(int precision, int frac, decimal_t *to);
121int decimal_shift(decimal_t *dec, int shift);
122
123/* set a decimal_t to zero */
124static inline void decimal_make_zero(decimal_t *dec) {
125 dec->buf[0] = 0;
126 dec->intg = 1;
127 dec->frac = 0;
128 dec->sign = false;
129}
130
131/**
132 Returns the length of the buffer to hold string representation
133 of the decimal (including decimal dot, possible sign and \0)
134*/
135static inline int decimal_string_size(const decimal_t *dec) {
136 return (dec->intg ? dec->intg : 1) + dec->frac + (dec->frac > 0) + 2;
137}
138
139/*
140 conventions:
141
142 decimal_smth() == 0 -- everything's ok
143 decimal_smth() <= 1 -- result is usable, but precision loss is
144 possible decimal_smth() <= 2 -- result can be unusable, most significant
145 digits could've been lost decimal_smth() > 2 -- no result was generated
146*/
147
148#define E_DEC_OK 0
149#define E_DEC_TRUNCATED 1
150#define E_DEC_OVERFLOW 2
151#define E_DEC_DIV_ZERO 4
152#define E_DEC_BAD_NUM 8
153#define E_DEC_OOM 16
154
155#define E_DEC_FATAL_ERROR \
156 (E_DEC_OVERFLOW | E_DEC_DIV_ZERO | E_DEC_BAD_NUM | E_DEC_OOM)
157#define E_DEC_ERROR (E_DEC_FATAL_ERROR | E_DEC_TRUNCATED)
158
159#endif // MYSQL_ABI_CHECK
160
161#endif // DECIMAL_INCLUDED
int decimal_round(const decimal_t *from, decimal_t *to, int new_scale, decimal_round_mode mode)
Definition: decimal.cc:1653
int decimal_bin_size(int precision, int scale)
Definition: decimal.cc:1631
int decimal2longlong(const decimal_t *from, longlong *to)
Definition: decimal.cc:1175
int ulonglong2decimal(ulonglong from, decimal_t *to)
Definition: decimal.cc:1139
int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
Definition: decimal.cc:2083
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:135
int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale, bool keep_prec=false)
Definition: decimal.cc:1486
int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
Definition: decimal.cc:2510
int double2lldiv_t(double nr, lldiv_t *lld)
Convert double value to lldiv_t value.
Definition: decimal.cc:1244
decimal_round_mode
Definition: decimal.h:34
@ CEILING
Definition: decimal.h:38
@ FLOOR
Definition: decimal.h:39
@ HALF_UP
Definition: decimal.h:37
@ TRUNCATE
Definition: decimal.h:35
@ HALF_EVEN
Definition: decimal.h:36
int decimal_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
Definition: decimal.cc:2034
int decimal_is_zero(const decimal_t *from)
Definition: decimal.cc:2054
int longlong2decimal(longlong from, decimal_t *to)
Definition: decimal.cc:1144
int decimal_actual_fraction(const decimal_t *from)
Definition: decimal.cc:486
int decimal2lldiv_t(const decimal_t *from, lldiv_t *to)
Convert decimal to lldiv_t.
Definition: decimal.cc:1222
void max_decimal(int precision, int frac, decimal_t *to)
Definition: decimal.cc:432
int32 decimal_digit_t
Definition: decimal.h:41
int decimal2ulonglong(const decimal_t *from, ulonglong *to)
Definition: decimal.cc:1151
int decimal2bin(const decimal_t *from, uchar *to, int precision, int scale)
Definition: decimal.cc:1351
int decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to, int scale_incr)
Definition: decimal.cc:2478
int decimal_shift(decimal_t *dec, int shift)
Definition: decimal.cc:760
int decimal_size(int precision, int scale)
Definition: decimal.cc:1606
int string2decimal(const char *from, decimal_t *to, const char **end)
Definition: decimal.cc:932
static void decimal_make_zero(decimal_t *dec)
Definition: decimal.h:124
int decimal2double(const decimal_t *from, double *to)
Definition: decimal.cc:1075
int decimal2string(const decimal_t *from, char *to, int *to_len, int fixed_precision, int fixed_decimals)
Definition: decimal.cc:526
int decimal_cmp(const decimal_t *from1, const decimal_t *from2)
Definition: decimal.cc:2044
void widen_fraction(int new_frac, decimal_t *d)
Add zeros behind comma to increase precision of decimal.
Definition: decimal.cc:1048
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:2028
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:2039
static const std::string dec("DECRYPTION")
Some integer typedefs for easier portability.
unsigned long long int ulonglong
Definition: my_inttypes.h:56
unsigned char uchar
Definition: my_inttypes.h:52
long long int longlong
Definition: my_inttypes.h:55
int32_t int32
Definition: my_inttypes.h:66
Some common macros.
Cursor end()
A past-the-end Cursor.
Definition: rules_table_service.cc:192
mode
Definition: file_handle.h:61
Base struct used to represent decimal data type.
Definition: decimal.h:49
int frac
The number of decimal digits after the point.
Definition: decimal.h:54
decimal_digit_t * buf
An array of decimal_digit_t's.
Definition: decimal.h:61
int intg
The number of decimal digits (NOT number of decimal_digit_t's !) before the point.
Definition: decimal.h:52
bool sign
False means positive, true means negative.
Definition: decimal.h:59
int len
The length of buf (length of allocated space) in decimal_digit_t's, not in bytes.
Definition: decimal.h:57