Displaying numbers in Julia

I want to make a very simple calculation:

julia> 6500 * ( (1.10)^58 )
1.6356451710902702e6

But, the format I’m hoping to for is 1,635,645.17 or 1635645.17.

I spent 10 minutes searching the internet & Julia built in help & couldn’t find an easy way to display something that seems so simple.

Please tell me I’m missing something obvious.

Summary of some proposed solutions:

julia> x = 6500 * ( (1.10)^58 );

julia> using Printf; @printf("%.2f", x)
1635645.17
julia> using Format; format(x; commas=true, precision=2)
"1,635,645.17"

I’m surprised round() doesn’t work here.

I’m concerned that something so simple isn’t automatically possible in Julia w/o calling other packages…

2 Likes

This fine?

julia> using Printf

julia> Base.show(io::IO, f::Float64) = @printf(io, "%.6f", f)

julia> 6500 * ( (1.10)^58 )
1635645.171090

You can then just update the display as needed.

2 Likes

I know that Formatting is deprecated. But you were able to do it with it.

using Formatting
x = 2124313412.1231243
new_value = replace(format(x, commas = true), "," => "_")

which gives “2_124_313_412.123124”

If you only want “,”:

new_value = format(x, commas = true)
1 Like

Pirating Base.show seems too dangerous for me.

Format.jl replaces Formatting.jl.

using Format
julia> format(x; commas=true, precision=2)
"2,124,313,412.12"

Also check out GitHub - ma-laforge/NumericIO.jl: Fine control over numeric output: Scientific/Engineering/SI-notation +UTF8

5 Likes

Ah yea, I thought you wanted to change the default printing of the REPL. But glad that the general approach seemed to help @Albert_Zevelev ! :smiley:

1 Like

To clarify, is there a way for the @printf macro to display commas?

That Printf.jl limitation is solved by Format.jl:

using Format
s = cfmt("%'.2f", 6500 * (1.10)^58) 
"1,635,645.17"
5 Likes

I happened to have this in one of my codes, you’re welcome to use it.

function with_commas(num::AbstractFloat, trunc::Integer=3)
    sig = Int(floor(num))
    frac = (num - sig)
    sig_str = string(sig)
    frac_str = string(frac)[2:2+trunc]
    return replace(sig_str, r"(?<=[0-9])(?=(?:[0-9]{3})+(?![0-9]))" => ",") * frac_str
end

julia> with_commas(1.6356451710902702e6)
"1,635,645.171"

Support ' format flag for @printf · Issue #29077 · JuliaLang/julia · GitHub

This is rooted in C’s printf, and I only did a cursory reading and am uncertain whether the apostrophe flag for a thousands separator is standard or an extension.

Just a note: Printf.jl (or Format.jl) rounds the number instead of truncating.

True enough. I didn’t care about that, but if you do:

function with_commas(num::AbstractFloat, trunc::Integer=3)
    sig = Int(floor(num))
    frac = (num - sig)
    sig_str = string(sig)
    frac_str = string(round(frac, digits=trunc))[2:end]
    return replace(sig_str, r"(?<=[0-9])(?=(?:[0-9]{3})+(?![0-9]))" => ",") * frac_str
end

julia> with_commas(1.6356451710902702e6)
"1,635,645.171"

julia> with_commas(1.6356451715902702e6)
"1,635,645.172"

It’s available…

1 Like

If going in the direction of reimplementing the string formatting instead of installing a package (yet I would think any good implementation is worth sharing as a package), I think changing the number of digits per delimiter, the delimiter character, and the decimal delimiter character can be low-hanging fruit. On the other hand, formats that vary number of digits per delimiter and the delimiter characters by magnitude could be more simply specified by label if finer control would be too complicated.

1 Like

There’s an open PR for this, awaiting review I believe. EDIT: needs a reviewer.

Support the flag ' for thousand separator in Printf, issue #29077 by ki-chi · Pull Request #42145 · JuliaLang/julia (github.com)

1 Like

The floor call leads to some possibly undesirable behaviour:

julia> x = 1.6356451710902702e6
1.6356451710902702e6

julia> with_commas(x)
"1,635,645.171"

julia> with_commas(-x)
"-1,635,646.829"
1 Like

The floor call leads to some possibly undesirable behaviour:

julia> x = 1.6356451710902702e6
1.6356451710902702e6

julia> with_commas(x)
"1,635,645.171"

julia> with_commas(-x)
"-1,635,646.829"

isn’t the solution to check if the number is negative, if so mark a flag then turn the number positive and perform the function then after the function is done add a negative sign to the front of the string if the number is negative?

function with_commas(num::AbstractFloat, trunc::Integer=3)
    negflag = false
    if num < 0
        negflag = true
        num = -1 * num
    end
    sig = Int(floor(num))
    frac = (num - sig)
    sig_str = string(sig)
    frac_str = string(round(frac, digits=trunc))[2:end]
    newstring = replace(sig_str, r"(?<=[0-9])(?=(?:[0-9]{3})+(?![0-9]))" => ",") * frac_str
    if negflag == true
        newstring = "-" * newstring
    end
    return newstring
end
julia> x = 1.6356451710902702e6
1.6356451710902702e6

julia> with_commas(x)
"1,635,645.171"

julia> with_commas(-x)
"-1,635,645.171"
2 Likes

This isn’t optimized for speed (too many allocations…) but it may serve as another base for further optimization and parameters such as different bases, and different separators etc:

function with_commas2(num::AbstractFloat, trunc::Integer=3)
    d,r = divrem(num, 1000)
    s = string(round(r; digits=trunc))
    while d > 0
        d,r = divrem(d, 1000)
        s = string(floor(Int, r))*','*s
    end
    s
end

Also, perhaps truncdigits to match round would be nicer.
On x in the post it is 2x faster.

2 Likes