Skip to content

Commit

Permalink
updated json readme
Browse files Browse the repository at this point in the history
  • Loading branch information
jlangch committed Oct 20, 2023
1 parent 13ac722 commit 597c771
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 25 deletions.
51 changes: 39 additions & 12 deletions doc/readme/json-lines.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,47 +173,74 @@ JSON handling.

#### Decimals

**JSON floating-point number problem**

When dealing with floating-point numbers, we often encounter a rounding
errors known as the double precision issue.

```clojure
(do
(load-module :jsonl)

(jsonl/write-str {:a (+ 0.1 0.2)}))
;;=> "{\"a\":0.30000000000000004}"
```

Using decimals avoid this problem and are the means of choice when dealing
with financial amounts but unfortunately JSON does not support decimals as
data type.



**Venice's approach for decimals**

Venice decimals are converted to strings by default:

```clojure
(do
(load-module :jsonl)

(jsonl/write-str {:a 100.23M}))

;;=> "{\"a\":\"100.23\"}"
;;=> "{\"a\":\"100.23\"}"
```

But Venice decimals can also be forced to be converted to doubles
when the loss of precision is acceptable:
But Venice decimals can also be forced to be converted to doubles:

```clojure
(do
(load-module :jsonl)

(jsonl/write-str {:a 100.23M} :decimal-as-double true))
(json/write-str {:a (+ 0.1M 0.2M)} :decimal-as-double true)
;;=> "{\"a\":0.3}"

;;=> "{\"a\":100.23}"
(jsonl/write-str {:a 100.23M} :decimal-as-double true))
;;=> "{\"a\":100.23}"
```

If for example the loss of precision is not acceptable with financial
money amounts Venice support implicite support for decimal values when
reading floating point numbers from JSON.

While writing Venice emits decimals as 'double' floating-point values
in exact representation. On reading back this floating-point string
is directly converted into a decimal, without intermediate double
conversion, thus keeping the precision.
conversion, thus keeping the precision and allow for full decimal
value range.

```clojure
(do
(load-module :jsonl)

(jsonl/write-str {:a 100.33M} :decimal-as-double true))
(jsonl/write-str {:a 100.33M} :decimal-as-double true)
;;=> "{\"a\":100.33}"

(jsonl/write-str {:a 99999999999999999999999999999999999999999999999999.33M}
:decimal-as-double true)
;;=> "{\"a\":99999999999999999999999999999999999999999999999999.33}"


(jsonl/read-str """{"a":10.33}""" :decimal true)
;;=> {"a" 10.33M}

(jsonl/read-str """{"a":99999999999999999999999999999999999999999999999999.33}"""
:decimal true)
;;=> {"a" 99999999999999999999999999999999999999999999999999.33M}
)
```

Expand Down
52 changes: 39 additions & 13 deletions doc/readme/json.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,38 +86,64 @@ Map JSON object values to local-date-time

#### Decimals

**JSON floating-point number problem**

When dealing with floating-point numbers, we often encounter a rounding
errors known as the double precision issue.

```clojure
(json/write-str {:a (+ 0.1 0.2)})
;;=> "{\"a\":0.30000000000000004}"
```

Using decimals avoid this problem and are the means of choice when dealing
with financial amounts but unfortunately JSON does not support decimals as
data type.



**Venice's approach for decimals**

Venice decimals are converted to strings by default:

```clojure
(json/write-str {:a 100.23M})
;;=> "{\"a\":\"100.23\"}"
```

But Venice decimals can also be forced to be converted to doubles
when the loss of precision is acceptable:
But Venice decimals can also be forced to be converted to doubles:

```clojure
(json/write-str {:a (+ 0.1M 0.2M)} :decimal-as-double true)
;;=> "{\"a\":0.3}"

(json/write-str {:a 100.23M} :decimal-as-double true))

;;=> "{\"a\":100.23}"
```

If for example the loss of precision is not acceptable with financial
money amounts Venice support implicite support for decimal values when
reading floating point numbers from JSON.

While writing Venice emits decimals as 'double' floating-point values
in exact representation. On reading back this floating-point string
is directly converted into a decimal, without intermediate double
conversion, thus keeping the precision.
conversion, thus keeping the precision and allow for full decimal
value range.

```clojure
(json/write-str {:a 100.33M} :decimal-as-double true))
;;=> "{\"a\":100.33}"
(do
(json/write-str {:a 100.33M} :decimal-as-double true)
;;=> "{\"a\":100.33}"

(json/write-str {:a 99999999999999999999999999999999999999999999999999.33M}
:decimal-as-double true)
;;=> "{\"a\":99999999999999999999999999999999999999999999999999.33}"

(json/read-str """{"a":10.33}""" :decimal true)
;;=> {"a" 10.33M}
```

(json/read-str """{"a":10.33}""" :decimal true)
;;=> {"a" 10.33M}

(json/read-str """{"a":99999999999999999999999999999999999999999999999999.33}"""
:decimal true)
;;=> {"a" 99999999999999999999999999999999999999999999999999.33M}
)```


#### Binary data
Expand Down

0 comments on commit 597c771

Please sign in to comment.