Convert '6E+007' into Decimal

给你一囗甜甜゛ 提交于 2019-12-06 10:23:40

You're checking the validity by converting to float, but actually doing the conversion with int - the discrepancy is causing your problems.

The decimal module is the best way to convert large format numbers.

>>> int(decimal.Decimal('6E+007'))
60000000

You don't want to do a double conversion to float then int because that can result in rounding errors.

>>> int(float('1e23'))
99999999999999991611392L
>>> int(decimal.Decimal('1e23'))
100000000000000000000000L

Hmm. You changed the original question; the way it is now it should be trivial: since you're checking for whether float() works now, just be consistent with that: stop using int()! That is, change to this:

def format_decimal(value, decimals):
    try:
        if decimals == 2:
            value = float(value)/100
            return "{:.2f}".format(value)
    except ValueError:
        raise

But the code is still confused:

  1. Why are you dividing by 100? Do you really want, e.g., "1234" to change into "12.34"?
  2. What if decimals isn't 2? Then your format_decimal() does nothing: it "falls off the end" and so returns None.
  3. Catching an exception and immediately re-raising it is the same as not bothering to catch it to begin with. That is, the try/except structure, as written, does nothing except complicate the code.

It would really help if you gave exact examples of input strings and their expected output strings.

Generalizing

Try this?

def format_decimal(value, decimals=2):
    from decimal import Decimal
    # divide value by 10**decimals; this is just scaling
    value = Decimal(value).scaleb(-decimals)
    return "{:.{d}f}".format(value, d=decimals)

That allows specifying the scaling factor (decimals). Here's sample input/output. If anything isn't what you want, say exactly what it is that you do want:

for v in "1", "1234.5678", "1.2e6":
    for d in range(4):
        print repr(v), d, "->", repr(format_decimal(v, d))

and the output:

'1' 0 -> '1'
'1' 1 -> '0.1'
'1' 2 -> '0.01'
'1' 3 -> '0.001'
'1234.5678' 0 -> '1235'
'1234.5678' 1 -> '123.5'
'1234.5678' 2 -> '12.35'
'1234.5678' 3 -> '1.235'
'1.2e6' 0 -> '1200000'
'1.2e6' 1 -> '120000.0'
'1.2e6' 2 -> '12000.00'
'1.2e6' 3 -> '1200.000'

The problem is simple. 6E+007 is not an integer notation, but a float notation.

Instead of int('6E+007'), use float first:

int(float('6E+007'))

Or, use the decimal module:

import decimal
int(decimal.Decimal('6E+007'))

Also, IMO if you want the number to have two decimal places, you should use float instead, since the value of an integer cannot contain any fractional component, and will always be like that. For example, int('1.5') will always be 1, not 1.5.

So just use:

value = float(value/100) #Well, i'll keep the division here,
# since i don't know what it's about.
return ":{.2f}".format(value)

Hope this helps!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!