[python] 후행 0없이 부동 소수점 형식화

후행 0을 포함하지 않도록 float을 어떻게 포맷 할 수 있습니까? 즉, 결과 문자열을 가능한 짧게 만들고 싶습니다.

예를 들면 다음과 같습니다.

3 -> "3"
3. -> "3"
3.0 -> "3"
3.1 -> "3.1"
3.14 -> "3.14"
3.140 -> "3.14"



답변

저도 할 것입니다 ('%f' % x).rstrip('0').rstrip('.')-과학적 표기법 등이 아닌 고정 소수점 형식을 보장합니다. 예, 매끄럽고 우아 %g하지는 않지만 작동합니다 %g. -).


답변

%g이것을 달성하기 위해 사용할 수 있습니다 :

'%g'%(3.140)

또는 파이썬 2.6 이상의 경우 :

'{0:g}'.format(3.140)

보내는 사람 에 대한 문서format : g(무엇보다도) 원인

중요하지 않은 후행 0은 [유의]에서 제거되며 그 뒤에 남은 자릿수가 없으면 소수점도 제거됩니다.


답변

가장 쉽고 아마도 가장 효과적인 접근법을 시도하는 것은 어떻습니까? normalize () 메소드 는 가장 오른쪽에있는 모든 0을 제거합니다.

from decimal import Decimal

print (Decimal('0.001000').normalize())
# Result: 0.001

Python 2Python 3 에서 작동합니다 .

-업데이트-

@ BobStein-VisiBone이 지적한 유일한 문제는 10, 100, 1000 …과 같은 숫자가 지수 표현으로 표시된다는 것입니다. 대신 다음 기능을 사용하여 쉽게 고칠 수 있습니다.

from decimal import Decimal


def format_float(f):
    d = Decimal(str(f));
    return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()


답변

몇 가지 유사한 질문에 대한 답변을 살펴본 후에 이것은 가장 좋은 해결책 인 것 같습니다.

def floatToString(inputValue):
    return ('%.15f' % inputValue).rstrip('0').rstrip('.')

내 추론 :

%g 과학적 표기법을 제거하지 않습니다.

>>> '%g' % 0.000035
'3.5e-05'

소수 자릿수 15 자리는 이상한 행동을 피하는 것으로 보이며 내 요구에 충분한 정밀도를 가지고 있습니다.

>>> ('%.15f' % 1.35).rstrip('0').rstrip('.')
'1.35'
>>> ('%.16f' % 1.35).rstrip('0').rstrip('.')
'1.3500000000000001'

format(inputValue, '.15f').대신 사용할 수는 '%.15f' % inputValue있지만 조금 느립니다 (~ 30 %).

사용할 수는 Decimal(inputValue).normalize()있지만 몇 가지 문제가 있습니다. 하나, 그것은 훨씬 더 느립니다 (~ 11x). 또한 정확도가 매우 뛰어나지 만 사용할 때 여전히 정밀도 손실이 발생한다는 것을 알았습니다 normalize().

>>> Decimal('0.21000000000000000000000000006').normalize()
Decimal('0.2100000000000000000000000001')
>>> Decimal('0.21000000000000000000000000006')
Decimal('0.21000000000000000000000000006')

가장 중요한 것은, 나는 여전히 당신이 거기에 넣은 숫자가 아닌 다른 것으로 끝날 수있는 Decimal에서 로 변환 할 float것입니다. 내가 생각하는 Decimal일을 가장 잘 할 때 산술에서 숙박 Decimal하고이 Decimal문자열로 초기화됩니다.

>>> Decimal(1.35)
Decimal('1.350000000000000088817841970012523233890533447265625')
>>> Decimal('1.35')
Decimal('1.35')

Decimal.normalize()컨텍스트 설정을 사용하여 필요한 것에 대한 정밀도 문제를 조정할 수 있다고 확신 하지만 이미 느린 속도와 어리석은 정밀도가 필요하지 않고 여전히 부동에서 변환하고 정밀도를 잃어 가고 있다는 사실을 고려하면 추구 할 가치가 있다고 생각하지 않습니다.

-0.0이 유효한 부동 소수점 수이므로 가능한 “-0″결과에 대해 걱정하지 않고 어쨌든 드물게 발생하지만 문자열 결과를 가능한 한 짧게 유지하려고합니다. 아주 작은 추가 비용으로 항상 추가 조건을 사용할 수 있습니다.

def floatToString(inputValue):
    result = ('%.15f' % inputValue).rstrip('0').rstrip('.')
    return '0' if result == '-0' else result


답변

나를 위해 일한 해결책이 있습니다. 그것은의 혼합의 솔루션 으로 폴리 메쉬 새로운의 사용 .format() 구문 .

for num in 3, 3., 3.0, 3.1, 3.14, 3.140:
    print('{0:.2f}'.format(num).rstrip('0').rstrip('.'))

출력 :

3
3
3
3.1
3.14
3.14


답변

format ()을 사용하여 이것을 달성 할 수 있습니다.

format(3.140, '.10g') 여기서 10은 원하는 정밀도입니다.


답변

>>> str(a if a % 1 else int(a))