일반적인 문제 이중 부동 소수점 연산이 정밀도를 잃는 이유는 무엇입니까?

이중 부동 소수점 연산이 정밀도를 잃는 이유는 무엇입니까?

Jun 26, 2019 am 09:15 AM
double 부동 소수점 수

이중 부동 소수점 연산이 정밀도를 잃는 이유는 무엇입니까?

서문: 직장에서 소수점을 사용한 덧셈, 뺄셈, 곱셈, 나눗셈을 할 때 BigDecimal을 사용하여 해결하려고 생각하지만 많은 사람들이 double 또는 float가 정밀도를 잃는 이유에 대해 혼란스러워합니다. BigDecimal을 해결하는 방법은 무엇입니까? 더 이상 고민하지 말고 시작해 보겠습니다.

1. 부동소수점 숫자란 무엇인가요?

부동 소수점 숫자는 과학적 표기법을 사용하여 소수를 표현하기 위해 컴퓨터에서 사용하는 데이터 유형입니다. Java에서 double은 배정밀도, 64비트 부동 소수점 숫자이며 기본값은 0.0d입니다. float는 단정밀도, 32비트 부동 소수점 숫자이며 기본값은 0.0f입니다.

이중 부동 소수점 연산이 정밀도를 잃는 이유는 무엇입니까?

메모리에 저장됨

float 부호 비트(1비트) 지수(8비트) 가수(23비트)
이중 부호 비트( 1bit) 지수(11비트) 가수(52비트)


float는 메모리에 8비트의 지수를 가지고 있으므로 지수의 실제 값을 e라고 가정하면 지수 코드는 실제로 지수의 프레임 코드를 저장합니다. 지수 코드는 E이면 E= e+(2^n-1 -1)입니다. 그 중 2^n-1 -1은 IEEE754 표준에서 지정한 지수 오프셋이다. 이 공식에 따르면 2^8 -1=127을 얻을 수 있다. 따라서 float의 지수 범위는 -128 +127이고, double의 지수 범위는 -1024 +1023입니다. 음수 지수는 부동 소수점 숫자가 표현할 수 있는 절대값이 가장 작은 0이 아닌 숫자를 결정하고, 양수 지수는 부동 소수점 숫자가 표현할 수 있는 절대값이 가장 큰 숫자를 결정합니다. 부동 소수점 숫자의 값 범위.


float의 범위는 -2^128 ~ +2^127이며, 이는 -3.40E+38 ~ +3.40E+38입니다.
double의 범위는 -2^1024 ~ +2^1023입니다. -1.79 E+308 ~ +1.79E+308

2. 왜곡의 과학적 표기법에 대해 알아보세요

먼저 과학적 표기법에 대해 이야기해보겠습니다. 자릿수가 많은 숫자, 과학적 표기법은 자릿수가 작은 값에는 장점이 없지만 자릿수가 많은 값의 경우 계산 방법의 장점은 매우 분명합니다. 예를 들어, 빛의 속도는 300000000미터/초이고, 세계 인구는 약 6억100000000명입니다. 빛의 속도와 세계 인구와 같은 큰 숫자는 읽고 쓰기가 매우 불편하므로 빛의 속도는 3*10^8, 세계 인구는 6.1*10^9로 쓸 수 있습니다. 그래서 계산기는 과학적 표기법을 사용하여 빛의 속도가 3E8이고 세계 인구는 약 6.1E9임을 나타냅니다.

어렸을 때 우리는 계산기를 가지고 미친 듯이 덧셈과 뺄셈을 하곤 했습니다. 결국 계산기에는 아래 그림이 표시됩니다. 과학적 표기법으로 표시한 결과입니다

이중 부동 소수점 연산이 정밀도를 잃는 이유는 무엇입니까?

그림의 실제 값은 -4.86*10^11=-486000000000입니다. 소수 과학 표기법에서는 유효 숫자의 정수 부분이 간격 [1, 9] 내에 있어야 합니다.

3. 왜곡의 정확성 알아보기

데이터의 컴퓨터 처리에는 데이터 변환과 다양한 단위 변환, 다양한 진수 변환(예: 이진수 10진수) 등과 같은 다양한 복잡한 작업이 포함됩니다. 예를 들어 10¼3=3.3333...은 끝이 없지만 정확도에는 제한이 있습니다. 3.3333333x3은 10이 아닙니다. 복잡한 처리를 거쳐 얻은 십진수 데이터는 정확도가 높을수록 정확하지 않습니다. 이다. float 및 double의 정확도는 가수의 자릿수에 따라 결정됩니다. 정수 부분은 변경되지 않으므로 항상 암시적 "1"입니다. float: 2^23 = 8388608, 총 7자리입니다. 가장 왼쪽 숫자가 생략되었기 때문에 최대 8자리까지 표현할 수 있다는 뜻입니다: 28388608 = 16777216. 유효 숫자는 8개이지만 절대적으로 7자리가 보장됩니다. 즉, float의 정밀도는 7~8개의 유효 숫자입니다. double: 2^52 = 4503599627370496, 총 16자리, 마찬가지로 double의 정밀도도 마찬가지입니다. 16~17비트입니다.

이중 부동 소수점 연산이 정밀도를 잃는 이유는 무엇입니까?

특정 값에 도달하면 자동으로 과학적 표기법을 사용하기 시작하고 관련 정밀도의 유효 숫자를 유지하므로 결과는 대략적인 숫자이고 지수는 정수입니다. 십진법에서는 일부 소수를 이진법으로 완전히 표현할 수 없습니다. 따라서 제한된 비트로만 표현할 수 있어 저장 시 오류가 발생할 수 있습니다. 십진수를 이진수로 변환하려면 2 곱셈 방법을 사용하여 정수 부분을 제거한 후 소수 부분이 모두 0이 될 때까지 나머지 소수에 2를 계속 곱합니다.

이중 부동 소수점 연산이 정밀도를 잃는 이유는 무엇입니까?

이 0.19999999999999998

인 상황이 발생하면 0.3-0.1을 입력하세요. 연산을 위해서는 0.3을 바이너리로 변환해야 합니다


0.3 * 2 = 0.6 => .0(.6)은 0을 취하고 0.6
0.6 * 2 = 1.2 => .01(.2)은 1을 취하고 0.2를 남깁니다.
0.2 * 2 = 0.4 => .010(.4)은 0을 취하고 0.4
0.4 * 2 = 0.8 => .0100(.8)은 0을 취하고 0.8
0.8 * 2 => 01001 (.6 )은 1을 취하고 0.6을 남깁니다
..............

이중 부동 소수점 연산이 정밀도를 잃는 이유는 무엇입니까?

3. 요약

위 내용을 읽고 나면 부동 소수점 숫자가 왜 정확성을 갖는지 분명해질 것입니다. 문제. 간단히 말해서, float 및 double 유형은 주로 과학적 계산 및 공학적 계산을 위해 설계되었습니다. 이 유형은 광범위한 값에 대해 보다 정확하고 빠른 근사 합계 계산을 제공하도록 신중하게 설계된 이진 부동 소수점 연산을 수행합니다. 그러나 완전히 정확한 결과를 제공하지는 않으며 정확한 결과를 위해 사용해서는 안 됩니다. 특정 크기에 도달하는 부동 소수점 숫자는 자동으로 과학적 표기법을 사용합니다. 이러한 표현은 실수의 근사치일 뿐 실수와 동일하지 않습니다. 10진수를 2진수로 변환하면 무한루프가 발생하거나 부동소수점 가수의 길이를 초과하게 됩니다.

4 그렇다면 BigDecimal을 사용하여 어떻게 해결할 수 있을까요?

아래 두 출력을 보세요

이중 부동 소수점 연산이 정밀도를 잃는 이유는 무엇입니까?

출력 결과

0.2999999999999998889 7 769753748434595763683319091796875#🎜🎜 #0.3

사진 속 알리바바의 코드 제약 플러그인은 경고를 표시하고 BigDecimal을 생성하려면 문자열 매개변수의 생성 방법을 사용하라고 요청했습니다. double은 정확히 0.3(유한 길이의 이진수)으로 표현될 수 없기 때문에 생성자가 전달한 값은 정확히 0.3과 같지 않습니다. BigDecimal을 사용하는 경우 String 매개변수의 생성자 메서드를 사용하여 생성해야 합니다. 그런데 궁금한 아기들이 있는데 BigDecimal의 원리는 무엇인가요? 왜 문제가 없나요? 실제로 원리는 매우 간단합니다. BigDecimal은 불변이며 모든 정밀도의 부호 있는 십진수를 나타내는 데 사용할 수 있습니다. double의 문제는 소수점이 이진수로 변환되어 정밀도가 손실되기 때문입니다. 처리 중에 BigDecimal은 정수로 계산할 수 있고 해당 정밀도 정보를 유지할 수 있도록 십진수를 N배로 확장합니다. BigDecimal이 어떻게 저장되는지는 소스 코드를 읽을 수 있습니다.

자주 묻는 질문(FAQ)과 관련된 기술 관련 기사를 더 보려면

FAQ 열을 방문하여 자세히 알아보세요!

위 내용은 이중 부동 소수점 연산이 정밀도를 잃는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

PHP에서 문자열을 10진수로 변환하는 방법 PHP에서 문자열을 10진수로 변환하는 방법 Mar 22, 2023 pm 03:22 PM

PHP는 웹 개발 분야에서 널리 사용되는 강력한 프로그래밍 언어입니다. 매우 일반적인 상황 중 하나는 문자열을 10진수로 변환해야 하는 경우입니다. 이는 데이터 처리를 할 때 매우 유용합니다. 이번 글에서는 PHP에서 문자열을 10진수로 변환하는 방법을 설명하겠습니다.

PHP 부동 소수점 수 반올림 방법 PHP 부동 소수점 수 반올림 방법 Mar 21, 2024 am 09:21 AM

이 글은 PHP 부동 소수점 숫자 반올림 방법에 대해 자세히 설명할 것입니다. 편집자는 이것이 매우 실용적이라고 생각하므로 이 글을 읽고 뭔가를 얻을 수 있기를 바랍니다. PHP 부동 소수점 반올림 개요 부동 소수점 숫자는 컴퓨터에서 소수점 뒤에 지수가 오는 형식으로 표시되지만 제한된 자릿수의 근사값으로 저장되는 경우가 많습니다. 부동 소수점 숫자를 특정 정밀도로 반올림해야 하는 경우 여러 가지 방법으로 이를 수행할 수 있습니다. 방법 1. round() 함수 round() 함수는 부동 소수점 숫자를 가장 가까운 정수로 반올림합니다. 부동 소수점 숫자와 선택적 정밀도 매개변수를 허용합니다. 예: $num=1.55;echoround($num);//출력: 2echoround($num,1)

Jul 25, 2023 am 11:45 AM

strconv.FormatFloat 함수를 사용하여 부동 소수점 숫자를 문자열로 변환합니다. Go 언어에서는 출력이나 저장 요구에 따라 부동 소수점 숫자를 문자열 유형으로 변환해야 하는 경우가 많습니다. strconv 패키지는 Go 언어로 제공되며, 여기에 포함된 FormatFloat 함수는 부동 소수점 숫자를 문자열 유형으로 변환할 수 있습니다. FormatFloat 함수는 세 가지 매개변수를 사용합니다. f는 변환할 부동 소수점 숫자를 나타내고, fmt는 형식을 나타내고, prec는 유지할 소수 자릿수를 나타냅니다. 그 중 f 매개변수는

double 유형 변수를 int 유형으로 변환하는 C++ 프로그램 double 유형 변수를 int 유형으로 변환하는 C++ 프로그램 Aug 25, 2023 pm 08:25 PM

C++에서 int 유형의 변수는 양수 또는 음수 정수 값만 보유할 수 있으며 소수 값은 보유할 수 없습니다. 이를 위해 float 및 double 값을 사용할 수 있습니다. double 데이터형은 소수점 이하 7자리까지 소수점 이하 자릿수를 저장하기 위해 만들어졌습니다. 정수를 double 데이터 형식으로 변환하는 것은 컴파일러에 의해 자동으로 수행되거나("암시적" 변환이라고 함) 프로그래머가 컴파일러에서 명시적으로 요청할 수 있습니다("명시적" 변환이라고 함). 다음 섹션에서는 다양한 변환 방법을 다룹니다. 암시적 변환 컴파일러는 암시적 유형 변환을 자동으로 수행합니다. 이를 달성하려면 부동 소수점 유형과 정수 유형의 두 가지 변수가 필요합니다. 단순히 부동 소수점 값이나 변수를 정수 변수에 할당하면 컴파일러가 다른 모든 사항을 처리합니다.

PHP 부동 소수점 계산 오류의 원인과 방지 전략 PHP 부동 소수점 계산 오류의 원인과 방지 전략 Feb 27, 2024 pm 06:33 PM

널리 사용되는 서버 측 스크립팅 언어인 PHP는 부동 소수점 계산을 수행할 때 정밀도 손실이나 계산 오류 문제에 직면하는 경우가 많습니다. 이러한 문제는 프로그램의 정확성과 안정성에 영향을 미칠 수 있습니다. 이 기사에서는 PHP 부동 소수점 계산 오류의 원인을 살펴보고, 몇 가지 방지 전략을 제안하고, 참조할 수 있는 특정 코드 예제를 제공합니다. 1. PHP 부동 소수점 계산 오류의 원인 컴퓨터에서 부동 소수점 숫자는 이진수 형식으로 표시되며, 이진수는 모든 십진수를 정확하게 나타낼 수 없으므로 부동 소수점 숫자가 부정확해집니다.

PHP BCMath에 대한 심층 설명: 숫자 연산의 잠재력 활용 PHP BCMath에 대한 심층 설명: 숫자 연산의 잠재력 활용 Feb 23, 2024 am 09:10 AM

:1. BCMath 소개 BCMath는 PHP에 내장된 확장 라이브러리로, 특히 큰 정수 및 부동 소수점 연산을 처리하는 데 사용됩니다. 덧셈, 뺄셈, 곱셈, 나눗셈, 제곱, 제곱근 등 다양한 수학 연산을 수행할 수 있는 풍부한 기능을 제공하며 다진수에서의 디지털 표현을 지원합니다. 2. BCMath의 장점 PHP에서 기본적으로 제공하는 산술 연산자 및 함수와 비교할 때 BCMath는 주로 다음과 같은 장점을 가지고 있습니다. 더 높은 정밀도: BCMath의 연산 결과는 더 많은 유효 자릿수를 유지할 수 있으며 이는 큰 숫자와 관련된 계산에 특히 중요합니다. 더 넓은 범위: BCMath는 PHP의 기본 데이터 유형보다 더 큰 숫자를 처리할 수 있으므로 오버플로나 정밀도 손실 문제를 방지할 수 있습니다. 더욱 풍부한 기능: BCMath는 다음을 제공합니다.

C#에서 Math.Round 함수를 사용하여 부동 소수점 숫자 반올림 C#에서 Math.Round 함수를 사용하여 부동 소수점 숫자 반올림 Nov 18, 2023 pm 02:17 PM

C#에서 Math.Round 함수를 사용하여 부동 소수점 숫자를 반올림하려면 특정 코드 예제가 필요합니다. C# 프로그래밍 언어에서는 부동 소수점 숫자를 반올림해야 하는 경우가 있습니다. 이때 Math.Round 함수를 사용하여 이 기능을 구현할 수 있습니다. Math.Round 함수는 수학적 계산에 사용되는 C#의 내장 함수입니다. 주요 함수는 지정된 부동 소수점 숫자를 반올림하는 것입니다. 다음은 Math.Round 함수의 일반적인 형식입니다. Math.Round(doub

PHP에서 문자열을 부동 소수점으로 변환하는 방법 PHP에서 문자열을 부동 소수점으로 변환하는 방법 Mar 27, 2024 pm 12:48 PM

문자열을 부동 소수점 숫자로 변환하는 것은 PHP에서 일반적인 작업이며 내장된 메서드를 통해 수행할 수 있습니다. 먼저 문자열이 부동 소수점 숫자로 성공적으로 변환되기 전에 올바른 부동 소수점 형식인지 확인하십시오. 다음은 PHP에서 문자열을 부동 소수점 숫자로 변환하는 방법을 자세히 소개하고 구체적인 코드 예제를 제공합니다. 1. (부동) 캐스트 사용 PHP에서 문자열을 부동 소수점 숫자로 변환하는 가장 간단한 방법은 캐스트를 사용하는 것입니다. 강제 변환하는 방법은 문자열 앞에 (float)을 추가하는 것이며, PHP가 자동으로 변환합니다.