When formatting floats, is there any python method/formatting for reducing how many decimals that is shown as the number becomes larger?
It could for instance be a limit to how many digits of the number that is shown. Example below:
100.145 -> 100
2.392 -> 2.39
34.827 -> 34.8
4599.298 -> 4599
Update:
As chux points out in his comment, my original solution does not work for
boundary cases in which rounding leads to a carry. Also, I didn't pay attention
to the fact that log10(100) == 2 != 3
.
The second bug is easy to come by. To fix the first one, I came up with a
recursion. Now it should work but isn't simple anymore.
import math
def flexible_format(num_in, total_digits):
try:
digits_before_decimal = math.floor(math.log10(abs(num_in))) + 1
except ValueError:
# if num == 0
return '0'
digits_after_decimal = max(0, total_digits - digits_before_decimal)
# if rounding increases number of digits, we have to format once again
# after that, an additional rounding doesn't increase the number of digits
# so we can be sure not to land in an infinite recursion
num_out = round(num_in, digits_after_decimal)
if math.floor(math.log10(abs(num_out))) >= digits_before_decimal:
return flexible_format(num_out, total_digits)
return f'{num_out:.{digits_after_decimal}f}'
list_nums = [-100.145, 2.392, -34.827 , 4599.298, 99.95, 100 ]
for num in list_nums:
print(flexible_format(num, total_digits=3))
# -100
# 2.39
# -34.8
# 4599
# 100
# 100
Original false solution:
I don't know a commonly used function achieving that, but it is easy to implement.
import math
def flexible_format(num, total_digits):
try:
digits_before_decimal = math.ceil(math.log10(abs(num)))
except ValueError:
# if num == 0
return '0'
digits_after_decimal = max(0, total_digits - digits_before_decimal)
return f'{num:.{digits_after_decimal}f}'
list_nums = [-100.145, 2.392, -34.827 , 4599.298, 0]
for num in list_nums:
print(flexible_format(num, total_digits=3))
# -100
# 2.39
# -34.8
# 4599
# 0