Java의 부동 및 이중 데이터 유형


220

float 데이터 형식은 단 정밀도 32 비트 IEEE 754 부동 소수점이고 double 데이터 형식은 배정 밀도 64 비트 IEEE 754 부동 소수점입니다.

무슨 뜻인가요? 그리고 언제 double 대신 float를 사용해야합니까?


8
메모리 사용이 중요한 경우에는 double 대신 float를 사용해야합니다. 보다 정확한 계산이 필요한 경우 복식을 사용하십시오.
Everv0id

12
@ Everv0id : 메모리가 너무 조여서 공간의 정확도를 희생 해야하는 상황은 확실하지 않습니다. (당신은 선을 위해 자바를 사용하고 있습니다 ...) 그것이 요구되는 상황이있을 수 있지만, 실제로는 거의 보지 못했습니다. 이것이 좋은 아이디어라고 생각하는 이유를 자세히 설명하고 싶다면 인스턴스에 대한 답변을 제공하는 것이 좋습니다.
Makoto


5
@Makoto 실제로, 나는 수레를 사용한 적이 없으며 단지 두 배입니다. 그러나 많은 양의 부동 소수점 숫자를 유지해야하는 응용 프로그램 (이론상)이있을 수 있으므로 2 배의 메모리 사용이 중요 할 수 있습니다. 이론적으로, ofc; 실제로 항상 다른 서버를 구입할 수 있습니다 .
Everv0id

3
메모리를 절약하기 위해 4 바이트 및 2 바이트 고정 정밀도 숫자를 사용했지만 수십억 개가 없으면 그만한 가치가 없습니다. "float"대신 "double"을 쓰는 데 걸리는 시간 (문자가 하나 더 있음)은 사용하는 추가 메모리보다 1000 배나 더 가치가 있지만 정밀도 관련 버그를 피하기 double보다는 사용 float하면 가치가 있습니다. .
Peter Lawrey

답변:


259

위키 페이지 그것에는 시작하기에 좋은 장소입니다.

요약하면 :

  • float는 1 비트 비트, 8 비트 지수 및 23 비트의 부호와 함께 32 비트로 표시됩니다 (또는 과학적 표기 번호 : 2.33728 * 10 12 ; 33728은 부호입니다).

  • double 는 1 비트 비트, 11 비트 지수 및 52 비트의 부호를 갖는 64 비트로 표시됩니다.

기본적으로 Java는 double부동 소수점 숫자를 나타 내기 위해 사용 합니다 (따라서 리터럴 3.14은 유형이 지정됨 double). 또한 훨씬 더 큰 숫자 범위를 제공하는 데이터 유형이므로을 (를) 사용하는 것이 좋습니다 float.

특정 실제로 당신의 사용을 강제 라이브러리가있을 수 float있지만, 일반적으로 - 당신이 당신의 결과에 맞게 충분히 작은 될 것이라고 보장 할 수없는 float'의 규정 범위 , 그것은으로 선택하는 것이 가장 좋습니다double .

당신은 정확성이 필요한 경우 - 예를 들어, 당신은 (같은 부정확 진수 값을 가질 수 없습니다 1/10 + 2/10), 또는 당신이하고있는 어떤 (시스템에 $ 10.33를 나타내는 예를 들어,) 통화와, 다음을 사용 BigDecimal를 지원할 수있는을, 임의의 정밀도와 그런 상황을 우아하게 처리합니다.


4
주어진 예에서 233728 == 가수가 아닙니까? 정수 부분이 어디에 저장되어 있습니까?
JaLoveAst1k

1
@ mathguy54 : 과학적 표기법에서 2는 정수 전체이고 .33728은 가수입니다. 여기에 대한 참조가 있습니다.
Makoto

5
나는 수레와 복식에 대한 정보를 찾고 있었고 이것을 발견하고 논평해야했습니다. 소수 센트가 포함되지 않은 통화로 무언가를하고 있다면 BigDecimal을 사용하는 것은 어리 석습니다. 공통 통화는 이산 데이터이므로 정수 데이터 유형을 사용해야합니다. (이것은 젊은 프로그래머들이하는 가장 일반적인 오류 중 하나입니다. 우리는.을 사용하여 센트와 달러를 구분하기 때문에 부동 소수점 값이라고 생각합니다.)
Trixie Wolf

2
@TrixieWolf, 좀 더 구체적으로 말할 수 있습니까? 정수와 소수점 두 개의 정수를 사용하도록 제안 했습니까? 그리고 당신은 공통 통화에 대해 이야기하고 있습니다. 나머지는 어떻습니까? 일부 금액은 소수점 이하 6 자리로 평가되므로 간단히 할 수 없습니다 *100. 여기에 요점이 있지만 더 정확할 수 있습니다 :)
AxelH

9
@AxelH 분수 센트가 존재할 수있는 재무 계산 중간을 제외하고 돈은 항상 이산 적입니다. 하나의 정수 유형을 사용하여 데이터를 저장합니다. 따라서 $ 5.34는 534로 저장됩니다. 달러 부분은 정수 수학에서 val / 100이고, 센트는 정수 수학에서 val % 100입니다. 여기서 %는 나머지 연산을 나타냅니다. 소수점 이하의 장소가 더 많은 돈의 경우, 불연속이기 때문에 여전히 정수로 저장해야합니다. 불 연속적이지 않더라도 대부분 정확한 시간에 반올림 오류로 돈을 잃지 않기 때문에 대부분의 경우 이산 저장소로 돌아가고 싶을 때가 있습니다.
Trixie Wolf

72

플로트는 대략 당신에게 준다. 6 자리는 소수점 이하 7 자리의 정밀도로 약 2 배가됩니다. 15-16. 또한 숫자의 범위는 두 배로 큽니다.

double은 8 바이트의 저장 공간이 필요하지만 float는 4 바이트 만 필요합니다.


13

실수로도 알려진 부동 소수점 숫자는 분수 정밀도가 필요한 표현식을 평가할 때 사용됩니다. 예를 들어, 제곱근과 같은 계산 또는 사인 및 코사인과 같은 초월 계산에는 정밀도에 부동 소수점 유형이 필요한 값이 생성됩니다. Java는 표준 (IEEE–754) 부동 소수점 유형 및 연산자 세트를 구현합니다. 부동 소수점 유형에는 float 및 double의 두 가지 종류가 있으며, 각각 단일 및 배정도 숫자를 나타냅니다. 너비와 범위는 다음과 같습니다.


   Name     Width in Bits   Range 
    double  64              1 .7e308 to 1.7e+308
    float   32              3 .4e038 to 3.4e+038


흙손

float 유형은 32 비트 스토리지를 사용하는 단 정밀도 값을 지정합니다. 단 정밀도는 일부 프로세서에서 더 빠르며 배정 밀도의 절반만큼 공간을 차지하지만 값이 매우 크거나 작 으면 정확하지 않습니다. float 유형의 변수는 분수 구성 요소가 필요할 때 유용하지만 큰 정밀도를 요구하지는 않습니다.

float 변수 선언의 예는 다음과 같습니다.

부유물 고온, 저온;


더블

double 키워드로 표시되는 배정 밀도는 64 비트를 사용하여 값을 저장합니다. 고속 수학적 계산에 최적화 된 일부 최신 프로세서에서는 실제로 배정도가 단 정도보다 빠릅니다. sin (), cos () 및 sqrt ()와 같은 모든 초월 수학 함수는 double 값을 반환합니다. 많은 반복 계산에서 정확도를 유지해야하거나 값이 큰 숫자를 조작하는 경우 double이 가장 좋습니다.


플로트와 더블을 사용해야 할 때 명확하게 설명합니다.
Ye 승리

8
반올림 오류가 발생할 가능성이 있기 때문에 Java의 통화에는 유형 floatdouble유형이 가장 적합 하지 않습니다 . 이 문서에서는 더 자세히로 전환 : javapractices.com/topic/TopicAction.do?Id=13
PPartisan

1
"float는 달러와 센트를 나타낼 때 유용 할 수 있습니다." -아니, 아니, 아니, nononono. 절대로 통화를 플로트 / 더블로 저장하지 마십시오.
활동 감소

2

그럼에도 불구하고 Java는 계산에 double을 사용하는 것에 대한 편견이있는 것 같습니다.

필자가 오늘 앞서 작성한 프로그램에서 float을 사용할 때 메소드가 작동하지 않지만 float을 double로 대체하면 훌륭하게 작동합니다 (NetBeans IDE에서).

package palettedos;
import java.util.*;

class Palettedos{
    private static Scanner Z = new Scanner(System.in);
    public static final double pi = 3.142;

    public static void main(String[]args){
        Palettedos A = new Palettedos();
        System.out.println("Enter the base and height of the triangle respectively");
        int base = Z.nextInt();
        int height = Z.nextInt();
        System.out.println("Enter the radius of the circle");
        int radius = Z.nextInt();
        System.out.println("Enter the length of the square");
        long length = Z.nextInt();
        double tArea = A.calculateArea(base, height);
        double cArea = A.calculateArea(radius);
        long sqArea = A.calculateArea(length);
        System.out.println("The area of the triangle is\t" + tArea);
        System.out.println("The area of the circle is\t" + cArea);
        System.out.println("The area of the square is\t" + sqArea);
    }

    double calculateArea(int base, int height){
        double triArea = 0.5*base*height;
        return triArea;
    }

    double calculateArea(int radius){
        double circArea = pi*radius*radius;
        return circArea;
    }

    long calculateArea(long length){
        long squaArea = length*length;
        return squaArea;
    }
}

나는 오늘 같은 문제가 있었다. 이 편견의 원인은 무엇입니까?
Shachi

2

오류가 발생합니다.

public class MyClass {
    public static void main(String args[]) {
        float a = 0.5;
    }
}

/MyClass.java:3 : 오류 : 호환되지 않는 유형 : double에서 float 로의 손실 가능한 변환 float a = 0.5;

이것은 완벽하게 작동합니다

public class MyClass {
    public static void main(String args[]) {
        double a = 0.5;
    }
}

이것은 또한 완벽하게 작동합니다

public class MyClass {
    public static void main(String args[]) {
        float a = (float)0.5;
    }
}

이유 : Java는 기본적으로 실수를 두 배로 저장하여 정밀도를 높입니다.

Double은 더 많은 공간을 차지하지만 계산 중에는 더 정확하고 float은 더 적은 공간을 차지하지만 덜 정밀합니다.


1

IEEE 표준에 따르면 float는 실수의 32 비트 표현이고 double은 64 비트 표현입니다.

Java 프로그램에서는 일반적으로 이중 데이터 유형이 사용됩니다. double 데이터 형식을 사용하여 수용 할 수있는 숫자 범위가 float을 사용할 때의 범위보다 많기 때문에 오버플로를 피하기 만합니다.

또한 높은 정밀도가 필요한 경우에는 double을 사용하는 것이 좋습니다. 오래 전에 구현 된 라이브러리 메소드 중 일부는 여전히 float 데이터 유형을 필수로 사용해야합니다 (float를 사용하여 구현되었으므로 다른 것은 없습니다!).

그러나 프로그램에 작은 숫자가 필요하고 float를 사용할 때 오버플로가 발생하지 않을 것이라고 확신하는 경우 float를 사용하면 float에 필요한 메모리의 절반이 두 배로 필요하므로 공간 복잡성이 크게 향상됩니다.


0

이 예제는 Java의 float에서 부호 (가장 왼쪽 비트), 지수 (8 다음 비트) 및 가수 (가장 오른쪽 23 비트)를 추출하는 방법을 보여줍니다.

int bits = Float.floatToIntBits(-0.005f);
int sign = bits >>> 31;
int exp = (bits >>> 23 & ((1 << 8) - 1)) - ((1 << 7) - 1);
int mantissa = bits & ((1 << 23) - 1);
System.out.println(sign + " " + exp + " " + mantissa + " " +
  Float.intBitsToFloat((sign << 31) | (exp + ((1 << 7) - 1)) << 23 | mantissa));

더블 (11 비트 지수 및 52 비트 가수)에 대해 동일한 접근 방식을 사용할 수 있습니다.

long bits = Double.doubleToLongBits(-0.005);
long sign = bits >>> 63;
long exp = (bits >>> 52 & ((1 << 11) - 1)) - ((1 << 10) - 1);
long mantissa = bits & ((1L << 52) - 1);
System.out.println(sign + " " + exp + " " + mantissa + " " +
  Double.longBitsToDouble((sign << 63) | (exp + ((1 << 10) - 1)) << 52 | mantissa));

크레딧 : http://sj.github.io/java-float/


0

정확한 계산에는 float 대신 double을 사용하고 덜 정확한 계산에는 double 대신 float를 사용해야합니다. 부동 소수점은 소수만 포함하고 double은 IEEE754 배정 밀도 부동 소수점 숫자를 포함하므로 숫자를보다 정확하게 포함하고 계산할 수 있습니다. 도움이 되었기를 바랍니다.


0

정규 프로그래밍 계산에서는 float을 사용하지 않습니다. 결과 범위가 float 데이터 형식의 범위 내에 있으면 메모리 절약을 위해 float 데이터 형식을 선택할 수 있습니다. 일반적으로 두 가지 이유로 인해 double을 사용합니다.

  • 부동 소수점 숫자를 부동 소수점 데이터 유형으로 사용하려면 기본적으로 모든 부동 소수점 숫자가 두 배로 취급되므로 메소드 호출자는 명시 적으로 F 또는 f 접미 부를 지정해야합니다. 프로그래머의 부담을 증가시킵니다. 부동 소수점 숫자를 이중 데이터 유형으로 사용하는 경우 접미사를 추가 할 필요가 없습니다.
  • 부동 소수점은 단 정밀도 데이터 형식이므로 4 바이트를 차지합니다. 따라서 큰 계산에서는 완전한 결과를 얻지 못할 것입니다. 이중 데이터 유형을 선택하면 8 바이트를 차지하며 완전한 결과를 얻습니다.

float 및 double 데이터 형식은 근사 오차가 허용되는 과학적 계산을 위해 특별히 설계되었습니다. 정확성이 가장 중요한 관심사 인 경우 float 또는 double 데이터 유형 대신 BigDecimal 클래스를 사용하는 것이 좋습니다. 출처 : Java의 부동 및 이중 데이터 유형

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.