Fix natural sort comparison for strings with large numbers
Fix errors when comparing strings with large numbers (> INT64_MAX). Comparisons now occur by comparing individual digits, instead of converting to int64_t first.
This commit is contained in:
parent
73fddc623b
commit
de46c92711
1 changed files with 29 additions and 12 deletions
|
@ -527,29 +527,46 @@ signed char String::naturalnocasecmp_to(const String &p_str) const {
|
||||||
if (!*that_str) {
|
if (!*that_str) {
|
||||||
return 1;
|
return 1;
|
||||||
} else if (IS_DIGIT(*this_str)) {
|
} else if (IS_DIGIT(*this_str)) {
|
||||||
int64_t this_int, that_int;
|
|
||||||
|
|
||||||
if (!IS_DIGIT(*that_str)) {
|
if (!IS_DIGIT(*that_str)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compare the numbers */
|
// Keep ptrs to start of numerical sequences
|
||||||
this_int = to_int(this_str, -1, true);
|
const CharType *this_substr = this_str;
|
||||||
that_int = to_int(that_str, -1, true);
|
const CharType *that_substr = that_str;
|
||||||
|
|
||||||
if (this_int < that_int) {
|
// Compare lengths of both numerical sequences, ignoring leading zeros
|
||||||
return -1;
|
|
||||||
} else if (this_int > that_int) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skip */
|
|
||||||
while (IS_DIGIT(*this_str)) {
|
while (IS_DIGIT(*this_str)) {
|
||||||
this_str++;
|
this_str++;
|
||||||
}
|
}
|
||||||
while (IS_DIGIT(*that_str)) {
|
while (IS_DIGIT(*that_str)) {
|
||||||
that_str++;
|
that_str++;
|
||||||
}
|
}
|
||||||
|
while (*this_substr == '0') {
|
||||||
|
this_substr++;
|
||||||
|
}
|
||||||
|
while (*that_substr == '0') {
|
||||||
|
that_substr++;
|
||||||
|
}
|
||||||
|
int this_len = this_str - this_substr;
|
||||||
|
int that_len = that_str - that_substr;
|
||||||
|
|
||||||
|
if (this_len < that_len) {
|
||||||
|
return -1;
|
||||||
|
} else if (this_len > that_len) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If lengths equal, compare lexicographically
|
||||||
|
while (this_substr != this_str && that_substr != that_str) {
|
||||||
|
if (*this_substr < *that_substr) {
|
||||||
|
return -1;
|
||||||
|
} else if (*this_substr > *that_substr) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
this_substr++;
|
||||||
|
that_substr++;
|
||||||
|
}
|
||||||
} else if (IS_DIGIT(*that_str)) {
|
} else if (IS_DIGIT(*that_str)) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue