>

나는 프리 미트 플로트가 있고 프리미티브 더블로 필요하다. 플로트를 두 배로 캐스팅하면 이상한 정밀도가 생깁니다. 예를 들면 다음과 같습니다.

float temp = 14009.35F;
System.out.println(Float.toString(temp)); // Prints 14009.35
System.out.println(Double.toString((double)temp)); // Prints 14009.349609375

그러나 캐스팅하는 대신 float를 문자열로 출력하고 문자열을 double로 구문 분석하면 원하는 것을 얻습니다.

System.out.println(Double.toString(Double.parseDouble(Float.toString(temp))));
// Prints 14009.35

문자열로 돌아가는 것보다 더 좋은 방법이 있습니까?


  • 답변 # 1

    정확한 정밀도를 얻는 것이실제로인 것은 아닙니다. 플로트가 원래 목표로 삼 았던 숫자를 정확하게 나타내지 않았기 때문입니다. 이중원래의 부동 소수점을 정확하게 나타냅니다. 와이즈 비즈  이미 존재하는 "추가"데이터를 표시합니다.

    예를 들어 (이 숫자가 맞지 않다면, 나는 단지 물건을 만들고 있습니다.)

    toString
    
    
    그런 다음 float f = 0.1F; double d = f; 의 가치  정확히 0.100000234523 일 수 있습니다. 와이즈 비즈  정확히 같은 값을 갖지만, 문자열로 변환 할 때 더 높은 정밀도로 정확하다는 것을 "신뢰"하므로 빨리 반올림하지 않으며 이미 "추가 숫자"가 표시됩니다 거기에 있지만 숨겨져 있습니다.

    문자열로 변환하고 다시 되돌릴 때 원래 float보다 문자열 값에 더 가까운 double 값으로 끝나는 것입니다. 그러나문자열 값은 당신이 정말로 원하는 것입니다.

    float/double이 f 대신 여기에 사용하기에 적합한 유형인지 확인하십시오 ? 정확한 소수점 값 (예 : 돈)을 가진 숫자를 사용하려고하면 d  더 적합한 유형 IMO입니다.

  • 답변 # 2

    이 문제를 파악하기 위해 이진 표현으로 변환하는 것이 더 쉽다는 것을 알았습니다.

    BigDecimal
    
    

    끝에 0을 추가하여 float가 double로 확장 된 것을 볼 수 있지만 0.27의 이중 표현이 '보다 정확'하므로 문제가 있습니다.

    BigDecimal
    
    

  • 답변 # 3

    이것은 float f = 0.27f; double d2 = (double) f; double d3 = 0.27d; System.out.println(Integer.toBinaryString(Float.floatToRawIntBits(f))); System.out.println(Long.toBinaryString(Double.doubleToRawLongBits(d2))); System.out.println(Long.toBinaryString(Double.doubleToRawLongBits(d3))); 의 계약 때문입니다 부분은 다음과 같습니다.

    와이즈 비즈

  • 답변 # 4

    오늘이 문제가 발생하여 프로젝트가 엄청 나기 때문에 BigDecimal에 리팩터링을 사용할 수 없습니다. 그러나 나는

      111110100010100011110101110001
    11111111010001010001111010111000100000000000000000000000000000
    11111111010001010001111010111000010100011110101110000101001000
    
    

    이 작동합니다.

    result.doubleValue ()를 호출하면 5623.22998046875를 반환합니다.

    그러나 doubleResult.doubleValue ()를 호출하면 올바르게 5623.23을 반환합니다.

    그러나 그것이 올바른 해결책인지는 확실하지 않습니다.

  • 답변 # 5

    Float.toString(float) 사용  

    How many digits must be printed for the fractional part […]? There must be at least one digit to represent the fractional part, and beyond that as many,but only as many, more digits as are needed to uniquely distinguish the argument value from adjacent values of type float.That is, suppose that x is the exact mathematical value represented by the decimal representation produced by this method for a finite nonzero argument f. Then f must be the float value nearest to x; or, if two float values are equally close to x, then f must be one of them and the least significant bit of the significand of f must be 0.

    대신 / Float result = new Float(5623.23) Double doubleResult = new FloatingDecimal(result.floatValue()).doubleValue() . 이진 부동 소수점으로 표현할 수없는 숫자가 많이 있습니다 (예 : BigDecimal ). 따라서 항상 결과를 알려진 정밀도로 반올림하거나 float 를 사용해야합니다. .

    자세한 내용은 http://en.wikipedia.org/wiki/Floating_point를 참조하십시오.

    double

관련 자료

  • 이전 c++ - Visual Studio 2012에 라이브러리를 포함시키는 방법은 무엇입니까?
  • 다음 HTTP POST를 사용하여 HTML 및 PHP로 여러 파일을 선택하고 업로드하려면 어떻게해야합니까?