Skip to content

Commit 287f6ad

Browse files
committed
fix
1 parent a64a202 commit 287f6ad

File tree

1 file changed

+24
-15
lines changed

1 file changed

+24
-15
lines changed

velox/type/DecimalUtilOp.h

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,8 @@ class DecimalUtilOp {
197197
number += '0';
198198
}
199199
} else {
200-
number += digits.substr(0, exponent) + '.' + digits.substr(exponent + 1, digits.length());
200+
number += digits.substr(0, exponent) + '.' +
201+
digits.substr(exponent + 1, digits.length());
201202
}
202203
return number;
203204
}
@@ -221,30 +222,38 @@ class DecimalUtilOp {
221222
return value;
222223
}
223224

224-
inline static double roundUp(double value, int decimalPlaces) {
225-
const double multiplier = std::pow(10.0, decimalPlaces);
226-
return std::ceil(value * multiplier) / multiplier;
225+
// Round double to certain precision with half up.
226+
inline static double roundTo(double value, int precision) {
227+
int charsNeeded = 1 + snprintf(NULL, 0, "%.*f", (int)precision, value);
228+
char* buffer = reinterpret_cast<char*>(malloc(charsNeeded));
229+
double nextValue;
230+
if (value < 0) {
231+
nextValue = nextafter(value, value - 0.1);
232+
} else {
233+
nextValue = nextafter(value, value + 0.1);
234+
}
235+
snprintf(buffer, charsNeeded, "%.*f", (int)precision, nextValue);
236+
return atof(buffer);
227237
}
228238

229239
// return unscaled value and scale
230240
inline static std::pair<std::string, uint8_t> splitVarChar(
231-
const StringView& value, int toScale) {
241+
const StringView& value,
242+
int toScale) {
232243
std::string s = getNormalNumber(value.str());
233244
size_t pos = s.find('.');
234245
if (pos == std::string::npos) {
235246
return {s.substr(0, pos), 0};
236-
} else if (toScale < scales.length()) {
237-
// If toScale is less than scales.length(), the string scales will be cut and rounded.
238-
std::string roundedValue = std::to_string(roundUp(std::stod(s), toScale));
239-
std::string scales = roundedValue.substr(pos + 1, roundedValue.length());
240-
return {
241-
roundedValue.substr(0, pos) + scales,
242-
scales.length()};
247+
} else if (toScale < s.length() - pos - 1) {
248+
// If toScale is less than scales.length(), the string scales will be cut
249+
// and rounded.
250+
std::string roundedValue = std::to_string(roundTo(std::stod(s), toScale));
251+
pos = roundedValue.find('.');
252+
std::string scales = roundedValue.substr(pos + 1, toScale);
253+
return {roundedValue.substr(0, pos) + scales, scales.length()};
243254
} else {
244255
std::string scales = s.substr(pos + 1, s.length());
245-
return {
246-
s.substr(0, pos) + scales,
247-
scales.length()};
256+
return {s.substr(0, pos) + scales, scales.length()};
248257
}
249258
}
250259

0 commit comments

Comments
 (0)