Java : 이중 값에 대한 정밀도를 설정하는 방법은 무엇입니까? [복제]
이 질문에 이미 답변이 있습니다.
최근에 숫자 작업을했는데 데이터베이스에 저장된 값에 따라 이중 값의 정밀도를 6 자리 또는 4 자리로 설정하고 싶은 상황이있었습니다.
예를 들어, 데이터베이스에서 정밀도가 4 자리로 설정된 경우 출력은 다음과 같아야합니다.
10.0000.
나는 DecimalFormat문자열을 사용해 보았지만 ##.####매번 기호를 사용하는 것은 성가신 일입니다.
더 나은 접근 방법이 있습니까? 다음과 같이 말하십시오.
Double value = 10.0;
value.setPrecision(4);
부동 소수점 값에는 10 진수가 없기 때문에 double (또는 Double)의 정밀도를 지정된 10 진수 숫자로 설정할 수 없습니다. 이진수가 있습니다.
당신은을 통해 중, 진수 기수로 전환해야합니다 BigDecimal또는 DecimalFormat나중에 값으로 수행 할 작업에 따라.
피할 수없는 * 100 / 100 답변에 대한 반박은 이 질문에 대한 나의 답변을 참조하십시오 .
이 목적으로 BigDecimal 을 사용해 볼 수 있습니다.
Double toBeTruncated = new Double("3.5789055");
Double truncatedDouble = BigDecimal.valueOf(toBeTruncated)
.setScale(3, RoundingMode.HALF_UP)
.doubleValue();
이것은 쉽게 할 수있는 방법입니다.
String formato = String.format("%.2f");
정밀도를 2 자리로 설정합니다.
인쇄 만하려면 다음과 같이 사용하십시오.
System.out.printf("%.2f",123.234);
double 값에 대한 정밀도를 설정하는 DecimalFormat것은 좋은 기술입니다. 이 클래스 가져 오기를 사용 java.text.DecimalFormat하고 예를 들어 객체를 생성 하려면
double no=12.786;
DecimalFormat dec = new DecimalFormat("#0.00");
System.out.println(dec.format(no));
따라서 소수점 이하 두 자리를 인쇄합니다. 여기서는 12.79를 인쇄합니다.
이것은 나를 위해 일했습니다.
public static void main(String[] s) {
Double d = Math.PI;
d = Double.parseDouble(String.format("%.3f", d)); // can be required precision
System.out.println(d);
}
다음은 두 가지주의 사항으로 결과를 얻는 효율적인 방법입니다.
- 정밀도를 '최대'N 자리로 제한합니다 (N 자리로 고정되지 않음).
- 숫자를 내림합니다 (가장 가까운 값으로 반올림하지 않음).
여기에서 샘플 테스트 사례를 참조하십시오.
123.12345678 ==> 123.123
1.230000 ==> 1.23
1.1 ==> 1.1
1 ==> 1.0
0.000 ==> 0.0
0.00 ==> 0.0
0.4 ==> 0.4
0 ==> 0.0
1.4999 ==> 1.499
1.4995 ==> 1.499
1.4994 ==> 1.499
여기에 코드가 있습니다. 위에서 언급 한 두 가지주의 사항은 매우 쉽게 해결할 수 있지만 정확도보다 속도가 더 중요했기 때문에 여기에 남겨 두었습니다. 같은 문자열 조작 System.out.printf("%.2f",123.234);은 수학 연산에 비해 계산 비용이 많이 듭니다. 내 테스트에서 아래 코드 (sysout없이)는 문자열 조작에 비해 1/30의 시간이 걸렸습니다.
public double limitPrecision(String dblAsString, int maxDigitsAfterDecimal) {
int multiplier = (int) Math.pow(10, maxDigitsAfterDecimal);
double truncated = (double) ((long) ((Double.parseDouble(dblAsString)) * multiplier)) / multiplier;
System.out.println(dblAsString + " ==> " + truncated);
return truncated;
}
double및 의 정밀도는 float크기와 IEEE 부동 소수점 유형 이 구현 되는 방식으로 고정됩니다 .
반면 출력의 소수 자릿수는 형식화의 문제입니다. 같은 상수를 반복해서 입력하는 것은 나쁜 생각이라는 것이 맞습니다. 대신 문자열 상수를 선언하고 기호 표현을 사용해야합니다.
private static final String DBL_FMT = "##.####";
Using a symbolic representation would let you change precision in all places the constant is used without searching through your code.
BigDecimal value = new BigDecimal(10.0000);
value.setScale(4);
To expand on @EJP, the concept of 'precision' when dealing with doubles is extremely fraught. As discussed in https://stackoverflow.com/a/3730040/390153 you can't even represent 0.1 as a double regardless of the precision, for the same reason you can't represent 1/3 in base 10 with finite precision.
You need to consider the problem you are trying to solve, and consider:
a) Should I be using doubles in the first place; if precision is a relevant concept, then using doubles may well be a mistake.
b) If doubles are appropriate, what do I mean by precision? If you are only talking about display, wrap the logic in a display function and you will only need to deal with it in one place; ie. apply the DRY principle.
Maybe this method would help you for precising double values.
double truncate(double number)
{
int integerPart = (int) number;
double fractionalPart = number - integerPart;
fractionalPart *= 100; //It is for upto two decimal values after point.
//You can increase the zeros to fulfill your needs.
int fractPart = (int) fractionalPart;
fractionalPart = (double) (integerPart) + (double) (fractPart)/100;
return fractionalPart;
}
This method will allow to set the precision level.
double truncate(double number, int precision)
{
double prec = Math.pow(10, precision);
int integerPart = (int) number;
double fractionalPart = number - integerPart;
fractionalPart *= prec;
int fractPart = (int) fractionalPart;
fractionalPart = (double) (integerPart) + (double) (fractPart)/prec;
return fractionalPart;
}
public static String setPrecision(String number, int decimal) {
double nbr = Double.valueOf(number);
int integer_Part = (int) nbr;
double float_Part = nbr - integer_Part;
int floating_point = (int) (Math.pow(10, decimal) * float_Part);
String final_nbr = String.valueOf(integer_Part) + "." + String.valueOf(floating_point);
return final_nbr;
}
I saw the answer at top:
Double toBeTruncated = new Double("3.5789055");
Double truncatedDouble = BigDecimal.valueOf(toBeTruncated)
.setScale(3, RoundingMode.HALF_UP)
.doubleValue();
which I think is not the perfect answer, because the answer will change when you call doubleValue() in many cases.
Example: output of BigDecimal.valueOf(toBeTruncated).setScale(3, RoundingMode.HALF_UP) is 12.500,
then after .doubleValue(), the output will be 12.5 i.e. precision is lost.
Solution: either use BigDecimal type without .doubleValue() method to display, or use string formatting after the final answer.
참고URL : https://stackoverflow.com/questions/14845937/java-how-to-set-precision-for-double-value
'Programing' 카테고리의 다른 글
| Python이 C ++보다 빠르고 가볍습니까? (0) | 2020.09.20 |
|---|---|
| 유닉스 스크립트를 15 초마다 실행하는 방법은 무엇입니까? (0) | 2020.09.20 |
| EC2는 크기를 늘린 후 볼륨 크기를 조정할 수 없습니다. (0) | 2020.09.20 |
| "실행 대상 iOS 장치가 구성표를 실행하는 데 유효하지 않습니다." (0) | 2020.09.20 |
| angular2 제출 버튼없이 Enter를 눌러 양식 제출 (0) | 2020.09.20 |