Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
d5af61b1
Commit
d5af61b1
authored
Mar 21, 2005
by
konstantin@mysql.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rename decimal -> decimal_t, decimal_digit -> decimal_digit_t
parent
752a7873
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
107 additions
and
100 deletions
+107
-100
include/decimal.h
include/decimal.h
+30
-27
sql/log_event.cc
sql/log_event.cc
+3
-3
sql/my_decimal.cc
sql/my_decimal.cc
+2
-2
sql/my_decimal.h
sql/my_decimal.h
+23
-23
strings/decimal.c
strings/decimal.c
+49
-45
No files found.
include/decimal.h
View file @
d5af61b1
...
...
@@ -20,47 +20,50 @@
typedef
enum
{
TRUNCATE
=
0
,
HALF_EVEN
,
HALF_UP
,
CEILING
,
FLOOR
}
decimal_round_mode
;
typedef
int32
decimal_digit
;
typedef
int32
decimal_digit
_t
;
typedef
struct
st_decimal
{
typedef
struct
st_decimal
_t
{
int
intg
,
frac
,
len
;
my_bool
sign
;
decimal_digit
*
buf
;
}
decimal
;
decimal_digit
_t
*
buf
;
}
decimal
_t
;
int
internal_str2dec
(
const
char
*
from
,
decimal
*
to
,
char
**
end
,
my_bool
fixed
);
int
decimal2string
(
decimal
*
from
,
char
*
to
,
int
*
to_len
,
int
internal_str2dec
(
const
char
*
from
,
decimal_t
*
to
,
char
**
end
,
my_bool
fixed
);
int
decimal2string
(
decimal_t
*
from
,
char
*
to
,
int
*
to_len
,
int
fixed_precision
,
int
fixed_decimals
,
char
filler
);
int
decimal2ulonglong
(
decimal
*
from
,
ulonglong
*
to
);
int
ulonglong2decimal
(
ulonglong
from
,
decimal
*
to
);
int
decimal2longlong
(
decimal
*
from
,
longlong
*
to
);
int
longlong2decimal
(
longlong
from
,
decimal
*
to
);
int
decimal2double
(
decimal
*
from
,
double
*
to
);
int
double2decimal
(
double
from
,
decimal
*
to
);
void
decimal_optimize_fraction
(
decimal
*
from
);
int
decimal2bin
(
decimal
*
from
,
char
*
to
,
int
precision
,
int
scale
);
int
bin2decimal
(
char
*
from
,
decimal
*
to
,
int
precision
,
int
scale
);
int
decimal2ulonglong
(
decimal
_t
*
from
,
ulonglong
*
to
);
int
ulonglong2decimal
(
ulonglong
from
,
decimal
_t
*
to
);
int
decimal2longlong
(
decimal
_t
*
from
,
longlong
*
to
);
int
longlong2decimal
(
longlong
from
,
decimal
_t
*
to
);
int
decimal2double
(
decimal
_t
*
from
,
double
*
to
);
int
double2decimal
(
double
from
,
decimal
_t
*
to
);
void
decimal_optimize_fraction
(
decimal
_t
*
from
);
int
decimal2bin
(
decimal
_t
*
from
,
char
*
to
,
int
precision
,
int
scale
);
int
bin2decimal
(
char
*
from
,
decimal
_t
*
to
,
int
precision
,
int
scale
);
int
decimal_size
(
int
precision
,
int
scale
);
int
decimal_bin_size
(
int
precision
,
int
scale
);
int
decimal_result_size
(
decimal
*
from1
,
decimal
*
from2
,
char
op
,
int
param
);
int
decimal_add
(
decimal
*
from1
,
decimal
*
from2
,
decimal
*
to
);
int
decimal_sub
(
decimal
*
from1
,
decimal
*
from2
,
decimal
*
to
);
int
decimal_cmp
(
decimal
*
from1
,
decimal
*
from2
);
int
decimal_mul
(
decimal
*
from1
,
decimal
*
from2
,
decimal
*
to
);
int
decimal_div
(
decimal
*
from1
,
decimal
*
from2
,
decimal
*
to
,
int
scale_incr
);
int
decimal_mod
(
decimal
*
from1
,
decimal
*
from2
,
decimal
*
to
);
int
decimal_round
(
decimal
*
from
,
decimal
*
to
,
int
new_scale
,
int
decimal_result_size
(
decimal_t
*
from1
,
decimal_t
*
from2
,
char
op
,
int
param
);
int
decimal_add
(
decimal_t
*
from1
,
decimal_t
*
from2
,
decimal_t
*
to
);
int
decimal_sub
(
decimal_t
*
from1
,
decimal_t
*
from2
,
decimal_t
*
to
);
int
decimal_cmp
(
decimal_t
*
from1
,
decimal_t
*
from2
);
int
decimal_mul
(
decimal_t
*
from1
,
decimal_t
*
from2
,
decimal_t
*
to
);
int
decimal_div
(
decimal_t
*
from1
,
decimal_t
*
from2
,
decimal_t
*
to
,
int
scale_incr
);
int
decimal_mod
(
decimal_t
*
from1
,
decimal_t
*
from2
,
decimal_t
*
to
);
int
decimal_round
(
decimal_t
*
from
,
decimal_t
*
to
,
int
new_scale
,
decimal_round_mode
mode
);
int
decimal_is_zero
(
decimal
*
from
);
void
max_decimal
(
int
precision
,
int
frac
,
decimal
*
to
);
int
decimal_is_zero
(
decimal
_t
*
from
);
void
max_decimal
(
int
precision
,
int
frac
,
decimal
_t
*
to
);
#define string2decimal(A,B,C) internal_str2dec((A), (B), (C), 0)
#define string2decimal_fixed(A,B,C) internal_str2dec((A), (B), (C), 1)
/* set a decimal to zero */
/* set a decimal
_t
to zero */
#define decimal_make_zero(dec) do { \
(dec)->buf[0]=0; \
...
...
sql/log_event.cc
View file @
d5af61b1
...
...
@@ -3336,7 +3336,7 @@ bool User_var_log_event::write(IO_CACHE* file)
dec
->
fix_buffer_pointer
();
buf2
[
0
]
=
(
char
)(
dec
->
intg
+
dec
->
frac
);
buf2
[
1
]
=
(
char
)
dec
->
frac
;
decimal2bin
((
decimal
*
)
val
,
buf2
+
2
,
buf2
[
0
],
buf2
[
1
]);
decimal2bin
((
decimal
_t
*
)
val
,
buf2
+
2
,
buf2
[
0
],
buf2
[
1
]);
val_len
=
decimal_bin_size
(
buf2
[
0
],
buf2
[
1
])
+
2
;
break
;
}
...
...
@@ -3403,8 +3403,8 @@ void User_var_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* las
int
str_len
=
sizeof
(
str_buf
)
-
1
;
int
precision
=
(
int
)
val
[
0
];
int
scale
=
(
int
)
val
[
1
];
decimal_digit
dec_buf
[
10
];
decimal
dec
;
decimal_digit
_t
dec_buf
[
10
];
decimal
_t
dec
;
dec
.
len
=
10
;
dec
.
buf
=
dec_buf
;
...
...
sql/my_decimal.cc
View file @
d5af61b1
...
...
@@ -88,7 +88,7 @@ int my_decimal2string(uint mask, const my_decimal *d,
int
result
;
if
(
str
->
alloc
(
length
))
return
check_result
(
mask
,
E_DEC_OOM
);
result
=
decimal2string
((
decimal
*
)
d
,
(
char
*
)
str
->
ptr
(),
result
=
decimal2string
((
decimal
_t
*
)
d
,
(
char
*
)
str
->
ptr
(),
&
length
,
fixed_prec
,
fixed_dec
,
filler
);
str
->
length
(
length
);
...
...
@@ -172,7 +172,7 @@ int str2my_decimal(uint mask, const char *from, uint length,
charset
=
&
my_charset_bin
;
}
from_end
=
end
=
(
char
*
)
from
+
length
;
err
=
string2decimal
((
char
*
)
from
,
(
decimal
*
)
decimal_value
,
&
end
);
err
=
string2decimal
((
char
*
)
from
,
(
decimal
_t
*
)
decimal_value
,
&
end
);
if
(
end
!=
from_end
&&
!
err
)
{
/* Give warining if there is something other than end space */
...
...
sql/my_decimal.h
View file @
d5af61b1
...
...
@@ -69,15 +69,15 @@ inline uint my_decimal_size(uint precision, uint scale)
/*
my_decimal class limits 'decimal' type to what we need in MySQL
my_decimal class limits 'decimal
_t
' type to what we need in MySQL
It contains internally all necessary space needed by the instance so
no extra memory is needed. One should call fix_buffer_pointer() function
when he moves my_decimal objects in memory
*/
class
my_decimal
:
public
decimal
class
my_decimal
:
public
decimal
_t
{
decimal_digit
buffer
[
DECIMAL_BUFF_LENGTH
];
decimal_digit
_t
buffer
[
DECIMAL_BUFF_LENGTH
];
public:
...
...
@@ -97,8 +97,8 @@ public:
}
void
fix_buffer_pointer
()
{
buf
=
buffer
;
}
bool
sign
()
const
{
return
decimal
::
sign
;
}
void
sign
(
bool
s
)
{
decimal
::
sign
=
s
;
}
bool
sign
()
const
{
return
decimal
_t
::
sign
;
}
void
sign
(
bool
s
)
{
decimal
_t
::
sign
=
s
;
}
};
...
...
@@ -165,7 +165,7 @@ inline
int
binary2my_decimal
(
uint
mask
,
const
char
*
bin
,
my_decimal
*
d
,
int
prec
,
int
scale
)
{
return
check_result
(
mask
,
bin2decimal
((
char
*
)
bin
,
(
decimal
*
)
d
,
prec
,
return
check_result
(
mask
,
bin2decimal
((
char
*
)
bin
,
(
decimal
_t
*
)
d
,
prec
,
scale
));
}
...
...
@@ -173,7 +173,7 @@ int binary2my_decimal(uint mask, const char *bin, my_decimal *d, int prec,
inline
int
my_decimal_set_zero
(
my_decimal
*
d
)
{
decimal_make_zero
(((
decimal
*
)
d
));
decimal_make_zero
(((
decimal
_t
*
)
d
));
return
0
;
}
...
...
@@ -181,7 +181,7 @@ int my_decimal_set_zero(my_decimal *d)
inline
bool
my_decimal_is_zero
(
const
my_decimal
*
decimal_value
)
{
return
decimal_is_zero
((
decimal
*
)
decimal_value
);
return
decimal_is_zero
((
decimal
_t
*
)
decimal_value
);
}
...
...
@@ -189,7 +189,7 @@ inline
int
my_decimal_round
(
uint
mask
,
const
my_decimal
*
from
,
int
scale
,
bool
truncate
,
my_decimal
*
to
)
{
return
check_result
(
mask
,
decimal_round
((
decimal
*
)
from
,
to
,
scale
,
return
check_result
(
mask
,
decimal_round
((
decimal
_t
*
)
from
,
to
,
scale
,
(
truncate
?
TRUNCATE
:
HALF_UP
)));
}
...
...
@@ -197,14 +197,14 @@ int my_decimal_round(uint mask, const my_decimal *from, int scale,
inline
int
my_decimal_floor
(
uint
mask
,
const
my_decimal
*
from
,
my_decimal
*
to
)
{
return
check_result
(
mask
,
decimal_round
((
decimal
*
)
from
,
to
,
0
,
FLOOR
));
return
check_result
(
mask
,
decimal_round
((
decimal
_t
*
)
from
,
to
,
0
,
FLOOR
));
}
inline
int
my_decimal_ceiling
(
uint
mask
,
const
my_decimal
*
from
,
my_decimal
*
to
)
{
return
check_result
(
mask
,
decimal_round
((
decimal
*
)
from
,
to
,
0
,
CEILING
));
return
check_result
(
mask
,
decimal_round
((
decimal
_t
*
)
from
,
to
,
0
,
CEILING
));
}
...
...
@@ -219,7 +219,7 @@ int my_decimal2int(uint mask, const my_decimal *d, my_bool unsigned_flag,
{
my_decimal
rounded
;
/* decimal_round can return only E_DEC_TRUNCATED */
decimal_round
((
decimal
*
)
d
,
&
rounded
,
0
,
HALF_UP
);
decimal_round
((
decimal
_t
*
)
d
,
&
rounded
,
0
,
HALF_UP
);
return
check_result
(
mask
,
(
unsigned_flag
?
decimal2ulonglong
(
&
rounded
,
(
ulonglong
*
)
l
)
:
decimal2longlong
(
&
rounded
,
l
)));
...
...
@@ -230,14 +230,14 @@ inline
int
my_decimal2double
(
uint
mask
,
const
my_decimal
*
d
,
double
*
result
)
{
/* No need to call check_result as this will always succeed */
return
decimal2double
((
decimal
*
)
d
,
result
);
return
decimal2double
((
decimal
_t
*
)
d
,
result
);
}
inline
int
str2my_decimal
(
uint
mask
,
const
char
*
str
,
my_decimal
*
d
,
char
**
end
)
{
return
check_result
(
mask
,
string2decimal
(
str
,
(
decimal
*
)
d
,
end
));
return
check_result
(
mask
,
string2decimal
(
str
,
(
decimal
_t
*
)
d
,
end
));
}
...
...
@@ -255,7 +255,7 @@ int string2my_decimal(uint mask, const String *str, my_decimal *d)
inline
int
double2my_decimal
(
uint
mask
,
double
val
,
my_decimal
*
d
)
{
return
check_result
(
mask
,
double2decimal
(
val
,
(
decimal
*
)
d
));
return
check_result
(
mask
,
double2decimal
(
val
,
(
decimal
_t
*
)
d
));
}
...
...
@@ -269,7 +269,7 @@ int int2my_decimal(uint mask, longlong i, my_bool unsigned_flag, my_decimal *d)
inline
void
my_decimal_neg
(
st_decimal
*
arg
)
void
my_decimal_neg
(
decimal_t
*
arg
)
{
decimal_neg
(
arg
);
}
...
...
@@ -279,7 +279,7 @@ inline
int
my_decimal_add
(
uint
mask
,
my_decimal
*
res
,
const
my_decimal
*
a
,
const
my_decimal
*
b
)
{
return
check_result
(
mask
,
decimal_add
((
decimal
*
)
a
,
(
decimal
*
)
b
,
res
));
return
check_result
(
mask
,
decimal_add
((
decimal
_t
*
)
a
,
(
decimal_t
*
)
b
,
res
));
}
...
...
@@ -287,7 +287,7 @@ inline
int
my_decimal_sub
(
uint
mask
,
my_decimal
*
res
,
const
my_decimal
*
a
,
const
my_decimal
*
b
)
{
return
check_result
(
mask
,
decimal_sub
((
decimal
*
)
a
,
(
decimal
*
)
b
,
res
));
return
check_result
(
mask
,
decimal_sub
((
decimal
_t
*
)
a
,
(
decimal_t
*
)
b
,
res
));
}
...
...
@@ -295,7 +295,7 @@ inline
int
my_decimal_mul
(
uint
mask
,
my_decimal
*
res
,
const
my_decimal
*
a
,
const
my_decimal
*
b
)
{
return
check_result
(
mask
,
decimal_mul
((
decimal
*
)
a
,
(
decimal
*
)
b
,
res
));
return
check_result
(
mask
,
decimal_mul
((
decimal
_t
*
)
a
,
(
decimal_t
*
)
b
,
res
));
}
...
...
@@ -303,7 +303,7 @@ inline
int
my_decimal_div
(
uint
mask
,
my_decimal
*
res
,
const
my_decimal
*
a
,
const
my_decimal
*
b
,
int
div_scale_inc
)
{
return
check_result
(
mask
,
decimal_div
((
decimal
*
)
a
,
(
decimal
*
)
b
,
res
,
return
check_result
(
mask
,
decimal_div
((
decimal
_t
*
)
a
,
(
decimal_t
*
)
b
,
res
,
div_scale_inc
));
}
...
...
@@ -312,7 +312,7 @@ inline
int
my_decimal_mod
(
uint
mask
,
my_decimal
*
res
,
const
my_decimal
*
a
,
const
my_decimal
*
b
)
{
return
check_result
(
mask
,
decimal_mod
((
decimal
*
)
a
,
(
decimal
*
)
b
,
res
));
return
check_result
(
mask
,
decimal_mod
((
decimal
_t
*
)
a
,
(
decimal_t
*
)
b
,
res
));
}
...
...
@@ -320,14 +320,14 @@ int my_decimal_mod(uint mask, my_decimal *res, const my_decimal *a,
inline
int
my_decimal_cmp
(
const
my_decimal
*
a
,
const
my_decimal
*
b
)
{
return
decimal_cmp
((
decimal
*
)
a
,
(
decimal
*
)
b
);
return
decimal_cmp
((
decimal
_t
*
)
a
,
(
decimal_t
*
)
b
);
}
inline
void
max_my_decimal
(
my_decimal
*
to
,
int
precision
,
int
frac
)
{
DBUG_ASSERT
(
precision
<=
DECIMAL_MAX_LENGTH
);
max_decimal
(
precision
,
frac
,
(
decimal
*
)
to
);
max_decimal
(
precision
,
frac
,
(
decimal
_t
*
)
to
);
}
#endif
/*my_decimal_h*/
...
...
strings/decimal.c
View file @
d5af61b1
...
...
@@ -109,20 +109,20 @@
/*
Internally decimal numbers are stored base 10^9 (see DIG_BASE below)
So one
"decimal_digit" is
So one
variable of type decimal_digit_t is limited:
0 < decimal_digit <= DIG_MAX < DIG_BASE
in the struct st_decimal:
in the struct st_decimal
_t
:
intg is the number of *decimal* digits (NOT number of decimal_digit's !)
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's
len is the length of buf (length of allocated space) in decimal_digit's,
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
*/
typedef
decimal_digit
dec1
;
typedef
decimal_digit
_t
dec1
;
typedef
longlong
dec2
;
#define DIG_PER_DEC1 9
...
...
@@ -223,7 +223,7 @@ static const dec1 frac_max[DIG_PER_DEC1-1]={
to->buf and to->len must be set.
*/
void
max_decimal
(
int
precision
,
int
frac
,
decimal
*
to
)
void
max_decimal
(
int
precision
,
int
frac
,
decimal
_t
*
to
)
{
int
intpart
;
dec1
*
buf
=
to
->
buf
;
...
...
@@ -250,7 +250,7 @@ void max_decimal(int precision, int frac, decimal *to)
}
static
dec1
*
remove_leading_zeroes
(
decimal
*
from
,
int
*
intg_result
)
static
dec1
*
remove_leading_zeroes
(
decimal
_t
*
from
,
int
*
intg_result
)
{
int
intg
=
from
->
intg
,
i
;
dec1
*
buf0
=
from
->
buf
;
...
...
@@ -281,7 +281,7 @@ static dec1 *remove_leading_zeroes(decimal *from, int *intg_result)
from number for processing
*/
void
decimal_optimize_fraction
(
decimal
*
from
)
void
decimal_optimize_fraction
(
decimal
_t
*
from
)
{
int
frac
=
from
->
frac
,
i
;
dec1
*
buf0
=
from
->
buf
+
ROUND_UP
(
from
->
intg
)
+
ROUND_UP
(
frac
)
-
1
;
...
...
@@ -328,7 +328,7 @@ void decimal_optimize_fraction(decimal *from)
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
*/
int
decimal2string
(
decimal
*
from
,
char
*
to
,
int
*
to_len
,
int
decimal2string
(
decimal
_t
*
from
,
char
*
to
,
int
*
to_len
,
int
fixed_precision
,
int
fixed_decimals
,
char
filler
)
{
...
...
@@ -453,7 +453,7 @@ int decimal2string(decimal *from, char *to, int *to_len,
be written by this address
*/
static
void
digits_bounds
(
decimal
*
from
,
int
*
start_result
,
int
*
end_result
)
static
void
digits_bounds
(
decimal
_t
*
from
,
int
*
start_result
,
int
*
end_result
)
{
int
start
,
stop
,
i
;
dec1
*
buf_beg
=
from
->
buf
;
...
...
@@ -520,7 +520,7 @@ static void digits_bounds(decimal *from, int *start_result, int *end_result)
'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
*/
void
do_mini_left_shift
(
decimal
*
dec
,
int
shift
,
int
beg
,
int
last
)
void
do_mini_left_shift
(
decimal
_t
*
dec
,
int
shift
,
int
beg
,
int
last
)
{
dec1
*
from
=
dec
->
buf
+
ROUND_UP
(
beg
+
1
)
-
1
;
dec1
*
end
=
dec
->
buf
+
ROUND_UP
(
last
)
-
1
;
...
...
@@ -550,7 +550,7 @@ void do_mini_left_shift(decimal *dec, int shift, int beg, int last)
'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
*/
void
do_mini_right_shift
(
decimal
*
dec
,
int
shift
,
int
beg
,
int
last
)
void
do_mini_right_shift
(
decimal
_t
*
dec
,
int
shift
,
int
beg
,
int
last
)
{
dec1
*
from
=
dec
->
buf
+
ROUND_UP
(
last
)
-
1
;
dec1
*
end
=
dec
->
buf
+
ROUND_UP
(
beg
+
1
)
-
1
;
...
...
@@ -583,7 +583,7 @@ void do_mini_right_shift(decimal *dec, int shift, int beg, int last)
E_DEC_TRUNCATED number was rounded to fit into buffer
*/
int
decimal_shift
(
decimal
*
dec
,
int
shift
)
int
decimal_shift
(
decimal
_t
*
dec
,
int
shift
)
{
/* index of first non zero digit (all indexes from 0) */
int
beg
;
...
...
@@ -780,7 +780,8 @@ int decimal_shift(decimal *dec, int shift)
(to make error handling easier)
*/
int
internal_str2dec
(
const
char
*
from
,
decimal
*
to
,
char
**
end
,
my_bool
fixed
)
int
internal_str2dec
(
const
char
*
from
,
decimal_t
*
to
,
char
**
end
,
my_bool
fixed
)
{
const
char
*
s
=
from
,
*
s1
,
*
endp
,
*
end_of_string
=
*
end
;
int
i
,
intg
,
frac
,
error
,
intg1
,
frac1
;
...
...
@@ -937,7 +938,7 @@ fatal_error:
E_DEC_OK
*/
int
decimal2double
(
decimal
*
from
,
double
*
to
)
int
decimal2double
(
decimal
_t
*
from
,
double
*
to
)
{
double
x
=
0
,
t
=
DIG_BASE
;
int
intg
,
frac
;
...
...
@@ -963,7 +964,7 @@ int decimal2double(decimal *from, double *to)
E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
*/
int
double2decimal
(
double
from
,
decimal
*
to
)
int
double2decimal
(
double
from
,
decimal
_t
*
to
)
{
/* TODO: fix it, when we'll have dtoa */
char
s
[
400
],
*
end
;
...
...
@@ -972,7 +973,7 @@ int double2decimal(double from, decimal *to)
return
string2decimal
(
s
,
to
,
&
end
);
}
static
int
ull2dec
(
ulonglong
from
,
decimal
*
to
)
static
int
ull2dec
(
ulonglong
from
,
decimal
_t
*
to
)
{
int
intg1
,
error
=
E_DEC_OK
;
ulonglong
x
=
from
;
...
...
@@ -998,20 +999,20 @@ static int ull2dec(ulonglong from, decimal *to)
return
error
;
}
int
ulonglong2decimal
(
ulonglong
from
,
decimal
*
to
)
int
ulonglong2decimal
(
ulonglong
from
,
decimal
_t
*
to
)
{
to
->
sign
=
0
;
return
ull2dec
(
from
,
to
);
}
int
longlong2decimal
(
longlong
from
,
decimal
*
to
)
int
longlong2decimal
(
longlong
from
,
decimal
_t
*
to
)
{
if
((
to
->
sign
=
from
<
0
))
return
ull2dec
(
-
from
,
to
);
return
ull2dec
(
from
,
to
);
}
int
decimal2ulonglong
(
decimal
*
from
,
ulonglong
*
to
)
int
decimal2ulonglong
(
decimal
_t
*
from
,
ulonglong
*
to
)
{
dec1
*
buf
=
from
->
buf
;
ulonglong
x
=
0
;
...
...
@@ -1040,7 +1041,7 @@ int decimal2ulonglong(decimal *from, ulonglong *to)
return
E_DEC_OK
;
}
int
decimal2longlong
(
decimal
*
from
,
longlong
*
to
)
int
decimal2longlong
(
decimal
_t
*
from
,
longlong
*
to
)
{
dec1
*
buf
=
from
->
buf
;
longlong
x
=
0
;
...
...
@@ -1112,7 +1113,7 @@ int decimal2longlong(decimal *from, longlong *to)
3. The first intg % DIG_PER_DEC1 digits are stored in the reduced
number of bytes (enough bytes to store this number of digits -
see dig2bytes)
4. same for frac - full decimal_digit's are stored as is,
4. same for frac - full decimal_digit
_t
's are stored as is,
the last frac % DIG_PER_DEC1 digits - in the reduced number of bytes.
5. If the number is negative - every byte is inversed.
5. The very first bit of the resulting byte array is inverted (because
...
...
@@ -1122,7 +1123,7 @@ int decimal2longlong(decimal *from, longlong *to)
1234567890.1234
internally is represented as 3 decimal_digit's
internally is represented as 3 decimal_digit
_t
's
1 234567890 123400000
...
...
@@ -1131,13 +1132,13 @@ int decimal2longlong(decimal *from, longlong *to)
00-00-00-01 0D-FB-38-D2 07-5A-EF-40
now, middle decimal_digit is full - it stores 9 decimal digits. It goes
now, middle decimal_digit
_t
is full - it stores 9 decimal digits. It goes
into binary representation as is:
........... 0D-FB-38-D2 ............
First decimal_digit has only one decimal digit. We can store one digit in
First decimal_digit
_t
has only one decimal digit. We can store one digit in
one byte, no need to waste four:
01 0D-FB-38-D2 ............
...
...
@@ -1155,7 +1156,7 @@ int decimal2longlong(decimal *from, longlong *to)
7E F2 04 37 2D FB 2D
*/
int
decimal2bin
(
decimal
*
from
,
char
*
to
,
int
precision
,
int
frac
)
int
decimal2bin
(
decimal
_t
*
from
,
char
*
to
,
int
precision
,
int
frac
)
{
dec1
mask
=
from
->
sign
?
-
1
:
0
,
*
buf1
=
from
->
buf
,
*
stop1
;
int
error
=
E_DEC_OK
,
intg
=
precision
-
frac
,
...
...
@@ -1283,7 +1284,7 @@ int decimal2bin(decimal *from, char *to, int precision, int frac)
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
*/
int
bin2decimal
(
char
*
from
,
decimal
*
to
,
int
precision
,
int
scale
)
int
bin2decimal
(
char
*
from
,
decimal
_t
*
to
,
int
precision
,
int
scale
)
{
int
error
=
E_DEC_OK
,
intg
=
precision
-
scale
,
intg0
=
intg
/
DIG_PER_DEC1
,
frac0
=
scale
/
DIG_PER_DEC1
,
...
...
@@ -1424,7 +1425,9 @@ int decimal_bin_size(int precision, int scale)
E_DEC_OK/E_DEC_TRUNCATED
*/
int
decimal_round
(
decimal
*
from
,
decimal
*
to
,
int
scale
,
decimal_round_mode
mode
)
int
decimal_round
(
decimal_t
*
from
,
decimal_t
*
to
,
int
scale
,
decimal_round_mode
mode
)
{
int
frac0
=
scale
>
0
?
ROUND_UP
(
scale
)
:
scale
/
DIG_PER_DEC1
,
frac1
=
ROUND_UP
(
from
->
frac
),
round_digit
,
...
...
@@ -1585,7 +1588,7 @@ done:
multiply by sizeof(dec1)
*/
int
decimal_result_size
(
decimal
*
from1
,
decimal
*
from2
,
char
op
,
int
param
)
int
decimal_result_size
(
decimal
_t
*
from1
,
decimal_t
*
from2
,
char
op
,
int
param
)
{
switch
(
op
)
{
case
'-'
:
...
...
@@ -1604,7 +1607,7 @@ int decimal_result_size(decimal *from1, decimal *from2, char op, int param)
return
-
1
;
/* shut up the warning */
}
static
int
do_add
(
decimal
*
from1
,
decimal
*
from2
,
decimal
*
to
)
static
int
do_add
(
decimal
_t
*
from1
,
decimal_t
*
from2
,
decimal_t
*
to
)
{
int
intg1
=
ROUND_UP
(
from1
->
intg
),
intg2
=
ROUND_UP
(
from2
->
intg
),
frac1
=
ROUND_UP
(
from1
->
frac
),
frac2
=
ROUND_UP
(
from2
->
frac
),
...
...
@@ -1680,7 +1683,7 @@ static int do_add(decimal *from1, decimal *from2, decimal *to)
/* to=from1-from2.
if to==0, return -1/0/+1 - the result of the comparison */
static
int
do_sub
(
decimal
*
from1
,
decimal
*
from2
,
decimal
*
to
)
static
int
do_sub
(
decimal
_t
*
from1
,
decimal_t
*
from2
,
decimal_t
*
to
)
{
int
intg1
=
ROUND_UP
(
from1
->
intg
),
intg2
=
ROUND_UP
(
from2
->
intg
),
frac1
=
ROUND_UP
(
from1
->
frac
),
frac2
=
ROUND_UP
(
from2
->
frac
);
...
...
@@ -1741,7 +1744,7 @@ static int do_sub(decimal *from1, decimal *from2, decimal *to)
/* ensure that always from1 > from2 (and intg1 >= intg2) */
if
(
carry
)
{
swap_variables
(
decimal
*
,
from1
,
from1
);
swap_variables
(
decimal
_t
*
,
from1
,
from1
);
swap_variables
(
dec1
*
,
start1
,
start2
);
swap_variables
(
int
,
intg1
,
intg2
);
swap_variables
(
int
,
frac1
,
frac2
);
...
...
@@ -1807,28 +1810,28 @@ static int do_sub(decimal *from1, decimal *from2, decimal *to)
return
error
;
}
int
decimal_add
(
decimal
*
from1
,
decimal
*
from2
,
decimal
*
to
)
int
decimal_add
(
decimal
_t
*
from1
,
decimal_t
*
from2
,
decimal_t
*
to
)
{
if
(
likely
(
from1
->
sign
==
from2
->
sign
))
return
do_add
(
from1
,
from2
,
to
);
return
do_sub
(
from1
,
from2
,
to
);
}
int
decimal_sub
(
decimal
*
from1
,
decimal
*
from2
,
decimal
*
to
)
int
decimal_sub
(
decimal
_t
*
from1
,
decimal_t
*
from2
,
decimal_t
*
to
)
{
if
(
likely
(
from1
->
sign
==
from2
->
sign
))
return
do_sub
(
from1
,
from2
,
to
);
return
do_add
(
from1
,
from2
,
to
);
}
int
decimal_cmp
(
decimal
*
from1
,
decimal
*
from2
)
int
decimal_cmp
(
decimal
_t
*
from1
,
decimal_t
*
from2
)
{
if
(
likely
(
from1
->
sign
==
from2
->
sign
))
return
do_sub
(
from1
,
from2
,
0
);
return
from1
->
sign
>
from2
->
sign
?
-
1
:
1
;
}
int
decimal_is_zero
(
decimal
*
from
)
int
decimal_is_zero
(
decimal
_t
*
from
)
{
dec1
*
buf1
=
from
->
buf
,
*
end
=
buf1
+
ROUND_UP
(
from
->
intg
)
+
ROUND_UP
(
from
->
frac
);
...
...
@@ -1859,7 +1862,7 @@ int decimal_is_zero(decimal *from)
XXX if this library is to be used with huge numbers of thousands of
digits, fast multiplication must be implemented.
*/
int
decimal_mul
(
decimal
*
from1
,
decimal
*
from2
,
decimal
*
to
)
int
decimal_mul
(
decimal
_t
*
from1
,
decimal_t
*
from2
,
decimal_t
*
to
)
{
int
intg1
=
ROUND_UP
(
from1
->
intg
),
intg2
=
ROUND_UP
(
from2
->
intg
),
frac1
=
ROUND_UP
(
from1
->
frac
),
frac2
=
ROUND_UP
(
from2
->
frac
),
...
...
@@ -1932,8 +1935,8 @@ int decimal_mul(decimal *from1, decimal *from2, decimal *to)
changed to malloc (or at least fallback to malloc if alloca() fails)
but then, decimal_mod() should be rewritten too :(
*/
static
int
do_div_mod
(
decimal
*
from1
,
decimal
*
from2
,
decimal
*
to
,
decimal
*
mod
,
int
scale_incr
)
static
int
do_div_mod
(
decimal
_t
*
from1
,
decimal_t
*
from2
,
decimal
_t
*
to
,
decimal_t
*
mod
,
int
scale_incr
)
{
int
frac1
=
ROUND_UP
(
from1
->
frac
)
*
DIG_PER_DEC1
,
prec1
=
from1
->
intg
+
frac1
,
frac2
=
ROUND_UP
(
from2
->
frac
)
*
DIG_PER_DEC1
,
prec2
=
from2
->
intg
+
frac2
,
...
...
@@ -2208,7 +2211,8 @@ done:
see do_div_mod()
*/
int
decimal_div
(
decimal
*
from1
,
decimal
*
from2
,
decimal
*
to
,
int
scale_incr
)
int
decimal_div
(
decimal_t
*
from1
,
decimal_t
*
from2
,
decimal_t
*
to
,
int
scale_incr
)
{
return
do_div_mod
(
from1
,
from2
,
to
,
0
,
scale_incr
);
}
...
...
@@ -2240,7 +2244,7 @@ int decimal_div(decimal *from1, decimal *from2, decimal *to, int scale_incr)
thus, there's no requirement for M or N to be integers
*/
int
decimal_mod
(
decimal
*
from1
,
decimal
*
from2
,
decimal
*
to
)
int
decimal_mod
(
decimal
_t
*
from1
,
decimal_t
*
from2
,
decimal_t
*
to
)
{
return
do_div_mod
(
from1
,
from2
,
0
,
to
,
0
);
}
...
...
@@ -2248,10 +2252,10 @@ int decimal_mod(decimal *from1, decimal *from2, decimal *to)
#ifdef MAIN
int
full
=
0
;
decimal
a
,
b
,
c
;
decimal
_t
a
,
b
,
c
;
char
buf1
[
100
],
buf2
[
100
],
buf3
[
100
];
void
dump_decimal
(
decimal
*
d
)
void
dump_decimal
(
decimal
_t
*
d
)
{
int
i
;
printf
(
"/* intg=%d, frac=%d, sign=%d, buf[]={"
,
d
->
intg
,
d
->
frac
,
d
->
sign
);
...
...
@@ -2271,7 +2275,7 @@ void check_result_code(int actual, int want)
}
void
print_decimal
(
decimal
*
d
,
const
char
*
orig
,
int
actual
,
int
want
)
void
print_decimal
(
decimal
_t
*
d
,
const
char
*
orig
,
int
actual
,
int
want
)
{
char
s
[
100
];
int
slen
=
sizeof
(
s
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment