Re: sprintf() precision arbitrarily at six decimal places?

new topic     » goto parent     » topic index » view thread      » older message » newer message
euphoric said...

Pete, feel free to jump in here. This behavior also occurs with Phix.

You have not actually explained what your problem is:
There are many, many, many different uses of numbers.
Why exactly do you need variable precision outputs?

Anyway, here's what I have:

euphoric said...

What's the best way to insure all decimal places are returned without going scientific notation for very-precise values?

IEEE 754 floats are not exact and hence when using them "all decimal places" is simply meaningless (see link).

atom w = 0.123456789123456789123456789  
--                    ...^^^ ==> ...68(ish) [on 32-bit] 

Phix limits the precision to 16 on 32-bit and 20 on 64-bit, as that is the underlying hardware limit, and which is why sprintf("%0.25f",{w}) yields "0.1234567891234568" on Phix whereas OE yields "0.1234567891234568100000000".

The latter trailing "100000000" is completely meaningless. The definition of atom w rounded the second "678" to "68" plus some random leftover because it is stored in base 2 rather than base 10.

The default precision of sprintf() is 6, whereas the fixed precision of sprint() is 10. Note however that %g does trim trailing zeroes (and sometimes goes all e-notation on you) whereas %f does not.

If you use mpfr you can invoke (eg) mpfr_set_default_prec() to set the precision held.
Note however you are still expected to stipulate the printing precision when invoking mpfr_sprintf(), and that mpfr is an extension of IEEE 754 and hence still technically not exact, just allowing a higher precision/less inaccuracy.

If you use bigatom you can invoke (eg) ba_scale() to set the precision held.
Note however you are still expected to stipulate the printing precision when invoking ba_sprintf(), though it is a bcd-based library and therefore holds eg ba_new("0.123456789123456789123456789") exactly [using a string is deliberate] and ba_sprint() returns "the whole thing", which may be what you are after. It is significantly slower than mpfr though.

I sometimes use ad-hoc routines such as the following to smarten things up:

function smartp(atom N) 
string res 
    if N=floor(N) then return sprintf("%d",N) end if 
    res = sprintf("%12f",round(N,1000000)) 
    if find('.',res) then 
        res = trim_tail(res,"0") 
        res = trim_tail(res,".") 
    end if 
    return res 
end function 

PS: 0.8.0 introduced a new printf settings option, printf(0,"",{"unicode_align",true}) and I could easily add a few other options such as min/max d.p.

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu