왜 긴 타입 캐스트없이 플로트에 저장할 수 있습니다

gmanrocks :

좋아, 그래서 플로트 32 비트 소수점 알고있다. 이중 64 비트 진수입니다. 롱은 64 비트 정수입니다. 왜이 값은 다음과 같습니다 플로트 (32 비트) <- 롱 (64 비트). 분명하지 자바 코드 그러나 나는 자바에서 말하는 겁니다. 그것은 자동적으로는 32 비트로을 대량으로 분석하고 정밀도를 잃는다하더라도 캐스트. 그래서 수단의 정밀도는 중요하지 않습니다. 그러나 INT <- 명시 적으로 int로 더블 캐스팅하지 않는 한 두 번이 작동하지 않습니다. 그것은 작은 크기이며, 그들은 숫자와 모두 원시 상표입니다. 그냥 일반적인 규칙입니다 : 10 진수 번호 <- 전체 수에 관계없이 비트 크기의. 그냥 루프 다시 주위를 것입니다. 그냥 자바에서 숫자 사이의 규칙 및 모든 작동하는지? 실제 코드를 표시하려면 :

long L = 10_000L;
float f = L;

질문에 대해 특별히 유의 longfloat하지, 명시 적 캐스트없이 floatlong하지 명시 적 캐스팅에 대해.

TJ 크라우 :

변환 long하기 floatA는 확대 변환 프리미티브 . 그것은 그런 식으로 정의되어 있기 때문에 ... 자바 오류없이 그것을 할 수 있습니다. 링크에서 :

기본 유형 19 개 특정 변환은 확대 원시적 변환이라고합니다 :

  • byteshort, int, long, float, 또는double

  • shortint, long, float, 또는double

  • charint, long, float, 또는double

  • intlong, float또는double

  • longfloatdouble

...

프리미티브에서 확대 변환 intfloat또는 발 longfloat , 또는 긴에서 이중으로는 정밀도가 손실 될 수있다 즉, 결과 값의 최하위 비트 중 일부를 잃을 수있다 -. 이 경우, 생성 된 부동 소수점 값을 사용하여 상기 정수 값을 정확하게 둥근 버전 것이다 IEEE 754으로 반올림 모드 (§4.2.4).

(내 강조.)

왜 명시 적 캐스트없이 그것을 허용? 일반적으로, 단지 제임스 고슬링 (James Gosling)과이 시간에 다른 질문의 종류를 응답 할 수 있습니다. 우리의 나머지의 경우, 답은 그 사양의 말씀이기 때문.

그러나 , 나는 그것을 허용 왜 내기가 거라고하는 정밀도가 손실 되더라도, 전체 크기가 아니라는 것을 알게 될 것이다. float저장할 수있는 매우 부정확하게 큰 값을. 예를 들어 그래서 :

class Demo {
    public static void main(String[] args) {
        long l = Long.MAX_VALUE;
        float f = l;
        System.out.println(l);
        System.out.println(f);
    }
}

것을 실행하고 당신이 얻을 :

9223372036854775807 
9.223372E18

9.223372e18는 9223372000000000000. 비교한다 :

9223372036854775807 - long 값 
9223372000000000000 - 플로트 값

때문이다 float값의 범위에 대해 정밀도를 희생 할 그것이 지수로 상승하는 기준 값을 저장하기 때문에. 에서 는 IEEE-754 binary32 형식에 대한 위키 백과의 기사 (자바의가 무엇인가 float이다) :

(2 - 2 ... (754)는 IEEE 32 비트베이스 -2- 부동 소수점 변수의 최대 값을 갖는 -23 ) 2 × 127 ≈ 3.402823 × 10 38 ...

× 10 3.402823 (38) 이다 :

340,282,300,000,000,000,000,000,000,000,000,000,000

... 하지만 당신이 일하지 잃게 정밀도를 추가 할 수 있도록 저장할 수있는 가장 높은 정수 단지 2 24 -1 (16777215). 그것은 16,777,216 있지만 16777217 저장할 수 있습니다. 16,777,216 그래서 + 1은 여전히 16,777,216입니다 :

class Demo {
    public static void main(String[] args) {
        float f = 16_777_216f;
        System.out.println(String.format("%8.0f", f));     // 16777216
        System.out.println(String.format("%8.0f", f + 1)); // 16777216 (still)
    }
}

그것은 홀수 이상을 저장할 수 있으므로 지금, 2의 지수에 2 분할베이스 값 저장의 있기 때문에있다. 그것은 16의 다음 8의 다음, 4 만 저장 배수 할 수있는, 더 높은 당신이 얻는 등을 얻는다

a의 값 maxiumum 대조적 long2, 63 "전용"-1을 :

9,223,372,036,854,775,807

그러나 달리 float, 각 정확하게 그 정수 모두를 나타낼 수 있습니다.

추천

출처http://43.154.161.224:23101/article/api/json?id=207968&siteId=1