Khi xử lý các giá trị dấu phẩy động trong Java, việc gọi phương thức toString() cho một giá trị được in có số lượng dấu phẩy động chính xác. Tuy nhiên, trong C++, việc in phao qua chuỗi sẽ làm tròn giá trị sau 5 hoặc ít hơn chữ số. Có cách nào để "in đẹp" một phao trong C++ đến (giả định) số chính xác của các số liệu quan trọng?Làm thế nào để tính toán số chữ số thập phân có ý nghĩa của một C++ gấp đôi?
EDIT: Tôi nghĩ rằng tôi đang bị hiểu lầm. Tôi muốn đầu ra có độ dài động, không phải độ chính xác cố định. Tôi quen thuộc với việc quyết định. Nếu bạn nhìn vào nguồn java cho Double, nó tính toán số lượng chữ số có nghĩa bằng cách nào đó, và tôi thực sự muốn hiểu nó hoạt động như thế nào và/hoặc khả thi như thế nào để tái tạo điều này một cách dễ dàng trong C++.
/*
* FIRST IMPORTANT CONSTRUCTOR: DOUBLE
*/
public FloatingDecimal(double d)
{
long dBits = Double.doubleToLongBits(d);
long fractBits;
int binExp;
int nSignificantBits;
// discover and delete sign
if ((dBits&signMask) != 0){
isNegative = true;
dBits ^= signMask;
} else {
isNegative = false;
}
// Begin to unpack
// Discover obvious special cases of NaN and Infinity.
binExp = (int)((dBits&expMask) >> expShift);
fractBits = dBits&fractMask;
if (binExp == (int)(expMask>>expShift)) {
isExceptional = true;
if (fractBits == 0L){
digits = infinity;
} else {
digits = notANumber;
isNegative = false; // NaN has no sign!
}
nDigits = digits.length;
return;
}
isExceptional = false;
// Finish unpacking
// Normalize denormalized numbers.
// Insert assumed high-order bit for normalized numbers.
// Subtract exponent bias.
if (binExp == 0){
if (fractBits == 0L){
// not a denorm, just a 0!
decExponent = 0;
digits = zero;
nDigits = 1;
return;
}
while ((fractBits&fractHOB) == 0L){
fractBits <<= 1;
binExp -= 1;
}
nSignificantBits = expShift + binExp +1; // recall binExp is - shift count.
binExp += 1;
} else {
fractBits |= fractHOB;
nSignificantBits = expShift+1;
}
binExp -= expBias;
// call the routine that actually does all the hard work.
dtoa(binExp, fractBits, nSignificantBits);
}
Sau khi chức năng này, nó gọi dtoa(binExp, fractBits, nSignificantBits);
mà xử lý một loạt các trường hợp - đây là từ OpenJDK6
Để rõ ràng hơn, ví dụ: Java:
double test1 = 1.2593;
double test2 = 0.004963;
double test3 = 1.55558742563;
System.out.println(test1);
System.out.println(test2);
System.out.println(test3);
Output :
1.2593
0.004963
1.55558742563
C++:
std::cout << test1 << "\n";
std::cout << test2 << "\n";
std::cout << test3 << "\n";
Output:
1.2593
0.004963
1.55559
Lệnh 'phương pháp toString' không cung cấp cho các "con số chính xác" của số liệu quan trọng; nó không có cách nào biết được số liệu nào là quan trọng. Số dấu phẩy động IEEE không đại diện cho thông tin đó. –
Để tham khảo, đây là một cách tiếp cận Java phổ biến cho [* Tùy chỉnh Định dạng *] (http://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html). – trashgod
Java thực hiện một loạt các phép tính trên giá trị kép khi in - Tôi chỉ không hiểu biết đủ để hiểu nó đang làm gì. Xem chỉnh sửa – dave