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

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

서문: 직장에서 소수점을 사용한 덧셈, 뺄셈, 곱셈, 나눗셈을 할 때 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으로 문의하세요.
php怎么将字符串转换成小数php怎么将字符串转换成小数Mar 22, 2023 pm 03:22 PM

PHP 是一门功能强大的编程语言,广泛应用于 Web 开发领域。其中一个非常常见的情况是需要将字符串转换为小数。这在进行数据处理的时候非常有用。在本文中,我们将介绍如何在 PHP 中将字符串转换为小数。

PHP浮点数四舍五入法PHP浮点数四舍五入法Mar 21, 2024 am 09:21 AM

这篇文章将为大家详细讲解有关PHP浮点数四舍五入法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。PHP浮点数四舍五入法概述浮点数在计算机中表示为小数点后跟指数,然而,它们通常以有限位数的近似值存储。当需要将浮点数四舍五入到特定精度时,有几种方法可以实现。方法1.round()函数round()函数将浮点数四舍五入为最接近的整数。它接受浮点数和可选的精度参数。例如:$num=1.55;echoround($num);//输出:2echoround($num,1)

PHP浮点数计算误差原因及避免策略PHP浮点数计算误差原因及避免策略Feb 27, 2024 pm 06:33 PM

PHP作为一种流行的服务器端脚本语言,在进行浮点数计算时常常会遇到精度丢失或计算误差的问题,这些问题可能会对程序的准确性和稳定性造成影响。本文将探讨PHP浮点数计算误差的原因,并提出一些避免策略,同时给出具体的代码示例供参考。1.PHP浮点数计算误差的原因在计算机中,浮点数是以二进制形式表示的,而二进制并不能精确地表示所有的十进制小数,这就导致了浮点数的精

使用strconv.FormatFloat函数将浮点数转换为字符串使用strconv.FormatFloat函数将浮点数转换为字符串Jul 25, 2023 am 11:45 AM

使用strconv.FormatFloat函数将浮点数转换为字符串在Go语言中,我们经常需要将浮点数转换为字符串类型,用于输出或者存储等需求。Go语言中提供了strconv包,其中的FormatFloat函数可以将浮点数转换为字符串类型。FormatFloat函数有三个参数:f表示要转换的浮点数,fmt表示格式,以及prec表示要保留的小数位数。其中,f参数

C++程序将double类型的变量转换为int类型C++程序将double类型的变量转换为int类型Aug 25, 2023 pm 08:25 PM

在C++中,int类型的变量只能保存正整数或负整数值;它们不能保存小数值。有float和double值可用于此目的。为了存储小数点后最多七位的小数,创建了双精度数据类型。整数到双精度数据类型的转换可以由编译器自动完成(称为“隐式”转换),也可以由程序员向编译器显式请求(称为“显式”转换)。在接下来的部分中,我们将介绍各种转换方法。隐式转换编译器自动执行隐式类型转换。要实现这一点,需要两个变量——一个是浮点类型,另一个是整数类型。当我们简单地将浮点值或变量分配给整数变量时,编译器将处理所有其他事情

深入浅出解析PHP BCMath:释放数字运算的潜力深入浅出解析PHP BCMath:释放数字运算的潜力Feb 23, 2024 am 09:10 AM

:一、BCMath简介BCMath是PHP内置的一个扩展库,专门用于处理大型整数和浮点数运算。它提供了丰富的函数来进行加、减、乘、除、平方、开方等各种数学运算,并且支持多种进制的数字表示。二、BCMath的优势BCMath相较于php原生提供的算术运算符和函数,主要有以下几个方面的优势:精度更高:BCMath的运算结果可以保留更多的有效数字,这对于涉及大数计算的场景尤为重要。范围更广:BCMath可以处理比PHP原生数据类型更大的数字,从而避免溢出或精度丢失的问题。功能更丰富:BCMath提供了

如何在PHP中将字符串转换为浮点数如何在PHP中将字符串转换为浮点数Mar 27, 2024 pm 12:48 PM

将字符串转换为浮点数是在PHP中常见的操作,可以通过内置的方法来实现。首先要确保字符串是合法的浮点数格式,才能成功地转换为浮点数。下面将详细介绍如何在PHP中将字符串转换为浮点数,并提供具体的代码示例。一、使用(float)强制转换在PHP中,将字符串转换为浮点数最简单的方式就是使用强制转换。强制转换的方式是在字符串前加上(float)即可,PHP会自动将其

如何使用C#中的Math.Truncate函数对浮点数进行向下取整如何使用C#中的Math.Truncate函数对浮点数进行向下取整Nov 18, 2023 pm 02:02 PM

如何使用C#中的Math.Truncate函数对浮点数进行向下取整,需要具体代码示例在C#编程中,经常会遇到需要对浮点数进行取整的情况。其中,向下取整是一种常见的操作,可以利用C#中的Math.Truncate函数实现。本文将详细介绍Math.Truncate函数的用法,并提供具体的代码示例。Math.Truncate函数是C#中的一个数学函数,用于将一个浮

핫 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 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

에디트플러스 중국어 크랙 버전

에디트플러스 중국어 크랙 버전

작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

SublimeText3 영어 버전

SublimeText3 영어 버전

권장 사항: Win 버전, 코드 프롬프트 지원!

ZendStudio 13.5.1 맥

ZendStudio 13.5.1 맥

강력한 PHP 통합 개발 환경