정밀도를 잃지 않고 Python Float를 문자열로 변환
Python을 를 유지하고 .xlrdExcel 스프레드시트에서 값을 검색하여 다양한 작업을 수행합니다.스프레드시트의 일부 셀은 고정밀 수치이므로 그대로 유지해야 합니다.셀 중 할 때, 「 」는 「 」를 실시합니다.xlrd를 float0.38288746115497402입니다.
단, 이 값은 나중에 코드에서 문자열로 입력해야 합니다.어느쪽인가를 한다.str(value) ★★★★★★★★★★★★★★★★★」unicode(value)는, 「 「0.382887461155」등의 것을 합니다.요구사항에는 이것이 허용되지 않으며 정밀도를 유지할 필요가 있다고 나와 있습니다.
나는 지금까지 몇 가지 시도를 해봤지만 성공하지 못했다.첫 번째는 문자열 포맷을 사용한 것입니다.
data = "%.40s" % (value)
data2 = "%.40r" % (value)
그러나 둘 다 같은 반올림수인 "0.382887461155"를 생성합니다.
가 있는 때, 으로 SO를 하는 것이 되었습니다.Decimal데이터 수 을 바꿀 수 없습니다.xlrd의그리고 내가 이걸 하려고 하면
data = Decimal(value)
는 …을 .TypeError: Cannot convert float to Decimal. First convert the float to a string.이치노그렇지 않으면 정밀도가 떨어집니다.
그래서 저는 어떤 제안도 받아들일 수 있습니다.필요하다면 정말 역겨운 제안도 받아들일 수 있습니다.Python(Java/C#에 더 가까운 사람)에 대해서는 잘 모르기 때문에 근본적인 오해가 있으면 언제든지 정정해 주세요.
편집: Python 2.6.4를 사용하고 있다는 것을 덧붙여야겠다고 생각했습니다.버전 변경을 막는 공식적인 요건은 없다고 생각합니다.다른 코드를 망치지 않으면 됩니다.
저는 xlrd의 작가입니다.다른 답변이나 댓글에 반박이 너무 많아서 답변으로 하고 있습니다.
@katrialex:"xlrd의 뱃속에서 헤매고 있다"--- 전혀 근거가 없고 사실이 아니다.xlrd는 XLS 파일에 저장된 64비트 플로트를 정확하게 재현합니다.
@katrialex: "local xlrd installation을 변경하여 float cast를 변경할 수 있을지도 모릅니다." --- 왜 그렇게 하고 싶은지 모르겠습니다.16비트 정수를 플로팅해도 정밀도가 저하되지 않습니다!!!어떤 경우에도 이 코드는 Excel 2.X 파일(INTEGER 타입의 셀 레코드)을 읽을 때만 사용됩니다.OP는 그가 그런 고대 파일을 읽고 있다는 징후는 보이지 않는다.
@jloubert:당신이 틀렸나 봐요. "%.40r" % a_float는 을 얻기 이다.repr(a_float).
@Everybody: 정밀도를 유지하기 위해 플로트를 10진수로 변환할 필요는 없습니다.★★★★★★★★★★★★★★★★★★★★★★의 포인트repr()기능은 다음 사항이 보증되는 것입니다.
float(repr(a_float)) == a_float
Python 2.X(X <= 6) repr은 원래 값을 재현할 수 있도록 보장하기 위해 고정 17자리 정밀도를 제공합니다.이후 피톤(2.7, 3.1)은 원래 값을 재현할 최소 소수 자릿수를 제공합니다.
Python 2.6.4 (r264:75708, Oct 26 2009, 08:23:19) [MSC v.1500 32 bit (Intel)] on win32
>>> f = 0.38288746115497402
>>> repr(f)
'0.38288746115497402'
>>> float(repr(f)) == f
True
Python 2.7 (r27:82525, Jul 4 2010, 09:01:59) [MSC v.1500 32 bit (Intel)] on win32
>>> f = 0.38288746115497402
>>> repr(f)
'0.382887461154974'
>>> float(repr(f)) == f
True
요점은 플로트 객체의 정밀도를 모두 유지하는 문자열을 원하는 경우 ...을 사용한다는 것입니다. 에 의해 나중에 값을 회복합니다.그렇게 간단하다.는 필요 없습니다.decimal★★★★★★ 。
하시면 됩니다.repr()정밀도를 잃지 않고 문자열로 변환한 다음 10진수로 변환:
>>> from decimal import Decimal
>>> f = 0.38288746115497402
>>> d = Decimal(repr(f))
>>> print d
0.38288746115497402
편집: 틀렸습니다.이 답을 여기에 남겨두면 나머지는 말이 되지만, 사실이 아닙니다.위의 John Machin의 답변을 참조하십시오.고마워 =)
위의 답변이 효과가 있다면 매우 좋습니다.그렇게 하면 해킹을 크게 줄일 수 있습니다.하지만, 적어도 내 시스템에서는, 그들은 그러지 않을 것이다.예를 들어, 에서 확인할 수 있습니다.
import sys
print( "%.30f" % sys.float_info.epsilon )
이 숫자는 시스템에서 0과 구별할 수 있는 최소 부동수입니다. 이 값보다 작은 것은 작업을 수행할 때 플로트에서 임의로 더하거나 뺄 수 있습니다.
이것은 적어도 내 Python 셋업에서는 정밀도가 손실된다는 것을 의미합니다.xlrd이데올로기 때문에이상하군. 전에도 이런 일이 일어날 줄 알았는데, 확실히 그런 것 같진 않군!
수정이 할 수 .xlrdfloat문.site-packages\xlrd\sheet.py1099로 .
...
elif rc == XL_INTEGER:
rowx, colx, cell_attr, d = local_unpack('<HH3sH', data)
self_put_number_cell(rowx, colx, float(d), self.fixed_BIFF2_xfindex(cell_attr, rowx, colx))
...
점에 주의:float 좋을 것 요.decimal.Decimal무슨 일이 일어날지 지켜봐야지
편집: 이전 답변을 지웠습니다. 제대로 작동하지 않았습니다.
Python 2.6.5를 사용하고 있으며, 다음과 같이 조작할 수 있습니다.
a = 0.38288746115497402
print repr(a)
type(repr(a)) #Says it's a string
주의: 문자열로 변환됩니다.때 합니다.Decimal★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
이미 언급했듯이, 플로트는 전혀 정확하지 않기 때문에 정밀도를 유지하는 것은 다소 오해의 소지가 있습니다.
다음은 float 객체에서 모든 정보를 가져오는 방법입니다.
>>> from decimal import Decimal
>>> str(Decimal.from_float(0.1))
'0.1000000000000000055511151231257827021181583404541015625'
또 다른 방법은 그렇게 될 것이다.
>>> 0.1.hex()
'0x1.999999999999ap-4'
두 문자열 모두 플로트의 정확한 내용을 나타냅니다.그 외의 모든 것은 float를 python이 아마도 그것이 의도된 것이라고 생각하는 것으로 해석한다(대부분은 정확하다).
언급URL : https://stackoverflow.com/questions/3481289/converting-a-python-float-to-a-string-without-losing-precision
'programing' 카테고리의 다른 글
| Is String.Contains()가 String보다 빠릅니다.Index Of()? (0) | 2023.04.21 |
|---|---|
| Azure 데이터베이스의 비밀번호 재설정 (0) | 2023.04.21 |
| Azure 스토리지 블럽 이름 변경 (0) | 2023.04.21 |
| bash curl 문에 '&' 문자를 포함하는 방법 (0) | 2023.04.21 |
| "이 응용 프로그램은 백그라운드 스레드에서 자동 레이아웃 엔진을 수정하고 있습니다" 오류가 표시됩니까? (0) | 2023.04.21 |