Gangmax Blog

Protobuf uint64 & Java Long

The post records the issue I met when using protobuf uint64 and Java Long.

When we define some protobuf message with ab “uint64”(unsigned int64) type field in it, and decode the corresponding binary payload to a Java object, the uint64 field in protobuf format will be mapped to a Long type Java field.

An potential issue may happen in such case: if the uint64 number is bigger than “Long.MAX_VALUE“, it will be converted to a negative Java Long value. For example:

1
2
3
# Note: 9223372036854775807 is Long.MAX_VALUE:
uint64 14001908927091871061 is mapped to Java long -4444835146617680555
uint64 11141610350324941563 is mapped to Java long -7305133723384610053

This caused confusions and issues. To fix it, use the code below to convert:

1
2
3
4
5
6
7
8
9
10
11
String id = "14001908927091871061";
Long long1 = Long.parseUnsignedLong(id);
System.out.println("id: " + id);

id = "-4444835146617680555";
Long longId = Long.parseLong(id);
System.out.println("longId: " + Long.toUnsignedString(longId));

// The code above prints the following lines:
id: 14001908927091871061
longId: 14001908927091871061

Comments