Hiện nay tôi có phương pháp này:Làm thế nào để kiểm tra xem một đôi có nhiều nhất n chữ số thập phân?
static boolean checkDecimalPlaces(double d, int decimalPlaces){
if (d==0) return true;
double multiplier = Math.pow(10, decimalPlaces);
double check = d * multiplier;
check = Math.round(check);
check = check/multiplier;
return (d==check);
}
Nhưng phương pháp này không cho checkDecmialPlaces(649632196443.4279, 4)
lẽ bởi vì tôi làm cơ sở 10 toán trên cơ sở số 2.
Vậy cách kiểm tra này có thể được thực hiện đúng cách?
Tôi đã nghĩ đến việc biểu diễn chuỗi giá trị kép và sau đó kiểm tra bằng regexp - nhưng điều đó thật lạ.
EDIT: Cảm ơn mọi câu trả lời. Có những trường hợp mà tôi thực sự có được một đôi và đối với những trường hợp tôi thực hiện như sau:
private static boolean checkDecimalPlaces(double d, int decimalPlaces) {
if (d == 0) return true;
final double epsilon = Math.pow(10.0, ((decimalPlaces + 1) * -1));
double multiplier = Math.pow(10, decimalPlaces);
double check = d * multiplier;
long checkLong = (long) Math.abs(check);
check = checkLong/multiplier;
double e = Math.abs(d - check);
return e < epsilon;
}
Tôi đã thay đổi round
đến một cắt ngắn. Dường như việc tính toán được thực hiện trong round
làm tăng sự không chính xác quá nhiều. Ít nhất trong testcase thất bại.
Như một số bạn chỉ ra nếu tôi có thể nhận được vào chuỗi đầu vào 'thực tế' tôi nên sử dụng BigDecimal
để kiểm tra và vì vậy tôi đã thực hiện:
BigDecimal decimal = new BigDecimal(value);
BigDecimal checkDecimal = decimal.movePointRight(decimalPlaces);
return checkDecimal.scale() == 0;
Giá trị double
tôi nhận được xuất phát từ API Apache POI mà đọc các tệp excel. Tôi đã làm một vài xét nghiệm và phát hiện ra rằng mặc dù các API trả về double
giá trị cho các tế bào số tôi có thể có được một đại diện chính xác khi tôi ngay lập tức định dạng mà double
với DecimalFormat
:
DecimalFormat decimalFormat = new DecimalFormat();
decimalFormat.setMaximumIntegerDigits(Integer.MAX_VALUE);
// don't use grouping for numeric-type cells
decimalFormat.setGroupingUsed(false);
decimalFormat.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US));
value = decimalFormat.format(numericValue);
Điều này cũng làm cho các giá trị mà không thể được biểu diễn chính xác ở định dạng nhị phân.
"đúng" không có nghĩa là nhiều đây. Số thập phân ngẫu nhiên của bạn không có biểu diễn nhị phân chính xác. Bạn đang tìm số thập phân "đủ gần" để mọi người thích phiên bản thập phân của giá trị nhị phân. Làm thế nào gần là đủ gần? –