반올림하지 않고 부동 소수점을 문자열로 변환


88

설명 할 필요가없는 이유로 len ()으로 계산할 문자열로 변환 할 float가 필요한 프로그램을 만들고 있습니다. 그러나 str (float (x))는 문자열로 변환 될 때 x가 반올림되어 전체를 버립니다. 누구든지 그것에 대한 수정 사항을 알고 있습니까? 알고 싶은 경우 사용되는 코드는 다음과 같습니다.

len(str(float(x)/3))

2
x가 원래 str이면 왜 캐스트입니까?
Vinko Vrsalovic

1
-1 : 다른 값에 필요한 출력 예가 없습니다 x. 예가 없으면 문제가 무엇인지 추측 할 수 있습니다.
S.Lott

답변:


128

부동 소수점 숫자를 다룰 때 어떤 형태의 반올림은 종종 피할 수 없습니다. 이는 10 진수로 정확하게 표현할 수있는 숫자를 컴퓨터에서 사용하는 2 진수로 항상 정확하게 표현할 수 없기 때문입니다.

예를 들면 :

>>> .1
0.10000000000000001

이 경우 .1이 repr다음을 사용하여 문자열로 변환 된 것을 볼 수 있습니다 .

>>> repr(.1)
'0.10000000000000001'

이 문제를 해결하기 위해 str ()을 사용할 때 파이썬이 마지막 몇 자릿수를 잘라낸다고 생각하지만, 무슨 일이 일어나고 있는지 이해하는 것을 대체하지 않는 부분적인 해결 방법입니다.

>>> str(.1)
'0.1'

"반올림"이 어떤 문제를 일으키는 지 정확히 모르겠습니다. 출력을보다 정확하게 제어하는 ​​방법으로 문자열 형식화를 더 잘 수행 할 수 있습니까?

예 :

>>> '%.5f' % .1
'0.10000'
>>> '%.5f' % .12345678
'0.12346'

여기에 문서가 있습니다 .


12
len(repr(float(x)/3))

그러나 나는 이것이 당신이 생각하는 것만 큼 신뢰할 수 없다고 말해야합니다.

부동 소수점은 10 진수로 입력 / 표시되지만 컴퓨터 (사실 표준 C 라이브러리)는이를 2 진수로 저장합니다. 이 전환으로 인해 몇 가지 부작용이 발생합니다.

>>> print len(repr(0.1))
19
>>> print repr(0.1)
0.10000000000000001

이것이 일어나는 이유에 대한 설명 은 파이썬 튜토리얼 의이 장 에 있습니다.

해결책은 파이썬과 같이 10 진수를 구체적으로 추적하는 유형을 사용하는 것입니다 decimal.Decimal.

>>> print len(str(decimal.Decimal('0.1')))
3

: 부문에서 부동의 결과로 작업하는 방법에 관한 좋은 포스트 stackoverflow.com/questions/2958684/python-division
Trutane

3

다른 답변은 이미 부동 숫자의 표현이 까다로운 문제라고 지적했습니다.

질문에 충분한 컨텍스트를 제공하지 않았기 때문에 decimal 모듈이 귀하의 요구에 유용 할 수 있는지 알 수 없습니다.

http://docs.python.org/library/decimal.html

무엇보다도 (문서에서) 얻고 자하는 정밀도를 명시 적으로 지정할 수 있습니다.

>>> getcontext().prec = 6
>>> Decimal('3.0')
Decimal('3.0')
>>> Decimal('3.1415926535')
Decimal('3.1415926535')
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
Decimal('5.85987')
>>> getcontext().rounding = ROUND_UP
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
Decimal('5.85988')

내 프롬프트의 간단한 예 (python 2.6) :

>>> import decimal
>>> a = decimal.Decimal('10.000000001')
>>> a
Decimal('10.000000001')
>>> print a
10.000000001
>>> b = decimal.Decimal('10.00000000000000000000000000900000002')
>>> print b
10.00000000000000000000000000900000002
>>> print str(b)
10.00000000000000000000000000900000002
>>> len(str(b/decimal.Decimal('3.0')))
29

도움이 될까요? decimal은 2.4부터 python stdlib에 있으며 python 2.6에 추가되었습니다.

이것이 도움이되기를 바랍니다, Francesco


0

너무 늦었지만 처음 오시는 분들을 위해 해결책을 게시하고 싶습니다. 나는 float 값 index과 문자열 imgfile을 가지고 있으며 당신과 같은 문제가 있습니다. 이것이 내가 문제를 해결 한 방법입니다.

index = 1.0
imgfile = 'data/2.jpg'
out = '%.1f,%s' % (index,imgfile)
print out

출력은

1.0,data/2.jpg

편의에 따라이 서식 예제를 수정할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.