내가 원하는 a
13.95로 반올림합니다.
>>> a 13.949999999999999 >>> round(a, 2) 13.949999999999999
round
기능이 예상대로 작동하지 않습니다.
질문자 :kevin
내가 원하는 a
13.95로 반올림합니다.
>>> a 13.949999999999999 >>> round(a, 2) 13.949999999999999
round
기능이 예상대로 작동하지 않습니다.
모든 숫자를 정확하게 표현할 수 없는 부동 소수점 숫자에 대한 오래된 문제에 직면하고 있습니다. 명령줄은 메모리의 전체 부동 소수점 형식을 보여줍니다.
부동 소수점 표현을 사용하면 반올림된 버전이 동일한 숫자입니다. 컴퓨터는 이진법이므로 부동 소수점 숫자를 정수로 저장한 다음 2의 거듭제곱으로 나누므로 13.95는 125650429603636838/(2**53)과 유사한 방식으로 표시됩니다.
배정밀도 숫자는 53비트(16자리)의 정밀도를 가지며 일반 부동 소수점은 24비트(8자리)의 정밀도를 갖습니다. Python의 부동 소수점 유형은 배정밀도 를 사용하여 값을 저장합니다.
예를 들어,
>>> 125650429603636838/(2**53) 13.949999999999999 >>> 234042163/(2**24) 13.949999988079071 >>> a = 13.946 >>> print(a) 13.946 >>> print("%.2f" % a) 13.95 >>> round(a,2) 13.949999999999999 >>> print("%.2f" % round(a, 2)) 13.95 >>> print("{:.2f}".format(a)) 13.95 >>> print("{:.2f}".format(round(a, 2))) 13.95 >>> print("{:.15f}".format(round(a, 2))) 13.949999999999999
예를 들어 통화 값을 표시하기 위해 소수점 이하 두 자리만 뒤에 있는 경우 몇 가지 더 나은 선택이 있습니다.
새로운 형식 사양인 String 형식 사양 Mini-Language가 있습니다 .
다음과 같이 할 수 있습니다.
"{:.2f}".format(13.949999999999999)
참고 1: 위는 문자열을 반환합니다. float를 얻으려면 단순히 float(...)
래핑하십시오.
float("{:.2f}".format(13.949999999999999))
참고 2: float()
래핑해도 아무 것도 변경되지 않습니다.
>>> x = 13.949999999999999999 >>> x 13.95 >>> g = float("{:.2f}".format(x)) >>> g 13.95 >>> x == g True >>> h = round(x, 2) >>> h 13.95 >>> x == h True
가장 간단한 방법은 format()
함수를 사용하는 것입니다.
예를 들어:
a = 13.949999999999999 format(a, '.2f') 13.95
이것은 소수점 이하 두 자리로 반올림된 문자열로 부동 소수점 숫자를 생성합니다.
여기에서 아무도 그것을 언급하지 않은 것 같으니, Python 3.6의 f-string/template-string 형식으로 예를 들어보겠습니다.
>>> f'{a:.2f}'
연산자가 있고 괄호가 필요하지 않은 긴 예제에서도 잘 작동합니다.
>>> print(f'Completed in {time.time() - start:.2f}s')
대부분의 숫자는 float로 정확하게 표현할 수 없습니다. 수학 공식이나 알고리즘이 필요하기 때문에 숫자를 반올림하려면 반올림을 사용하고 싶습니다. 표시를 특정 정밀도로 제한하려면 round를 사용하지 않고 해당 문자열로 형식을 지정하면 됩니다. (다른 반올림 방법으로 표시하고 싶은데 톤이 있는 경우 두 가지 접근 방식을 혼합해야 합니다.)
>>> "%.2f" % 3.14159 '3.14' >>> "%.2f" % 13.9499999 '13.95'
그리고 마지막으로 가장 중요한 것은 정확한 수학을 원한다면 부동 소수점을 전혀 원하지 않는다는 것입니다. 일반적인 예는 돈을 다루고 '센트'를 정수로 저장하는 것입니다.
사용하다
print"{:.2f}".format(a)
대신에
print"{0:.2f}".format(a)
후자는 여러 변수를 출력하려고 할 때 출력 오류로 이어질 수 있기 때문입니다(주석 참조).
아래 코드를 시도하십시오.
>>> a = 0.99334 >>> a = int((a * 100) + 0.5) / 100.0 # Adding 0.5 rounds it up >>> print a 0.99
입력/출력의 반올림 문제는 Python 2.7.0 및 3.1에서 확실히 해결되었습니다.
올바르게 반올림된 숫자는 앞뒤로 가역적으로 변환할 수 있습니다.
str -> float() -> repr() -> float() ...
또는 Decimal -> float -> str -> Decimal
Decimal 유형은 더 이상 스토리지에 필요하지 않습니다.
(물론, 누적된 마지막 비트 오류를 제거하기 위해 반올림된 숫자의 덧셈 또는 뺄셈 결과를 반올림해야 할 수 있습니다. 명시적인 10진수 산술은 여전히 편리할 수 있지만 str()
의한 문자열로의 변환(반올림 포함) 12개의 유효한 숫자)는 일반적으로 극도의 정확도가 없거나 극도의 연속 산술 연산이 필요하지 않은 경우 충분합니다.)
무한 테스트 :
import random from decimal import Decimal for x in iter(random.random, None): # Verify FOREVER that rounding is fixed :-) assert float(repr(x)) == x # Reversible repr() conversion. assert float(Decimal(repr(x))) == x assert len(repr(round(x, 10))) <= 12 # Smart decimal places in repr() after round. if x >= 0.1: # Implicit rounding to 12 significant digits assert str(x) == repr(round(x, 12)) # by str() is good enough for small errors. y = 1000 * x # Decimal type is excessive for shopping assert str(y) == repr(round(y, 12 - 3)) # in a supermaket with Python 2.7+ :-)
릴리스 정보 Python 2.7 - 기타 언어 변경 네 번째 단락을 참조하세요.
이제 대부분의 플랫폼에서 부동 소수점 숫자와 문자열 간의 변환 이 올바르게 반올림됩니다. 이러한 변환은 다양한 위치에서 발생합니다. 부동 소수점 및 복소수의 str(); float 및 복잡한 생성자; 숫자 서식;
marshal
,pickle
및json
모듈을 사용하여 부동 소수점 및 복소수 직렬화 및 역직렬화 Python 코드에서 부동 소수점 및 허수 리터럴 구문 분석; 10진수에서 부동 소수점으로의 변환.이와 관련하여 부동 소수점 숫자 x의 repr() 은 이제 올바른 반올림(반올림에서 짝수로 반올림 모드 사용) 에서 x로 반올림되도록 보장되는 가장 짧은 십진수 문자열을 기반으로 결과를 반환합니다. 이전에는 x를 17자리 십진수로 반올림하여 문자열을 제공했습니다.
추가 정보: Python 2.7 이전 float
형식은 numpy.float64
와 유사했습니다. 두 유형 모두 52비트 가수와 함께 동일한 64비트 IEEE 754 배정밀도를 사용합니다. 큰 차이점은 np.float64.__repr__
이 비트가 손실될 수 없도록 과도한 십진수로 자주 형식이 지정되지만 13.949999999999999와 13.9500000000000001 사이에 유효한 IEEE 754 번호가 없다는 것입니다. 결과가 좋지 않고 repr(float(number_as_string))
변환은 numpy로 되돌릴 수 없습니다. 반면에 float.__repr__
은 모든 숫자가 중요하도록 형식이 지정됩니다. 순서는 간격이 없으며 변환은 되돌릴 수 있습니다. 간단히: numpy.float64 숫자가 있는 경우 숫자 프로세서가 아닌 사람을 위해 형식화하려면 일반 float로 변환하십시오. 그렇지 않으면 Python 2.7+에서 더 이상 필요하지 않습니다.
출력 형식을 수정할 수 있습니다.
>>> a = 13.95 >>> a 13.949999999999999 >>> print "%.2f" % a 13.95
Python < 3(예: 2.6 또는 2.7)에서는 두 가지 방법이 있습니다.
# Option one older_method_string = "%.9f" % numvar # Option two (note ':' before the '.9f') newer_method_string = "{:.9f}".format(numvar)
그러나 3 이상의 Python 버전(예: 3.2 또는 3.3)의 경우 옵션 2가 선호 됩니다.
옵션 2에 대한 자세한 내용은 Python 설명서의 문자열 형식 지정 에 대한 이 링크를 제안합니다.
옵션 1에 대한 자세한 내용은 이 링크로 충분하며 다양한 플래그에 대한 정보가 있습니다.
float_number = 12.234325335563 round(float_number, 2)
이것은 돌아올 것입니다.
12.23
설명:
round 함수는 두 개의 인수를 취합니다. 반올림할 숫자와 반환할 소수 자릿수. 여기에서 소수점 이하 2자리를 반환했습니다.
파이썬에서 소수점 이하 2자리까지 값을 반올림 하기 위해 형식 연산자를 사용할 수 있습니다:
print(format(14.4499923, '.2f')) // output is 14.45
파이썬 2.7:
a = 13.949999999999999 output = float("%0.2f"%a) print output
@Matt가 지적했듯이 Python 3.6은 f-strings 를 제공하며 중첩 매개변수 도 사용할 수 있습니다.
value = 2.34558 precision = 2 width = 4 print(f'result: {value:{width}.{precision}f}')
결과를 표시합니다 result: 2.35
Python 튜토리얼에는 Floating Point Arithmetic: Issues and Limitations 라는 부록이 있습니다. 읽어. 무슨 일이 일어나고 있고 왜 파이썬이 최선을 다하는지 설명합니다. 그것은 당신과 일치하는 예도 있습니다. 조금 인용하자면:
>>> 0.1 0.10000000000000001
round()
함수를 사용하여 예상한 한 자릿수로 다시 자르고 싶을 수 있습니다. 그러나 그것은 차이가 없습니다:>>> round(0.1, 1) 0.10000000000000001
“0.1”
에 대해 저장된 이진 부동 소수점 값1/10
대한 최상의 이진 근사값이었기 때문에 다시 반올림하려고 해도 더 나아질 수 없다는 것입니다.또 다른 결과는 그 이후
0.1
정확하지 않다1/10
의 열 값을 합산0.1
정확하게 산출되지 않을1.0
중 :>>> sum = 0.0 >>> for i in range(10): ... sum += 0.1 ... >>> sum 0.99999999999999989
문제에 대한 한 가지 대안 및 솔루션은 decimal
모듈을 사용하는 것입니다.
이를 위해 여러 가지 옵션이 있습니다. 옵션 1:
x = 1.090675765757 g = float("{:.2f}".format(x)) print(g)
옵션 2: 내장된 round()는 Python 2.7 이상을 지원합니다.
x = 1.090675765757 g = round(x, 2) print(g)
Decimal 객체와 round() 메서드의 조합을 사용합니다.
Python 3.7.3 >>> from decimal import Decimal >>> d1 = Decimal (13.949999999999999) # define a Decimal >>> d1 Decimal('13.949999999999999289457264239899814128875732421875') >>> d2 = round(d1, 2) # round to 2 decimals >>> d2 Decimal('13.95')
from decimal import Decimal def round_float(v, ndigits=2, rt_str=False): d = Decimal(v) v_str = ("{0:.%sf}" % ndigits).format(round(d, ndigits)) if rt_str: return v_str return Decimal(v_str)
결과:
Python 3.6.1 (default, Dec 11 2018, 17:41:10) >>> round_float(3.1415926) Decimal('3.14') >>> round_float(3.1445926) Decimal('3.14') >>> round_float(3.1455926) Decimal('3.15') >>> round_float(3.1455926, rt_str=True) '3.15' >>> str(round_float(3.1455926)) '3.15'
Python 및 JavaScript와 같은 유형 동적 언어에서 부동 소수점을 수정하기 위해 이 기술을 사용합니다.
# For example: a = 70000 b = 0.14 c = a * b print c # Prints 980.0000000002 # Try to fix c = int(c * 10000)/100000 print c # Prints 980
다음과 같이 Decimal을 사용할 수도 있습니다.
from decimal import * getcontext().prec = 6 Decimal(1) / Decimal(7) # Results in 6 precision -> Decimal('0.142857') getcontext().prec = 28 Decimal(1) / Decimal(7) # Results in 28 precision -> Decimal('0.1428571428571428571428571429')
다음과 같은 람다 함수는 어떻습니까?
arred = lambda x,n : x*(10**n)//1/(10**n)
이 방법으로 다음을 수행할 수 있습니다.
arred(3.141591657,2)
그리고 얻다
3.14
orig_float = 232569 / 16000.0
14.5355625
short_float = float("{:.2f}".format(orig_float))
14.54
1,2,3과 같이 간단합니다.
빠르고 정확하게 반올림된 10진수 부동 소수점 산술을 위해 10진수 모듈을 사용하십시오.
d=10진수(10000000.0000009)
반올림을 달성하려면:
d.quantize(Decimal('0.01'))
결과는 Decimal('10000000.00')
def round_decimal(number, exponent='0.01'): decimal_value = Decimal(number) return decimal_value.quantize(Decimal(exponent))
또는
def round_decimal(number, decimal_places=2): decimal_value = Decimal(number) return decimal_value.quantize(Decimal(10) ** -decimal_places)
추신: 다른 사람에 대한 비판: 형식이 반올림되지 않습니다.
숫자를 해상도로 반올림하는 가장 좋은 방법은 모든 해상도에서 작동할 수 있는 다음 방법입니다(소수점 두 개 또는 다른 단계의 경우 0.01).
>>> import numpy as np >>> value = 13.949999999999999 >>> resolution = 0.01 >>> newValue = int(np.round(value/resolution))*resolution >>> print newValue 13.95 >>> resolution = 0.5 >>> newValue = int(np.round(value/resolution))*resolution >>> print newValue 14.0
내가 본 답변은 float(52.15) 사례에서 작동하지 않았습니다. 몇 가지 테스트 후에 내가 사용하고 있는 솔루션이 있습니다.
import decimal def value_to_decimal(value, decimal_places): decimal.getcontext().rounding = decimal.ROUND_HALF_UP # define rounding method return decimal.Decimal(str(float(value))).quantize(decimal.Decimal('1e-{}'.format(decimal_places)))
('value'를 float로 변환한 다음 string으로 변환하는 것은 매우 중요합니다. 따라서 'value'는 float, decimal, integer 또는 string 유형이 될 수 있습니다!)
이것이 누구에게나 도움이되기를 바랍니다.
다음은 format 함수를 사용하는 간단한 솔루션입니다.
float(format(num, '.2f'))
참고: 형식 메서드가 문자열을 반환하기 때문에 숫자를 부동 소수점으로 변환합니다.
lambda x,n:int(x*10 n+.5)/10 n은 여러 언어로 수년 동안 저에게 도움이 되었습니다.
돈을 처리하려면 python decimal 모듈을 사용하십시오.
from decimal import Decimal, ROUND_HALF_UP # amount can be integer, string, tuple, float, or another Decimal object def to_money(amount) -> Decimal: money = Decimal(amount).quantize(Decimal('.00'), rounding=ROUND_HALF_UP) return money
이 함수를 사용하고 바이트를 입력으로 전달하기만 하면 됩니다.
def getSize(bytes): kb = round(bytes/1024, 4) mb = round(kb/1024, 4) gb = round(mb/1024, 4) if(gb > 1): return str(gb)+" GB" elif(mb > 1): return str(mb)+" MB" else: return str(kb)+" KB"
이것은 데이터 크기를 바이트에서 KB, MB 또는 GB로 동적으로 변환하는 가장 쉬운 방법입니다.
출처 : http:www.stackoverflow.com/questions/455612/limiting-floats-to-two-decimal-points
특정 문자열을 포함하는 모든 행을 텍스트 파일에서 삭제하는 방법은 무엇입니까? (0) | 2021.12.08 |
---|---|
언제 '$this'보다 'self'를 사용해야 합니까? (0) | 2021.12.08 |
자바스크립트 변수 존재 여부 확인(정의/초기화) (0) | 2021.12.08 |
NPM vs. Bower vs. Browserify vs. Gulp vs. Grunt vs. Webpack (0) | 2021.12.08 |
폴더 및 하위 폴더/파일에 대한 권한을 한 번에 변경하는 방법 (0) | 2021.12.08 |