PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Thursday, August 11, 2022

[FIXED] What are the high and low values in mongodb mongo-go-driver Decimal128 and how to use them to create a new decimal

 August 11, 2022     decimal, go, mongo-go, mongodb     No comments   

Issue

The GO driver for MongoDB has a Decimal128 type which is a struct that looks like this:

type Decimal128 struct {
    h, l uint64
}

according to the docs, the h and l are high and low uint64 values. What do these two values represent? Let's say I wanted to create a Decimal128 that when converted to a string will equal "100.50". Using the function below, what would be the value of h and l.

func NewDecimal128(h, l uint64) Decimal128 {
    return Decimal128{h: h, l: l}
} 

I'm always forced to parse a string like this d, _ := primitive.ParseDecimal128("100.50") instead of

d := primitive.NewDecimal128(h, l) 

to create a new Decimal128 just because i don't understand how the high and the low values are used to derive the decimal value.


Solution

Decimal128.h and Decimal128.l both are of type uint64, both have 64 bits which add up to 128 bits.

| Decimal128.h bits   || Decimal128.l bits   |
63...            ....0  63...           ....0

Mongo-go's implementation of Decimal128 is similar / close to the IEEE 754 quadruple-precision floating-point format with some minor differences. Highest bit of h is the sign bit, then there are 2 bits ignored, then comes 14 bits exponent, and 111 bits significand. The subsequent 5 bits next to the sign bits are special, if their value is 0x1f, that means the Decimal128 value represents NaN (not a number), if their value is 0x1e, then the value represents positive or negative infinity (depending on the sign bit).

Check out the implementation of the Decimal128.BigInt() method for details.

As you can see, the "individual" low and high values have no direct correlation to the represented floating point number, but instead their 128 bits are handled as described above.

E.g. low and high values for "100.50" will be:

d, err := primitive.ParseDecimal128("100.50")
fmt.Println(d, err)
fmt.Printf("%#v", d)

Output (try it on the Go Playground):

100.50 <nil>
primitive.Decimal128{h:0x303c000000000000, l:0x2742}


Answered By - icza
Answer Checked By - Timothy Miller (PHPFixing Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing