How datomic compares big decimals

There is schema:

(def user-schema [
                   {
                       :db/ident :User/bigDec
                       :db/valueType :db.type/bigdec
                       :db/cardinality :db.cardinality/one
                   }
                   ])
(d/transact conn user-schema)

And transacted data

(def user-data [
  {
    :db/id 17592186045427
    :User/bigDec (bigdec 3.020M)
  }
])
(d/transact conn user-data)

In the console we see:


So even the last zero is kept what means rounding is not executed. If to transact the next data:

(def user-data [
  {
    :db/id 17592186045434
    :User/bigDec (bigdec 3.02M)
  }
])
(d/transact connUser user-data)

then nothing is changed, if to execute **(= (bigdec 3.00M) (bigdec 3.00000M))** true is returned, but what is interesting, if to use equals from java (.equals (bigdec 3.00M) (bigdec 3.00000M)) then false is returned. Is interesting the thoughts of datomic team whether why the current datomic behaviour is correct.

P.S. Why this question has arrived: we have some db where were pasted big decimals with some umber of ending zeros and we wanted to round all those values and save its back, but the above behaviour did not allow us to do this

I would strongly recommending saving all values for a BigDecimal attribute with the same scale. It sounds like that was your intent, and now you just want to find and fix attributes with nonstandard scale.

I would think a query or datoms across the entire attribute plus a filter on scale would be sufficient to find all the problem values. Does this solve your original problem?

Right, it is possible to find problem values, but problem to correct data since datomic does not see the difference between bigdeciaml with differen scales :slight_smile:

Good idea, I believe we should capture all data coming from client and round its to avoid uncssary zeros

Thanks

Today’s release will help here – you can now use a transaction to correct the scale of a BigDecimal.

2 Likes