Last active
August 29, 2015 13:58
-
-
Save pyrtsa/10009826 to your computer and use it in GitHub Desktop.
Python: Convert floating point numbers to decimal keeping N digits of precision.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import math | |
| from decimal import Decimal | |
| def magnitude(value): | |
| """Decimal magnitude of abs(value) as int, or float('-inf') if value == 0. | |
| Example: | |
| >>> [magnitude(x) for x in [1.314234123412345678e-9, 124.355, -1000, 0]] | |
| [-9, 2, 3, -inf] | |
| """ | |
| return int(math.floor(math.log10(abs(value)))) if value else float('-inf') | |
| def approx(value, digits=4): | |
| """Convert value to Decimal keeping the given number of digits after the | |
| leading number. | |
| >>> [approx(x) for x in [1.314234123412345678e-9, 124.355, -1000, 0]] | |
| [Decimal('1.3142E-9'), Decimal('124.36'), Decimal('-1000.0'), Decimal('0')] | |
| """ | |
| if not isinstance(value, Decimal): value = Decimal(value) | |
| return round(value, digits - magnitude(value)) if value != 0 else value | |
| def decstr(x): | |
| """Convert (float) number x to string with sufficient precision | |
| for converting it back to float but without using the engineering | |
| notation. Example: | |
| >>> [decstr(x) for x in [1.314234123412345678e-9, 124.355, -1000, 0]] | |
| ['0.0000000013142341234123457', '124.355', '-1000', '0'] | |
| """ | |
| return format(Decimal(str(x)), 'f') | |
| # To print values with reasonable precision and without scientific notation, | |
| # use the 'f' format code: | |
| if __name__ = '__main__': | |
| for x in [1.31423412341e-9, 124.355, -1000, 0]: | |
| print(format(approx(x), 'f')) | |
| # => | |
| # 0.0000000013142 | |
| # 124.36 | |
| # -1000.0 | |
| # 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment