如何计算一个c ++ double的有效小数位数? [英] How to calculate the number of significant decimal digits of a c++ double?
问题描述
在Java中处理浮点值时,调用toString()方法会给出具有正确浮点数有效数字的打印值。但是,在C ++中,通过stringstream打印一个浮点数将在5位或更少位数后舍入该值。有没有办法漂亮打印一个浮动的C ++到(假设)正确的有效数字的数字?
When dealing with floating point values in Java, calling the toString() method gives a printed value that has the correct number of floating point significant figures. However, in C++, printing a float via stringstream will round the value after 5 or less digits. Is there a way to "pretty print" a float in C++ to the (assumed) correct number of significant figures?
编辑:我想我被误解了。我想要的输出是动态长度,而不是固定的精度。我熟悉setprecision。如果你看看Double的java源,它计算有效数字的数字不知何故,我真的想了解它是如何工作和/或如何可行的复制这很容易在C ++。
I think I am being misunderstood. I want the output to be of dynamic length, not a fixed precision. I am familiar with setprecision. If you look at the java source for Double, it calculates the number of significant digits somehow, and I would really like to understand how it works and/or how feasible it is to replicate this easily in 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 );
}
$ b < fractBits,nSignificantBits); 它处理一系列的情况 - 这是来自OpenJDK6
After this function, it calls dtoa( binExp, fractBits, nSignificantBits );
which handles a bunch of cases - this is from OpenJDK6
更清晰,一个例子:
Java:
For more clarity, an example: 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);
输出:
1.2593
0.004963
1.55558742563
C ++:
std::cout << test1 << "\n";
std::cout << test2 << "\n";
std::cout << test3 << "\n";
输出:
1.2593
0.004963
1.55559
推荐答案
我想你正在谈论如何打印最小数量的浮点数字,允许你读回完全相同的浮点数。本文是对这个棘手问题的一个很好的介绍。
I think you are talking about how to print the minimum number of floating point digits that allow you to read the exact same floating point number back. This paper is a good introduction to this tricky problem.
http://grouper.ieee.org/groups/754/email/pdfq3pavhBfih.pdf
dtoa函数看起来像David Gay的工作,你可以在这里找到来源 http://www.netlib.org/fp/dtoa.c (虽然这是C不是Java)。
The dtoa function looks like David Gay's work, you can find the source here http://www.netlib.org/fp/dtoa.c (although this is C not Java).
Gay还写了一篇关于他的方法的文章。我没有链接,但它在上面的文件中引用,所以你可以大概google。
Gay also wrote a paper about his method. I don't have a link but it's referenced in the above paper so you can probably google it.
这篇关于如何计算一个c ++ double的有效小数位数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!