Skip to content
This repository has been archived by the owner on Mar 1, 2024. It is now read-only.

Update calls to round, change signif to round #56

Merged
merged 4 commits into from
Apr 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

This package offers Python-style general formatting and c-style numerical formatting (for speed).

[![Build Status](https://travis-ci.org/JuliaIO/Formatting.jl.svg?branch=master)](https://travis-ci.org/JuliaIO/Formatting.jl)
[![Formatting](http://pkg.julialang.org/badges/Formatting_0.4.svg)](http://pkg.julialang.org/?pkg=Formatting&ver=0.4)
[![Formatting](http://pkg.julialang.org/badges/Formatting_0.5.svg)](http://pkg.julialang.org/?pkg=Formatting&ver=0.5)
[![Formatting](http://pkg.julialang.org/badges/Formatting_0.6.svg)](http://pkg.julialang.org/?pkg=Formatting&ver=0.6)
[![Formatting](http://pkg.julialang.org/badges/Formatting_0.7.svg)](http://pkg.julialang.org/?pkg=Formatting&ver=0.7)

---------------

Expand Down
35 changes: 33 additions & 2 deletions src/fmtcore.jl
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,8 @@ end

function _pfmt_f(out::IO, fs::FormatSpec, x::AbstractFloat)
# separate sign, integer, and decimal part
rax = round(abs(x), fs.prec)
rax = (@static VERSION < v"0.7.0-DEV.4804" ? round(abs(x), fs.prec) :
round(abs(x); digits=fs.prec))
sch = _signchar(x, fs.sign)
intv = trunc(Integer, rax)
decv = rax - intv
Expand Down Expand Up @@ -218,6 +219,36 @@ function _pfmt_floate(out::IO, sch::Char, zs::Integer, u::Real, prec::Int, e::In
end


# Pull in definition of signif from v0.6.2 base, since it is currently broken for
# BigFloat and DecFP (at least) on master

@static if VERSION >= v"0.7.0-DEV.4804"
# adapted from Matlab File Exchange roundsd: http://www.mathworks.com/matlabcentral/fileexchange/26212
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not use the Matlab file exchange. While the original author is required to license their work as BSD, by downloading it from the file exchange you're agreeing to this additional clause in their terms of use:

Content submitted to File Exchange may only be used with MathWorks products.

Besides that, a URL in source code does not satisfy the terms of the BSD license for the original author — that copyright notice should be added or linked to in the LICENSE.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was taken directly from Julia base/floatfunctions.jl (in v0.6.x).
If there is a problem with Julia base, then it should be corrected there as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, indeed. Thanks!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As soon as it is fixed in base (and hopefully supported by Compat.jl), this can be changed to simply call the new form, i.e. round(ax; sigdig=fs.prec + 1).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, glad to see it's being removed. The biggest thing is actually the ToU violation for the person that actually downloaded it, but even then that clause isn't very clear. I just try to stay away from the file exchange, personally.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep - good advice (to stay away from MathWorks).
I hadn't thought about it, since I'd assumed that things in Base had been well vetted.
(and you know what happens when you assume anything!)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found the original change - and it's an ancient one! 5.5 years old, from Sept. 4, 2012 (JuliaLang/julia@4c88c22) by HarlanH, committed by Stefan.
Not sure if the violation is considered to be by the person who made the PR, or the person who actually placed it into the Julia source code against the ToU.

# for round, og is the power of 10 relative to the decimal point
# for signif, og is the absolute power of 10
# digits and base must be integers, x must be convertable to float

function signif(x::Real, digits::Integer, base::Integer=10)
digits < 1 && throw(DomainError())

x = float(x)
(x == 0 || !isfinite(x)) && return x
if base == 10
e = floor(log10(abs(x)) - digits + 1.)
og = oftype(x, exp10(abs(e)))
elseif base == 2
e = exponent(abs(x)) - digits + 1.
og = oftype(x, exp2(abs(e)))
else
e = floor(log(base, abs(x)) - digits + 1.)
og = oftype(x, float(base) ^ abs(e))
end
# for numeric stability
r = e >= 0 ? round(x/og)*og : round(x*og)/og
isfinite(r) ? r : x
end
end

function _pfmt_e(out::IO, fs::FormatSpec, x::AbstractFloat)
# extract sign, significand, and exponent
ax = abs(x)
Expand All @@ -226,7 +257,7 @@ function _pfmt_e(out::IO, fs::FormatSpec, x::AbstractFloat)
e = 0
u = zero(x)
else
rax = signif(ax, fs.prec + 1)
rax = signif(ax, fs.prec + 1) # round(ax; sigdigits = fs.prec + 1)
e = floor(Integer, log10(rax)) # exponent
u = rax * exp10(-e) # significand
end
Expand Down