Float 및 Float 반올림 대신 Double

작 스택

편집 :이 질문은 두 가지 주제를 다룹니다.

  • 플로트 대신 이중 사용의 효율성
  • 반올림 후 부동 정밀도

float 대신 Java double을 항상 사용해서는 안되는 이유가 있습니까?

float를 사용할 때이 테스트 코드가 실패하고 유일한 차이점이 double 대신 float를 사용하는 이유가 명확하지 않기 때문에이 질문을합니다.

public class BigDecimalTest {
@Test public void testDeltaUsingDouble() { //test passes
    BigDecimal left = new BigDecimal("0.99").setScale(2,BigDecimal.ROUND_DOWN);
    BigDecimal right = new BigDecimal("0.979").setScale(2,BigDecimal.ROUND_DOWN);

    Assert.assertEquals(left.doubleValue(), right.doubleValue(), 0.09);
    Assert.assertEquals(left.doubleValue(), right.doubleValue(), 0.03);

    Assert.assertNotEquals(left.doubleValue(), right.doubleValue(), 0.02);
    Assert.assertNotEquals(left.doubleValue(), right.doubleValue(), 0.01);
    Assert.assertNotEquals(left.doubleValue(), right.doubleValue(), 0.0);
}
@Test public void testDeltaUsingFloat() {  //test fails on 'failing assert'

    BigDecimal left = new BigDecimal("0.99").setScale(2,BigDecimal.ROUND_DOWN);
    BigDecimal right = new BigDecimal("0.979").setScale(2,BigDecimal.ROUND_DOWN);

    Assert.assertEquals(left.floatValue(), right.floatValue(), 0.09);
    Assert.assertEquals(left.floatValue(), right.floatValue(), 0.03);

    /* failing assert */ Assert.assertNotEquals(left.floatValue() + " - " + right.floatValue() + " = " + (left.floatValue() - right.floatValue()),left.floatValue(), right.floatValue(), 0.02);
    Assert.assertNotEquals(left.floatValue(), right.floatValue(), 0.01);
    Assert.assertNotEquals(left.floatValue(), right.floatValue(), 0.0);
}}

실패 메시지 :

java.lang.AssertionError: 0.99 - 0.97 = 0.01999998. Actual: 0.9900000095367432
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failEquals(Assert.java:185)
at org.junit.Assert.assertNotEquals(Assert.java:230)
at com.icode.common.BigDecimalTest.testDeltaUsingFloat(BigDecimalTest.java:34)

이 테스트가 실패한 이유와 왜 항상 float 대신 double을 사용해서는 안되는지 아십니까? 물론 double 이외의 이유는 float보다 넓습니다.

편집 : 재미있는 점은 Assert.assertNotEquals (double, double, delta)가 두 경우 모두 두 배를 취하므로 실패한 테스트에서 반환 된 수레가 어쨌든 두 배로 넓어지고 왜 테스트 실패가 발생합니까?

편집 :이 다른 질문이 관련이있을 수 있지만 확실 하지 않습니다 .16 진수가 동일하지 않습니다.

편집 :이 질문에 대한 대답에서 16 진수는 동일하지 않습니다. float에 대한 .99에 대한 과학적 표현 IEEE 754는 동일한 값에 대해 double과 다르다는 결론을 내릴 수 있습니다. 이것은 반올림 때문입니다.

따라서 우리는 이것을 얻습니다.

  • 0.99-0.97 = 0.01999998 // 플로트 케이스
  • 0.99-0.97 = 0.020000000000000018 // 이중 케이스

위의 단위 테스트에서 최대 델타는 0.02이고 (실패한 테스트에서) 0.01999998은 델타 값보다 낮기 때문에 숫자는 동일하지만 테스트에서는 실패하지 않는다고 주장합니다.

이 모든 것에 동의하십니까?

에릭 포스트 피쉴

BigDecimal에 대한 문서floatValue()반올림 방법에 대해 침묵합니다 . 나는 그것이 가장 가깝게, 짝수로 동점을 사용한다고 가정합니다.

left그리고 right각각 0.99와 0.97로 설정됩니다. double가장 가까운 모드 로 변환 하면 결과는 0.9899999999999999911182158029987476766109466552734375 (16 진수 부동 소수점, 0x1.fae147aep-1) 및 0.9699999999999999733546474089962430298328399658203125 (0x1.f0a3d70a3d70ap-1)입니다. 이 값을 빼면 결과는 0.020000000000000017763568394002504646778106689453125로, .02를 분명히 초과합니다.

.99 및 .97을로 변환 float하면 결과는 0.9900000095367431640625 (0x1.fae148p-1) 및 0.9700000286102294921875 (0x1.f0a3d8p-1)입니다. 이 값을 빼면 결과는 0.019999980926513671875로 .02보다 분명히 작습니다.

간단히 말해, 10 진수가 부동 소수점으로 변환 될 때 반올림은 위 또는 아래 일 수 있습니다. 가장 가까운 표현 가능한 부동 소수점 값을 기준으로 숫자가 어디에 놓여 있는지에 따라 다릅니다. 제어되거나 분석되지 않으면 사실상 무작위입니다. 따라서 때로는 예상했던 것보다 더 큰 가치로 끝나고 때로는 더 낮은 가치로 끝나기도합니다.

double대신 사용 한다고해서 위와 유사한 결과 float가 발생 하지 않는다는 보장은 없습니다. double이 경우 값이 정확한 수학적 값을 초과했지만 float값은 그렇지 않은 경우에 불과 합니다. 다른 숫자를 사용하면 반대가 될 수 있습니다. 예를 들어,와 double, .09-.07와,보다 0.02이지만, float.07f`이 0.02보다 크다 - .09f.

Handbook of Floating-Point Arithmetic 과 같이 부동 소수점 산술을 다루는 방법에 대한 많은 정보가 있습니다. Stack Overflow 질문에서 다루기에는 너무 큰 주제입니다. 그것에 대학 과정이 있습니다.

오늘날의 일반적인 프로세서에서는 사용 double하는 데 드는 추가 비용이 거의 없습니다 float. 단순 스칼라 부동 소수점 연산은 double및에 대해 거의 동일한 속도로 수행됩니다 float. 데이터가 너무 많아서 데이터를 전송하는 시간 (디스크에서 메모리로 또는 메모리에서 프로세서로)이 중요해 지거나 디스크에서 차지하는 공간이 커지거나 소프트웨어가 프로세서의 SIMD 기능을 사용하는 경우 성능 차이가 발생합니다. (SIMD를 사용하면 프로세서가 여러 데이터 조각에 대해 병렬로 동일한 작업을 수행 할 수 있습니다. 현재 프로세서는 일반적으로 floatSIMD 작업에 대해 doubleSIMD 작업 에 대해 약 두 배의 대역폭을 제공하거나 doubleSIMD 작업을 전혀 제공하지 않습니다 .)

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

atof () double 대신 float 반환

분류에서Dev

Double 대신 Float를 기반으로 한 Android Opencv

분류에서Dev

Swift에서 double / float 반올림 (2 자리)

분류에서Dev

C ++는 int를 float / double로 어떻게 반올림합니까?

분류에서Dev

char, double 및 float에 대한 올바른 지정자는 무엇입니까?

분류에서Dev

Float 및 Double NaN (Not-a-Number) 값

분류에서Dev

Double 및 Float 공존 구현

분류에서Dev

float128 및 double-double 산술

분류에서Dev

Haskell-Float 및 Double에서 일반화하는 방법

분류에서Dev

int, float, double, long 및 string 간 변환

분류에서Dev

C에서 큰 숫자와 float 및 double

분류에서Dev

float 및 double 변수의 숫자

분류에서Dev

>>에 대한 TypeError on float 및 int

분류에서Dev

C # float.ToString 반올림 값

분류에서Dev

haskell에서 float를 int로 반올림

분류에서Dev

Double을 Float로 또는 그 반대로 수동으로 변환

분류에서Dev

float 및 double 데이터 유형에 대한 프로그래머의 이야기

분류에서Dev

cudaMemcpy double array to float array

분류에서Dev

float == 및! =가 정반대가 아닌 경우

분류에서Dev

Pytorch의 텐서 요소를 "double"대신 "float"유형으로 캐스팅

분류에서Dev

Java-double 및 float percision이 기계에 의존합니까?

분류에서Dev

CUDA의 float1 대 float

분류에서Dev

Float의 Julia 대 Float의 Octave

분류에서Dev

숫자를 문자열로 취하고 float 또는 double을 사용하지 않고 정확한 자릿수로 반올림하는 방법이 있습니까?

분류에서Dev

반올림하지 않고 f-string float 자르기

분류에서Dev

float를 varchar로 변환 할 때 반올림 방지

분류에서Dev

Swift : 값을 반올림하지 않고 float의 문자열

분류에서Dev

float를 다음 홀수 정수로 반올림

분류에서Dev

int에서 float로 변환, 반올림 가능?

Related 관련 기사

  1. 1

    atof () double 대신 float 반환

  2. 2

    Double 대신 Float를 기반으로 한 Android Opencv

  3. 3

    Swift에서 double / float 반올림 (2 자리)

  4. 4

    C ++는 int를 float / double로 어떻게 반올림합니까?

  5. 5

    char, double 및 float에 대한 올바른 지정자는 무엇입니까?

  6. 6

    Float 및 Double NaN (Not-a-Number) 값

  7. 7

    Double 및 Float 공존 구현

  8. 8

    float128 및 double-double 산술

  9. 9

    Haskell-Float 및 Double에서 일반화하는 방법

  10. 10

    int, float, double, long 및 string 간 변환

  11. 11

    C에서 큰 숫자와 float 및 double

  12. 12

    float 및 double 변수의 숫자

  13. 13

    >>에 대한 TypeError on float 및 int

  14. 14

    C # float.ToString 반올림 값

  15. 15

    haskell에서 float를 int로 반올림

  16. 16

    Double을 Float로 또는 그 반대로 수동으로 변환

  17. 17

    float 및 double 데이터 유형에 대한 프로그래머의 이야기

  18. 18

    cudaMemcpy double array to float array

  19. 19

    float == 및! =가 정반대가 아닌 경우

  20. 20

    Pytorch의 텐서 요소를 "double"대신 "float"유형으로 캐스팅

  21. 21

    Java-double 및 float percision이 기계에 의존합니까?

  22. 22

    CUDA의 float1 대 float

  23. 23

    Float의 Julia 대 Float의 Octave

  24. 24

    숫자를 문자열로 취하고 float 또는 double을 사용하지 않고 정확한 자릿수로 반올림하는 방법이 있습니까?

  25. 25

    반올림하지 않고 f-string float 자르기

  26. 26

    float를 varchar로 변환 할 때 반올림 방지

  27. 27

    Swift : 값을 반올림하지 않고 float의 문자열

  28. 28

    float를 다음 홀수 정수로 반올림

  29. 29

    int에서 float로 변환, 반올림 가능?

뜨겁다태그

보관