How to represent a Decimal for GoProtobuf ??

2,069 views
Skip to first unread message

Th3x0d3r

unread,
Oct 27, 2014, 12:41:25 PM10/27/14
to golan...@googlegroups.com
Hello there !

I'm trying to communicate my go app using goprotobuf with an existing c# service that uses protobuf-net as serialization, but since there's no decimal definition on protocol buffers, protobuf-net uses this representation structure:


message
Decimal {
  optional uint64 lo
= 1; // the first 64 bits of the underlying value
  optional uint32 hi
= 2; // the last 32 bis of the underlying value
  optional uint32 signScale
= 3; // the number of decimal digits (bits 1-16), and the sign (bit 0)
}

Go code:

val := math.Float64bits(3.74)
pd
.Lo = proto.Uint64(0x400deb851eb851ec) // Using 3.74 Float64bits hexa representation
pd
.Hi = proto.Uint32(0x00000000)
pd
.SignScale = proto.Uint32(0x000000020)


But, the C# server side doesn't get the 3.74  :(

Any help ?

Thanks !

Michael Jones

unread,
Oct 27, 2014, 1:46:39 PM10/27/14
to Th3x0d3r, golang-nuts

On Mon, Oct 27, 2014 at 9:41 AM, Th3x0d3r <xss...@gmail.com> wrote:
0x400deb851eb851ec

What do you get?

The significand (fraction) is 1.87 and the effective exponent is 2 so that could help decode your "C# gets the wrong thing" value if we new what that value is...



--
Michael T. Jones | Chief Technology Advocate  | m...@google.com |  +1 650-335-5765

Th3x0d3r

unread,
Oct 27, 2014, 2:32:41 PM10/27/14
to golan...@googlegroups.com
The thing is that I'm clueless on how to generate the Lo, Hi and Sign Scale for the Decimal Structure. Any example would be great

Daniel Eloff

unread,
Oct 27, 2014, 2:51:18 PM10/27/14
to golan...@googlegroups.com
You're trying to stuff a binary floating point number into a decimal floating point type. That's all wrong.

Decimal in .NET is a decimal floating point number (base 10, not base 2 like binary floats.) It is of the form sign * mantissa / 10^exponent where mantissa is a 96 bit integer, and exponent is 0-28 (effectively all negative, so the smallest number is 10^-28.)

So to represent 3.74, you would store 374 in the mantissa, and use 2 for the exponent. If you need more than 19 digits, you can use math.big.Int for the mantissa, otherwise uint64 will suffice.

Cheers,
Dan

Michael Jones

unread,
Oct 27, 2014, 2:54:21 PM10/27/14
to Daniel Eloff, golang-nuts

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Th3x0d3r

unread,
Oct 27, 2014, 3:06:09 PM10/27/14
to golan...@googlegroups.com
Thanks ! , can you show some example ??

Michael Jones

unread,
Oct 27, 2014, 3:13:57 PM10/27/14
to Th3x0d3r, golang-nuts
This is an unknown encoding to me beyond your emails. Perhaps there are tests and examples at the website I linked to. You might study those.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Th3x0d3r

unread,
Oct 27, 2014, 3:52:57 PM10/27/14
to golan...@googlegroups.com
Thanks ! but math it's not my field, and frankly I'm quite lost, can you show me some how to do that ?

Michael Jones

unread,
Oct 27, 2014, 3:59:06 PM10/27/14
to Th3x0d3r, golang-nuts
Daniel explained it. Try this:

pd.Lo = 374
pd.Hi = 0
pd.SignScale = 4

that (should/may/might) mean (0*(2**64)+374)/(10**2) == 374/100 == 3.74

If that works for you, come back for more. ;-)

On Mon, Oct 27, 2014 at 12:52 PM, Th3x0d3r <xss...@gmail.com> wrote:
Thanks ! but math it's not my field, and frankly I'm quite lost, can you show me some how to do that ?

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages