如何用正确的有效十进制数字打印C ++ double? [英] How to print a C++ double with the correct number of significant decimal digits?

查看:86
本文介绍了如何用正确的有效十进制数字打印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 );
}

此函数之后,它调用 dtoa(binExp,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).

盖伊还写了一篇有关他的方法的论文.我没有链接,但上面的文章中已引用它,因此您可以在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆