Skip to content

float: Replace some approximate assertions with exact #141669

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

Merged
merged 4 commits into from
May 30, 2025

Conversation

tgross35
Copy link
Contributor

@tgross35 tgross35 commented May 28, 2025

As was mentioned at 1, we currently use assert_approx_eq for testing
some math functions that guarantee exact results. Replace approximate
assertions with exact ones for the following:

  • ceil
  • floor
  • fract
  • from_bits
  • mul_add
  • round_ties_even
  • round
  • trunc

This likely wasn't done in the past to avoid writing out exact decimals
that don't match the intuitive answer (e.g. 1.3 - 1.0 = 0.300...004),
but ensuring our results are accurate seems more important here.

The first commit is a small bit of macro cleanup.

try-job: aarch64-gnu
try-job: x86_64-gnu-aux

cc @beetrees as you suggested this

@rustbot rustbot added the T-libs Relevant to the library team, which will review and decide on the PR/issue. label May 28, 2025
@tgross35
Copy link
Contributor Author

@bors try

@bors
Copy link
Collaborator

bors commented May 28, 2025

⌛ Trying commit f12c89e with merge 6f9d015...

bors added a commit that referenced this pull request May 28, 2025
float: Replace some approximate assertions with exact

As was mentioned at [1], we currently use `assert_approx_eq` for testing
some math functions that guarantee exact results. Replace approximate
assertions with exact ones for the following:

* `ceil`
* `floor`
* `fract`
* `from_bits`
* `mul_add`
* `round_ties_even`
* `round`
* `trunc`

This likely wasn't done in the past to avoid writing out exact decimals
that don't match the intuitive answer (e.g. 1.3 - 1.0 = 0.300...004),
but ensuring our results are accurate seems more important here.

[1]: #138087 (comment)

The first commit is a small bit of macro cleanup.

try-job: aarch64-gnu
@tgross35 tgross35 marked this pull request as ready for review May 28, 2025 01:43
@rustbot
Copy link
Collaborator

rustbot commented May 28, 2025

r? @Mark-Simulacrum

rustbot has assigned @Mark-Simulacrum.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 28, 2025
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@bors
Copy link
Collaborator

bors commented May 28, 2025

💔 Test failed - checks-actions

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 28, 2025
@tgross35
Copy link
Contributor Author

tgross35 commented May 28, 2025

@beetrees any idea what is going on here? It looks like the f128 fma and frac tests aren't giving the expected results with clif.

@tgross35
Copy link
Contributor Author

@bors try

bors added a commit that referenced this pull request May 28, 2025
float: Replace some approximate assertions with exact

As was mentioned at [1], we currently use `assert_approx_eq` for testing
some math functions that guarantee exact results. Replace approximate
assertions with exact ones for the following:

* `ceil`
* `floor`
* `fract`
* `from_bits`
* `mul_add`
* `round_ties_even`
* `round`
* `trunc`

This likely wasn't done in the past to avoid writing out exact decimals
that don't match the intuitive answer (e.g. 1.3 - 1.0 = 0.300...004),
but ensuring our results are accurate seems more important here.

[1]: #138087 (comment)

The first commit is a small bit of macro cleanup.

try-job: aarch64-gnu
@bors
Copy link
Collaborator

bors commented May 28, 2025

⌛ Trying commit b94d32e with merge f2c471b...

@bors
Copy link
Collaborator

bors commented May 28, 2025

☀️ Try build successful - checks-actions
Build commit: f2c471b (f2c471b102998ac17e9717af5c6da4647473717b)

@tgross35 tgross35 force-pushed the float-test-cleanup branch from b94d32e to 04570ba Compare May 28, 2025 22:39
@tgross35
Copy link
Contributor Author

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 28, 2025
@@ -260,98 +249,98 @@ fn test_classify() {
#[cfg(not(miri))]
Copy link
Member

Choose a reason for hiding this comment

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

Miri has f16 and f128 implementations for all the rounding functions by now -- I don't think there's still a good reason for these tests to be disabled in Miri?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not at all, I just wasn't aware of the change. I added 2e4824d to remove the #[cfg].

(which try job runs miri again?)

Copy link
Member

Choose a reason for hiding this comment

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

(which try job runs miri again?)

The gnu-aux one.

Comment on lines 242 to 243
assert_eq!(0.0f16.floor(), 0.0f16);
assert_eq!((-0.0f16).floor(), -0.0f16);
Copy link
Member

Choose a reason for hiding this comment

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

This test does not compare the sign since == ignores the sign of 0 -- that's pre-existing, but likely unintentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're very right. I added 0a87911 to just switch everything to assert_biteq which should catch things like this, since I don't think there is any downside.

@@ -257,114 +247,107 @@ fn test_classify() {
}

#[test]
#[cfg(not(miri))]
#[cfg(target_has_reliable_f128_math)]
Copy link
Member

Choose a reason for hiding this comment

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

Ideally this would become any(miri, target_has_reliable_f128_math) since f16/f128 math is always reliable with Miri... not sure if that's worth the churn though.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Might as well since I'm updating those configs anyway :) Done in a fixup

@@ -71,23 +60,23 @@ fn test_num_f128() {
fn test_num_f128_rem() {
let ten = 10f128;
let two = 2f128;
assert_eq!(ten.rem(two), ten % two);
assert_biteq!(ten.rem(two), ten % two);
}

#[test]
#[cfg(not(miri))]
#[cfg(target_has_reliable_f128_math)]
fn test_min_nan() {
Copy link
Member

Choose a reason for hiding this comment

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

min and max (and minimum and maximum) should also work in miri for f16 and f128

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated. powi, fma, and sqrt all still do not work, correct?

Copy link
Member

Choose a reason for hiding this comment

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

Correct (though they'd be fairly easy to add :)

@@ -71,23 +60,23 @@ fn test_num_f128() {
fn test_num_f128_rem() {
let ten = 10f128;
let two = 2f128;
assert_eq!(ten.rem(two), ten % two);
assert_biteq!(ten.rem(two), ten % two);
Copy link
Member

Choose a reason for hiding this comment

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

Isn't rem the same as %? I'm a bit confused by the test.^^

Anyway I think this always worked in Miri ever nice basic arithmetic worked, there's no intrinsics involved here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This test came from

pub fn test_num<T>(ten: T, two: T)
where
T: PartialEq
+ Add<Output = T>
+ Sub<Output = T>
+ Mul<Output = T>
+ Div<Output = T>
+ Rem<Output = T>
+ fmt::Debug
+ Copy,
{
assert_eq!(ten.add(two), ten + two);
assert_eq!(ten.sub(two), ten - two);
assert_eq!(ten.mul(two), ten * two);
assert_eq!(ten.div(two), ten / two);
assert_eq!(ten.rem(two), ten % two);
}
, indeed it is a bit dubious. I don't see anything else that exercises Rem but that would probably be something good to have.

@rust-log-analyzer

This comment has been minimized.

@bors

This comment was marked as outdated.

bors added a commit that referenced this pull request May 29, 2025
float: Replace some approximate assertions with exact

As was mentioned at [1], we currently use `assert_approx_eq` for testing
some math functions that guarantee exact results. Replace approximate
assertions with exact ones for the following:

* `ceil`
* `floor`
* `fract`
* `from_bits`
* `mul_add`
* `round_ties_even`
* `round`
* `trunc`

This likely wasn't done in the past to avoid writing out exact decimals
that don't match the intuitive answer (e.g. 1.3 - 1.0 = 0.300...004),
but ensuring our results are accurate seems more important here.

[1]: #138087 (comment)

The first commit is a small bit of macro cleanup.

try-job: aarch64-gnu
try-job: gnu-aux
@rust-log-analyzer

This comment was marked as outdated.

@tgross35
Copy link
Contributor Author

🤦
@bors try

@bors
Copy link
Collaborator

bors commented May 29, 2025

⌛ Trying commit 9c047e7 with merge a609092...

bors added a commit that referenced this pull request May 29, 2025
float: Replace some approximate assertions with exact

As was mentioned at [1], we currently use `assert_approx_eq` for testing
some math functions that guarantee exact results. Replace approximate
assertions with exact ones for the following:

* `ceil`
* `floor`
* `fract`
* `from_bits`
* `mul_add`
* `round_ties_even`
* `round`
* `trunc`

This likely wasn't done in the past to avoid writing out exact decimals
that don't match the intuitive answer (e.g. 1.3 - 1.0 = 0.300...004),
but ensuring our results are accurate seems more important here.

[1]: #138087 (comment)

The first commit is a small bit of macro cleanup.

try-job: aarch64-gnu
try-job: x86_64-gnu-aux
@bors
Copy link
Collaborator

bors commented May 29, 2025

☀️ Try build successful - checks-actions
Build commit: a609092 (a6090927d4f33b36e2998fdaa6d76908ba43c50e)

@tgross35 tgross35 force-pushed the float-test-cleanup branch from 9c047e7 to 9f9ac74 Compare May 29, 2025 17:43
@tgross35
Copy link
Contributor Author

Cleaned up history a bit.

Considering you've already looked at this and other float tests, r? @RalfJung

@rustbot rustbot assigned RalfJung and unassigned Mark-Simulacrum May 29, 2025
@RalfJung
Copy link
Member

Thanks! r=me after squashing

tgross35 added 4 commits May 29, 2025 21:13
Clean up the separate `assert_f{16,32,64,128}` macros with a single
`assert_biteq!` macro that works for all float widths.
As was mentioned at [1], we currently use `assert_approx_eq` for testing
some math functions that guarantee exact results. Replace approximate
assertions with exact ones for the following:

* `ceil`
* `floor`
* `fract`
* `from_bits`
* `mul_add`
* `round_ties_even`
* `round`
* `trunc`

This likely wasn't done in the past to avoid writing out exact decimals
that don't match the intuitive answer (e.g. 1.3 - 1.0 = 0.300...004),
but ensuring our results are accurate seems more important here.

[1]: rust-lang#138087 (comment)
The rounding tests are now supported, so there is no longer any reason
to skip these.
`assert_eq!` ignores the sign of zero, but for any tests involving zeros
we do care about this sign. Replace `assert_eq!` with `assert_biteq!`
everywhere possible for float tests to ensure we don't miss this.
`assert_biteq!` is also updated to check equality on non-NaNs, to catch
the unlikely case that bitwise equality works but our `==`
implementation is broken.

There is one notable output change: we were asserting that
`(-0.0).fract()` and `(-1.0).fract()` both return -0.0, but both
actually return +0.0.
@tgross35 tgross35 force-pushed the float-test-cleanup branch from 7de59e6 to 70cce1c Compare May 29, 2025 21:13
@tgross35
Copy link
Contributor Author

Thank you!
@bors r=RalfJung

@bors
Copy link
Collaborator

bors commented May 29, 2025

📌 Commit 70cce1c has been approved by RalfJung

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 29, 2025
bors added a commit that referenced this pull request May 30, 2025
Rollup of 8 pull requests

Successful merges:

 - #133823 (Use `cfg_attr_trace` in AST with a placeholder attribute for accurate suggestion)
 - #141004 (Report text_direction_codepoint_in_literal when parsing)
 - #141407 (Refactor the two-phase check for impls and impl items)
 - #141430 (remove `visit_clobber` and move `DummyAstNode` to `rustc_expand`)
 - #141507 (atomic_load intrinsic: use const generic parameter for ordering)
 - #141538 (implement `va_arg` for x86_64 systemv)
 - #141669 (float: Replace some approximate assertions with exact)
 - #141747 (rustdoc: display doc(cfg(false)) properly)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 3ebdd59 into rust-lang:master May 30, 2025
9 checks passed
@rustbot rustbot added this to the 1.89.0 milestone May 30, 2025
rust-timer added a commit that referenced this pull request May 30, 2025
Rollup merge of #141669 - tgross35:float-test-cleanup, r=RalfJung

float: Replace some approximate assertions with exact

As was mentioned at [1], we currently use `assert_approx_eq` for testing
some math functions that guarantee exact results. Replace approximate
assertions with exact ones for the following:

* `ceil`
* `floor`
* `fract`
* `from_bits`
* `mul_add`
* `round_ties_even`
* `round`
* `trunc`

This likely wasn't done in the past to avoid writing out exact decimals
that don't match the intuitive answer (e.g. 1.3 - 1.0 = 0.300...004),
but ensuring our results are accurate seems more important here.

[1]: #138087 (comment)

The first commit is a small bit of macro cleanup.

try-job: aarch64-gnu
try-job: x86_64-gnu-aux
@tgross35 tgross35 deleted the float-test-cleanup branch May 30, 2025 14:36
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request May 31, 2025
Rollup of 8 pull requests

Successful merges:

 - rust-lang/rust#133823 (Use `cfg_attr_trace` in AST with a placeholder attribute for accurate suggestion)
 - rust-lang/rust#141004 (Report text_direction_codepoint_in_literal when parsing)
 - rust-lang/rust#141407 (Refactor the two-phase check for impls and impl items)
 - rust-lang/rust#141430 (remove `visit_clobber` and move `DummyAstNode` to `rustc_expand`)
 - rust-lang/rust#141507 (atomic_load intrinsic: use const generic parameter for ordering)
 - rust-lang/rust#141538 (implement `va_arg` for x86_64 systemv)
 - rust-lang/rust#141669 (float: Replace some approximate assertions with exact)
 - rust-lang/rust#141747 (rustdoc: display doc(cfg(false)) properly)

r? `@ghost`
`@rustbot` modify labels: rollup
github-actions bot pushed a commit to model-checking/verify-rust-std that referenced this pull request Jun 3, 2025
…fJung

float: Replace some approximate assertions with exact

As was mentioned at [1], we currently use `assert_approx_eq` for testing
some math functions that guarantee exact results. Replace approximate
assertions with exact ones for the following:

* `ceil`
* `floor`
* `fract`
* `from_bits`
* `mul_add`
* `round_ties_even`
* `round`
* `trunc`

This likely wasn't done in the past to avoid writing out exact decimals
that don't match the intuitive answer (e.g. 1.3 - 1.0 = 0.300...004),
but ensuring our results are accurate seems more important here.

[1]: rust-lang#138087 (comment)

The first commit is a small bit of macro cleanup.

try-job: aarch64-gnu
try-job: x86_64-gnu-aux
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants