Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix display of -0.0 to 0.0 #500

Merged
merged 7 commits into from
Dec 14, 2021
Merged

Fix display of -0.0 to 0.0 #500

merged 7 commits into from
Dec 14, 2021

Conversation

lbenet
Copy link
Member

@lbenet lbenet commented Dec 13, 2021

See this comment for the motivation.

@lbenet
Copy link
Member Author

lbenet commented Dec 13, 2021

Example:

# Currently in master
julia> f(x) = 1 - x^4 + x^5
f (generic function with 1 method)

julia> ff = f(0..1)
[-0, 2]

# With this PR
julia> f(x) = 1 - x^4 + x^5
f (generic function with 1 method)

julia> ff = f(0..1)
[0, 2]

@lucaferranti
Copy link
Member

From the printing side great!
Do you think this can close #473 ?

@lbenet
Copy link
Member Author

lbenet commented Dec 13, 2021

Almost, but not quite. The following still doesn't look nice:

julia> interval(0.0, -0.0)
[0, -0]

Maybe having that zero returns always with positive sign is the best.

Other opinions?

@lucaferranti
Copy link
Member

lucaferranti commented Dec 13, 2021

I think calling the _signofzero to the upper bound would fix it?

Regarding the issue I linked: is the -0 vs 0 just a printing thing or do we actually have to make sure that 0 has the bitstring of -0 when it's in the lower bound and the bitstring of +0 when is in the upper bound? This is anyway tangential to this PR

@schillic
Copy link
Contributor

Regarding the issue I linked: is the -0 vs 0 just a printing thing or do we actually have to make sure that 0 has the bitstring of -0 when it's in the lower bound and the bitstring of +0 when is in the upper bound? This is anyway tangential to this PR

I think ±0 are considered identical (two representations of the same number).

julia> x = -0.0
-0.0

julia> y = 0.0
0.0

julia> x < y
false

julia> x > y
false

julia> x == y
true
``

@lucaferranti
Copy link
Member

lucaferranti commented Dec 13, 2021

they have different bit representation

julia> +0.0 === -0.0
false

julia> bitstring(+0.0)
"0000000000000000000000000000000000000000000000000000000000000000"

julia> bitstring(-0.0)
"1000000000000000000000000000000000000000000000000000000000000000"

There are a couple of points in this standard where this small nuisance matters

sec 12.12.8

In formats that have a signed zero, a Level 1 value of 0 shall be returned as −0 by inf, and +0 by all other
functions in this subclause.

hence e.g.

julia> inf(0..0) |> bitstring
"0000000000000000000000000000000000000000000000000000000000000000"

would contradict that point. (That's actually a test in ITF1788)

I would need to double check the ITF1788 testsuite to see if that's the only place where you actually check that you get a -0, but I think it is.

SUMMA SUMMARUM:

  1. This PR normalises the printing, which is good, and I think that mutatis mutandis it can be merged
  2. My comment in that issue (and on that other issue in ITF1788.jl) is that by the standard in some cases (I think only with inf) we need to make sure to actually return the right 0, but this can be addressed also in a separated PR I think.

@lbenet
Copy link
Member Author

lbenet commented Dec 13, 2021

The signed zero is a floating-point arithmetic feature, if i recall correctly, to have a unique answer for the inv function.

@lucaferranti Am I understanding you correct that the interval standard imposes that Interval(0,2) should indeed be displayed as [-0,2]? What about Interval(0.0,0.0)?

(I'm having a busy morning. I'll try to get back to this in the afternoon)

@lucaferranti
Copy link
Member

lucaferranti commented Dec 13, 2021

@lucaferranti Am I understanding you correct that the interval standard imposes that Interval(0,2) should indeed be displayed as [-0,2]? What about Interval(0.0,0.0)?

I doubt it, for example the Octave package also displayes Interval(0, 2) as [0, 2]. The only thing it says is that the function inf should return -0 when called when an interval which has 0 as lower bound value. Here is what the Octave package does

>> a = infsup(0.0, -0.0)
a = [0]
>> b = infsup(0.0, 1.0)
b = [0, 1]
>> c = infsup(-1, -0.0)
c = [-1, 0]
>> inf(a)
ans = 0
>> inf(b)
ans = 0
>> sup(c)
ans = 0
>> format 'bit'
>> inf(a)
ans = 100000000000000000000000000000000000000000000000000
0000000000000
>> inf(b)
ans = 100000000000000000000000000000000000000000000000000
0000000000000
>> sup(a)
ans = 000000000000000000000000000000000000000000000000000
0000000000000
>> sup(c)
ans = 000000000000000000000000000000000000000000000000000
0000000000000

@codecov-commenter
Copy link

codecov-commenter commented Dec 14, 2021

Codecov Report

Merging #500 (8201058) into master (af22f4a) will decrease coverage by 0.14%.
The diff coverage is 87.50%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #500      +/-   ##
==========================================
- Coverage   91.09%   90.94%   -0.15%     
==========================================
  Files          25       25              
  Lines        1785     1789       +4     
==========================================
+ Hits         1626     1627       +1     
- Misses        159      162       +3     
Impacted Files Coverage Δ
src/intervals/intervals.jl 92.53% <75.00%> (+0.34%) ⬆️
src/decorations/functions.jl 93.64% <100.00%> (-1.71%) ⬇️
src/intervals/arithmetic.jl 97.24% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update af22f4a...8201058. Read the comment docs.

@lbenet
Copy link
Member Author

lbenet commented Dec 14, 2021

I think this commit now fixes #473. Using it we have:

julia> -0 .. 0
[0, 0]

julia> dump( -0 .. 0)
Interval{Float64}
  lo: Float64 0.0
  hi: Float64 0.0

julia> dump( 0 .. -0)
Interval{Float64}
  lo: Float64 0.0
  hi: Float64 0.0

julia> inf(0 .. 0)
-0.0

julia> inf(-0 .. 0)
-0.0

julia> sup( -0 .. -0)
0.0

@lucaferranti lucaferranti linked an issue Dec 14, 2021 that may be closed by this pull request
src/intervals/arithmetic.jl Show resolved Hide resolved
src/intervals/intervals.jl Outdated Show resolved Hide resolved
@lucaferranti
Copy link
Member

@lbenet I left a couple of comments but overall LGTM

src/decorations/functions.jl Outdated Show resolved Hide resolved
@lbenet
Copy link
Member Author

lbenet commented Dec 14, 2021

I just pushed a new commit, getting rid of the _normalisezero method that was not used. Indeed, y.lo < 0 seems necessary, as you commented. I think this is ready to be merged!

Thanks a lot @lucaferranti for finding the tiny little uncomfortable issue in the if!!

Copy link
Member

@lucaferranti lucaferranti left a comment

Choose a reason for hiding this comment

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

I think this is ready to be merged too! (maybe bump the patch version?) 🎉

@lbenet
Copy link
Member Author

lbenet commented Dec 14, 2021

Done!

@lbenet
Copy link
Member Author

lbenet commented Dec 14, 2021

Merging...

@lbenet lbenet merged commit 75f53c0 into master Dec 14, 2021
@lbenet lbenet deleted the lb/negativezero branch April 20, 2022 17:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Normalise negative zero to zero
4 participants