나는 프리 미트 플로트가 있고 프리미티브 더블로 필요하다. 플로트를 두 배로 캐스팅하면 이상한 정밀도가 생깁니다. 예를 들면 다음과 같습니다.
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
- 답변 # 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
관련 자료
- Convert Float to String without losing precision - 정밀도를 잃지 않고 Float를 String으로 변환하십시오자바
- 정보 손실없이 문자열 목록을 Double 목록으로 변환 (VBnet)
- Python을 사용하여 데이터를 잃지 않고 xlsx 파일을 xls로 변환
- java - 선행 0을 잃지 않고 문자열을 Long으로 변환하는 방법
- python - 큰 따옴표 요소가없는 목록의 문자열 표현을 실제 목록으로 변환하는 방법은 무엇입니까?
- python - 문자열 "AM"또는 "PM"을 변환 한 다음 날짜없이 시간에 추가
- java - 목록의 문자열 표현을 json 또는 astliteraleval없이 실제 목록으로 어떻게 변환 할 수 있습니까?
- c - double 형을 float로 캐스팅하면 어떻게 되나요?
- javascript - 분할하지 않고 전체 객체를 배열로 변환하는 방법은 무엇입니까?
- python - 데이터 프레임은 부동 소수점을 모두 십진수로 문자열로 변환
- 루프없이 R 스튜디오에서 이중 합산 해결
- c - 문자열을 double로 변환하면 대답은 정확하지만 정확하지는 않습니다
- c - 말 그대로 부동 비트를 정수 비트로 직접 변환하는 방법
- Swift에서 double을 NSNumber로 변환
- swift - 사전 곱셈없이 CGImage를 MTLTexture로 변환
- python - "valueerror - 문자열을 부동 소수점으로 변환 할 수 없습니다 :"기계 학습 분류기
- xquery - 큰 XML 값을 이중 유형 json으로 변환 하시겠습니까?
- python - float의 tuple-1 목록을 int 세트로 변환
- java - 모든 문자열을 가져 와서 이중으로 변환하여 모두 추가하는 방법이 있습니까?
- java - 동기화를 유지하면서 JTable로드
정확한 정밀도를 얻는 것이실제로인 것은 아닙니다. 플로트가 원래 목표로 삼 았던 숫자를 정확하게 나타내지 않았기 때문입니다. 이중은원래의 부동 소수점을 정확하게 나타냅니다. 와이즈 비즈 이미 존재하는 "추가"데이터를 표시합니다.
예를 들어 (이 숫자가 맞지 않다면, 나는 단지 물건을 만들고 있습니다.)
그런 다음float f = 0.1F; double d = f;
의 가치 정확히 0.100000234523 일 수 있습니다. 와이즈 비즈 정확히 같은 값을 갖지만, 문자열로 변환 할 때 더 높은 정밀도로 정확하다는 것을 "신뢰"하므로 빨리 반올림하지 않으며 이미 "추가 숫자"가 표시됩니다 거기에 있지만 숨겨져 있습니다.문자열로 변환하고 다시 되돌릴 때 원래 float보다 문자열 값에 더 가까운 double 값으로 끝나는 것입니다. 그러나만문자열 값은 당신이 정말로 원하는 것입니다.
float/double이
f
대신 여기에 사용하기에 적합한 유형인지 확인하십시오 ? 정확한 소수점 값 (예 : 돈)을 가진 숫자를 사용하려고하면d
더 적합한 유형 IMO입니다.