|
| 1 | +def json_float_round(value, precision_digits, rounding_method="HALF-UP"): |
| 2 | + """Not suitable for float calculations! Similar to float_repr except that it |
| 3 | + returns a float suitable for json dump |
| 4 | +
|
| 5 | + This may be necessary to produce "exact" representations of rounded float |
| 6 | + values during serialization, such as what is done by `json.dumps()`. |
| 7 | + Unfortunately `json.dumps` does not allow any form of custom float representation, |
| 8 | + nor any custom types, everything is serialized from the basic JSON types. |
| 9 | +
|
| 10 | + :param int precision_digits: number of fractional digits to round to. |
| 11 | + :param rounding_method: the rounding method used: 'HALF-UP', 'UP' or 'DOWN', |
| 12 | + the first one rounding up to the closest number with the rule that |
| 13 | + number>=0.5 is rounded up to 1, the second always rounding up and the |
| 14 | + latest one always rounding down. |
| 15 | + :return: a rounded float value that must not be used for calculations, but |
| 16 | + is ready to be serialized in JSON with minimal chances of |
| 17 | + representation errors. |
| 18 | + """ |
| 19 | + rounded_value = float_round( |
| 20 | + value, precision_digits=precision_digits, rounding_method=rounding_method |
| 21 | + ) |
| 22 | + rounded_repr = float_repr(rounded_value, precision_digits=precision_digits) |
| 23 | + # As of Python 3.1, rounded_repr should be the shortest representation for our |
| 24 | + # rounded float, so we create a new float whose repr is expected |
| 25 | + # to be the same value, or a value that is semantically identical |
| 26 | + # and will be used in the json serialization. |
| 27 | + # e.g. if rounded_repr is '3.1750', the new float repr could be 3.175 |
| 28 | + # but not 3.174999999999322452. |
| 29 | + # Cfr. bpo-1580: https://bugs.python.org/issue1580 |
| 30 | + return float(rounded_repr) |
0 commit comments