2

I have a float let's say

x = 2.00

I want to send that as json

message = { 'x': 2.00 } 

But when I do

print(message)

I see that python has dropped the last decimal place. How can I keep the float at two decimal places? I understand that 2.00 and 2.0 are not different but it's a requirement that I send that exact number (two decimal places included) (I have tried the Decimal class, it still acts the same and I need to send it as a float not a string). Thanks in advance.

Morpheus.47
  • 131
  • 2
  • 10
  • This cannot be done in `json` as there is no requirement on the formatting of floats. This would have to be done after the `json` has been decoded again, by formatting as a string. See: https://stackoverflow.com/questions/8885663/how-to-format-a-floating-number-to-fixed-width-in-python – quamrana Jan 02 '20 at 14:10

4 Answers4

0

You would need to use a specialized library for serializing floats and retaining precision. Protocol Buffers is one such library (protocol)you can define your own JSON encoder class: https://developers.google.com/protocol-buffers/docs/proto3.

kederrac
  • 16,819
  • 6
  • 32
  • 55
Avi Kaminetzky
  • 1,489
  • 2
  • 19
  • 42
0

you can define your own JSON encoder class:

import json

message = {'x': 2.00}

class MyEncoder(json.JSONEncoder):
    def encode(self, obj):

        if isinstance(obj, dict):
            result = '{'
            for key, value in obj.items():
                if isinstance(value, float):
                    encoded_value = format(value, '.2f')
                else:
                    encoded_value = json.JSONEncoder.encode(self, value)

                result += f'"{key}": {encoded_value}, '

            result = result[:-2] + '}'
            return result
        return json.JSONEncoder.encode(self, obj)

print(json.dumps(message, cls=MyEncoder))

output:

{"x": 2.00}
kederrac
  • 16,819
  • 6
  • 32
  • 55
0

You can do this with a custom JSONEncoder by:

  1. Encoding the number as a 2dp string with some surrounding characters.

  2. Using regex to strip out the special characters and the quotes.

Here's an example using Decimal:

from decimal import Decimal
from json import JSONEncoder
import json
import re


def to_json(value: dict) -> str:
    class DecimalEncoder(JSONEncoder):
        def default(self, obj):
            if type(obj) is Decimal:
                return f"Decimal({obj:.2f})"
            else:
                return JSONEncoder.default(self, obj)

    json_string = json.dumps(value, cls=DecimalEncoder)
    json_string = re.sub(r'"Decimal\((.*?)\)"', r"\1", json_string)

    return json_string


before = {
    "amount": Decimal("2.1"),
}

after = to_json(before)

print(before)
print(after)

And the result:

{'amount': Decimal('2.1')}
{"amount": 2.10}
-1

Here's an example:

a=2.00
print ("{0:.2f}".format(a))
Henridv
  • 766
  • 12
  • 23
Tej
  • 11
  • 1