이것은 MariaDB의 ROUND 기능의 오동작입니까?
현재 작업 중인 프로젝트에서 백엔드와 프런트엔드에서 같은 계산을 하고 있는 자신을 발견했습니다.계산은 두 숫자와 다른 숫자의 비율의 곱을 반올림하는 것이다. 즉, 라운드 대 라운드 표현은 다음과 같은 형식이다.
x / y * n
프런트엔드는 자바스크립트를 사용하고 백엔드는 MariaDB를 사용하고 있습니다.x=41, y=60 및 n=30의 경우 프런트 엔드는 21로 표시됩니다.
41 / 60 * 30
20.5이지만 MariaDB의 구현은ROUND()
함수는 내가 이 표현에 전달했을 때 20을 준다!
ROUND(41/60*30,0)
(MariaDB)가 평가하는데도
41 / 60 * 30
올바른 결과 20.199에 도달합니다.
20.5(20.5000)를 MariaDB에 패스하면ROUND()
함수, 함수는 올바른 결과 21을 반환합니다!이 미스터리를 (적어도) 다음 SQL 문장으로 요약했습니다.
SELECT 41/60*30, ROUND(41/60*30,0), ROUND(20.5,0), ROUND(20.5000,0)
그 출력은...
구현에 문제가 있습니까?ROUND()
기능하고 있습니까?
이것은 부동소수점 정밀도 문제입니다.
SELECT CAST(41/60*30 AS DECIMAL(22,20))
다음과 같은 것이 있습니다.
20.49999999000000000000
그래서 반올림하면 20이 나옵니다.이 문제를 해결하려면DECIMAL
정확도가 떨어집니다(예:(5,3)
) 또는 이중 반올림(예:
SELECT ROUND(CAST(41/60*30 AS DECIMAL(5, 3))) AS crnd, ROUND(ROUND(41/60*30,3)) AS drnd
출력:
crnd drnd
21 21
나누기 전에 곱하면 부동 소수점을 사용하여 더 정확한 결과를 얻을 수 있습니다.
모두가 지적하고 있는 것처럼 사실이다
부동 소수점 정밀도 문제입니다.
Nick이 제안한 것보다 더 짧고 간단한 회피책(모든 상황에서 효과가 있는지 확실하지 않음)을 발견했을 수 있습니다.우린 뜨는 비율만 캐스팅하고 그게 다...따라서
ROUND(CAST(41/60 AS FLOAT)*30 ,0)
이것은 올바른 결과를 제공한다.
21
그런데 왜 ROUND()가 21과 20을 같은 입력으로 주는지 궁금합니다.누가 가능한 이유를 말해 줄 수 있나요?
언급URL : https://stackoverflow.com/questions/67158065/is-this-a-malfunction-of-the-round-function-in-mariadb
'source' 카테고리의 다른 글
VueJ에서의 HTTP 요청 재귀 전송s (0) | 2022.11.26 |
---|---|
Maria의 JSON 값 비교DB (0) | 2022.11.26 |
지속성 중에 JPA 필드를 무시하는 가장 쉬운 방법은 무엇입니까? (0) | 2022.11.26 |
커스텀 컴퍼레이터를 사용하여 int 배열을 정렬하려면 어떻게 해야 합니까? (0) | 2022.11.26 |
mysql datetime 비교 (0) | 2022.11.25 |