ICU-20901 VersionInfo.compareTo() compare signed version int as unsigned

This commit is contained in:
Markus Scherer 2020-10-02 11:08:39 -07:00
parent c0d4065607
commit b74b0c957e
2 changed files with 21 additions and 1 deletions

View file

@ -471,7 +471,15 @@ public final class VersionInfo implements Comparable<VersionInfo>
@Override
public int compareTo(VersionInfo other)
{
return m_version_ - other.m_version_;
// m_version_ is an int, a signed 32-bit integer.
// When the major version is >=128, then the version int is negative.
// Compare it in two steps to simulate an unsigned-int comparison.
// (Alternatively we could turn each int into a long and reset the upper 32 bits.)
// Compare the upper bits first, using logical shift right (unsigned).
int diff = (m_version_ >>> 1) - (other.m_version_ >>> 1);
if (diff != 0) { return diff; }
// Compare the remaining bits.
return (m_version_ & 1) - (other.m_version_ & 1);
}
// private data members ----------------------------------------------

View file

@ -138,6 +138,18 @@ public final class VersionInfoTest extends TestFmwk
}
}
@Test
public void TestCompareLarge() {
// One version with major<128, one >=128.
VersionInfo small = VersionInfo.getInstance(13);
VersionInfo large = VersionInfo.getInstance(222); // >=128
assertTrue(small + " < " + large, small.compareTo(large) < 0);
// Difference only in the last bit.
small = VersionInfo.getInstance(222, 0, 1, 2);
large = VersionInfo.getInstance(222, 0, 1, 3);
assertTrue(small + " < " + large, small.compareTo(large) < 0);
}
/**
* Test that the getter function works
*/