Para conseguir que esto funcione, hay que normalizar la decimal primera:
>>> x = decimal.Decimal ('10000000')
>>> x.normalize()
Decimal('1E+7')
>>> x.normalize().to_eng_string()
'10E+6'
La razón de esto puede ser descubierto por ahondar en la fuente código.
Si examina to_eng_string()
en el Python 2.7.3 árbol de fuentes (Lib/decimal.py
de la bola de alquitrán fuente gzipped here), que simplemente llama __str__
con eng
establece en true.
A continuación, puede ver que se decide sobre cuántos dígitos ir a la izquierda del punto decimal inicialmente con:
leftdigits = self._exp + len(self._int)
La siguiente tabla muestra cuáles son los valores de estas dos cosas:
._exp ._int len leftdigits
----- --------- --- ----------
Decimal (1000000) 0 '1000000' 7 7
Decimal ('1E+6') 6 '1' 1 7
El código que sigue después de eso es:
if self._exp <= 0 and leftdigits > -6:
# no exponent required
dotplace = leftdigits
elif not eng:
# usual scientific notation: 1 digit on left of the point
dotplace = 1
elif self._int == '0':
# engineering notation, zero
dotplace = (leftdigits + 1) % 3 - 1
else:
# engineering notation, nonzero
dotplace = (leftdigits - 1) % 3 + 1
y se puede ver que, unle Si ya es tiene un exponente en un cierto rango (self._exp > 0 or leftdigits <= -6
), no se le dará ninguno en la representación de cadena.
La investigación adicional muestra el motivo de este comportamiento. Al mirar el código en sí, verá que está basado en el General Decimal Arithmetic Specification
(PDF here).
Si usted busca en ese documento para to-scientific-string
(sobre la que se basa en gran medida to-engineering-string
), se establece en la parte (parafraseado, y con los pedazos en negrilla):
Las "a-científica-string" convertidos operación un número a una cadena, usando la notación científica si se necesita un exponente. La operación no se ve afectada por el contexto.
Si el número es un número finito entonces:
El coeficiente se convierte primero en una cadena en base diez utilizando los caracteres 0 a 9 sin ceros a la izquierda (excepto si su valor es cero, en la que un caso se usa un solo carácter 0).
A continuación, se calcula el exponente ajustado; este es el exponente, más el número de caracteres en el coeficiente convertido, menos uno. Es decir, exponente + (clength-1), donde clength es la longitud del coeficiente en dígitos decimales.
Si el exponente es menor o igual que cero y el exponente ajustado es mayor o igual que -6, el número se convertirá a una forma de carácter sin usar la notación exponencial. En este caso, si el exponente es cero, entonces no se agrega punto decimal. De lo contrario (el exponente será negativo), se insertará un punto decimal con el valor absoluto del exponente que especifica el número de caracteres a la derecha del punto decimal. Los caracteres "0" se agregan a la izquierda del coeficiente convertido según sea necesario. Si ningún carácter precede al punto decimal después de esta inserción, entonces se prefija un carácter "0" convencional.
En otras palabras, está haciendo lo que está haciendo porque eso es lo que el estándar le dice que haga.
he encontrado la solución aquí ".4G%" % x – lehalle