38
38
bool bc_str2num (bc_num * num , char * str , size_t scale )
39
39
{
40
40
size_t digits = 0 ;
41
- size_t strscale = 0 ;
41
+ size_t str_scale = 0 ;
42
42
char * ptr , * nptr , * integer_ptr , * integer_end , * fractional_ptr = NULL , * fractional_end = NULL , * decimal_point ;
43
43
bool zero_int = false;
44
- size_t len = strlen (str );
45
- sign num_sign = PLUS ;
46
44
47
45
/* Prepare num. */
48
46
bc_free_num (num );
49
47
50
48
/* Check for valid number and count digits. */
51
49
ptr = str ;
52
50
53
- if (* ptr == '+' ) {
54
- /* Skip Sign */
55
- ptr ++ ;
56
- } else if (* ptr == '-' ) {
57
- /* Skip Sign */
58
- num_sign = MINUS ;
59
- ptr ++ ;
60
- }
51
+ ptr += (* ptr == '-' || * ptr == '+' );
61
52
62
53
/* Skip leading zeros. */
63
54
while (* ptr == '0' ) {
@@ -82,45 +73,43 @@ bool bc_str2num(bc_num *num, char *str, size_t scale)
82
73
if (decimal_point ) {
83
74
/* search */
84
75
fractional_ptr = decimal_point + 1 ;
85
- fractional_end = str + len - 1 ;
86
- bool has_trailing_zero = false;
87
- while (* fractional_end == '0' && fractional_end >= fractional_ptr ) {
76
+ fractional_end = fractional_ptr + strlen (fractional_ptr ) - 1 ;
77
+ while (* fractional_end == '0' && fractional_end >= decimal_point ) {
88
78
fractional_end -- ;
89
- has_trailing_zero = true;
90
- }
91
- if (has_trailing_zero ) {
92
- fractional_end ++ ;
93
79
}
80
+ fractional_end ++ ;
81
+ str_scale = fractional_end - fractional_ptr ;
94
82
95
83
/* validate */
96
- strscale = fractional_end - fractional_ptr ;
97
- if (strspn (fractional_ptr , "0123456789" ) < strscale ) {
84
+ if (strspn (fractional_ptr , "0123456789" ) < str_scale ) {
98
85
/* invalid num */
99
- * num = bc_copy_num (BCG (_zero_ ));
100
- return false;
86
+ goto fail ;
87
+ }
88
+
89
+ while (str_scale > scale ) {
90
+ fractional_end -- ;
91
+ str_scale -- ;
101
92
}
102
93
}
103
94
104
- if (digits + strscale == 0 ) {
105
- * num = bc_copy_num (BCG (_zero_ ));
106
- return true;
95
+ if (digits + str_scale == 0 ) {
96
+ goto zero ;
107
97
}
108
98
109
99
/* Adjust numbers and allocate storage and initialize fields. */
110
- strscale = MIN (strscale , scale );
111
100
if (digits == 0 ) {
112
101
zero_int = true;
113
102
digits = 1 ;
114
103
}
115
104
116
- * num = bc_new_num (digits , strscale );
117
- (* num )-> n_sign = num_sign ;
105
+ * num = bc_new_num (digits , str_scale );
106
+ (* num )-> n_sign = * str == '-' ? MINUS : PLUS ;
118
107
nptr = (* num )-> n_value ;
119
108
120
109
if (zero_int ) {
121
110
nptr ++ ;
122
- if (decimal_point ) {
123
- while (fractional_ptr <= fractional_end ) {
111
+ if (str_scale > 0 ) {
112
+ while (fractional_ptr < fractional_end ) {
124
113
* nptr = CH_VAL (* fractional_ptr );
125
114
nptr ++ ;
126
115
fractional_ptr ++ ;
@@ -133,8 +122,8 @@ bool bc_str2num(bc_num *num, char *str, size_t scale)
133
122
nptr ++ ;
134
123
integer_ptr ++ ;
135
124
}
136
- if (decimal_point ) {
137
- while (fractional_ptr <= fractional_end ) {
125
+ if (str_scale > 0 ) {
126
+ while (fractional_ptr < fractional_end ) {
138
127
* nptr = CH_VAL (* fractional_ptr );
139
128
nptr ++ ;
140
129
fractional_ptr ++ ;
@@ -144,6 +133,10 @@ bool bc_str2num(bc_num *num, char *str, size_t scale)
144
133
145
134
return true;
146
135
136
+ zero :
137
+ * num = bc_copy_num (BCG (_zero_ ));
138
+ return true;
139
+
147
140
fail :
148
141
* num = bc_copy_num (BCG (_zero_ ));
149
142
return false;
0 commit comments