-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Allow ties in floating literals #866
Merged
zygoloid
merged 1 commit into
carbon-language:trunk
from
zygoloid:proposal-allow-ties-in-floati
Oct 2, 2021
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
# Allow ties in floating literals | ||
|
||
<!-- | ||
Part of the Carbon Language project, under the Apache License v2.0 with LLVM | ||
Exceptions. See /LICENSE for license information. | ||
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
--> | ||
|
||
[Pull request](https://github.com/carbon-language/carbon-lang/pull/866) | ||
|
||
<!-- toc --> | ||
|
||
## Table of contents | ||
|
||
- [Problem](#problem) | ||
- [Background](#background) | ||
- [Proposal](#proposal) | ||
- [Details](#details) | ||
- [Rationale based on Carbon's goals](#rationale-based-on-carbons-goals) | ||
- [Alternatives considered](#alternatives-considered) | ||
|
||
<!-- tocstop --> | ||
|
||
## Problem | ||
|
||
Proposal [#143](https://github.com/carbon-language/carbon-lang/pull/143) | ||
suggested that we do not allow ties in floating-point literals. That is, given a | ||
literal whose value lies exactly half way between two representable values, we | ||
should reject rather than arbitrarily picking one of the two possibilities. | ||
|
||
However, the [statistical argument](p0143.md#ties) presented in that proposal | ||
misses an important fact: the distribution of the values that are exactly half | ||
way between representable values includes several values of the form A x | ||
10<sup>B</sup>, where A and B are small integers. | ||
|
||
For example, the current rule rejects this very reasonable looking code: | ||
|
||
``` | ||
var v: f32 = 9.0e9; | ||
``` | ||
|
||
... because 9 x 10<sup>9</sup> lies exactly half way between the nearest two | ||
representable values of type `f32`, namely 8999999488 and 9000000512. Similar | ||
examples exist for larger floating point types: | ||
|
||
``` | ||
// Error, half way between two exactly representable values. | ||
var w: f64 = 5.0e22; | ||
``` | ||
|
||
We would also reject an attempted workaround such as: | ||
|
||
``` | ||
var v: f32 = 5 * 1.0e22; | ||
``` | ||
|
||
... because the literal arithmetic would be performed exactly, resulting in the | ||
same tie. A workaround such as | ||
|
||
``` | ||
var v1: f32 = 5.0e22 + 1.0; | ||
var v2: f32 = 5.0e22 - 1.0; | ||
``` | ||
|
||
... to request rounding upwards and downwards, respectively, would work. | ||
However, these seem cumbersome and burden the Carbon developer with | ||
floating-point minutiae about which they very likely do not care. | ||
|
||
## Background | ||
|
||
For background on the ties-to-even rounding rule, see | ||
[this Wikipedia article](https://en.wikipedia.org/wiki/Rounding#Round_half_to_even). | ||
The ties-to-even rule is the default rounding mode specified by ISO 60559 / | ||
IEEE 754. | ||
|
||
## Proposal | ||
|
||
Instead of rejecting exact ties, we use the default IEEE floating point rounding | ||
mode: we round to even. | ||
|
||
## Details | ||
|
||
See design changes. | ||
|
||
## Rationale based on Carbon's goals | ||
|
||
- [Code that is easy to read, understand, and write](/docs/project/goals.md#code-that-is-easy-to-read-understand-and-write) | ||
- This improves the ease of both reading and writing floating-point | ||
literals that would result in ties. | ||
- This improves the language consistency, by performing the same rounding | ||
when converting literals as is performed by default when converting | ||
runtime values. | ||
- [Practical safety and testing mechanisms](/docs/project/goals.md#practical-safety-and-testing-mechanisms) | ||
- It is unlikely that making an arbitrary but consistent rounding choice | ||
will harm safety or program correctness. | ||
- [Fast and scalable development](/docs/project/goals.md#fast-and-scalable-development) | ||
- [Modern OS platforms, hardware architectures, and environments](/docs/project/goals.md#modern-os-platforms-hardware-architectures-and-environments) | ||
- [Interoperability with and migration from existing C++ code](/docs/project/goals.md#interoperability-with-and-migration-from-existing-c-code) | ||
- This rule, likely because it is the IEEE default rounding mode, already | ||
appears to be used by major C++ compilers such as Clang, GCC, MSVC, and | ||
ICC. | ||
|
||
## Alternatives considered | ||
|
||
We could round to even only for decimal floating-point literals, and still use | ||
the rule that ties are rejected for hexadecimal floating point. In the latter | ||
case, a tie means that too many digits were specified, and the trailing digits | ||
were exactly `80000...`. | ||
|
||
However, because we support arithmetic on literals, forming other literals, this | ||
would mean that whether a literal was originally written in hexadecimal would | ||
form part of its value and thereby part of its type. There would also be | ||
problems with literals produced by arithmetic. The complexity involved here far | ||
outweighs any perceived benefit of diagnosing mistyped literals. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, I actually think math between floating point literals is even more important than just removing another way to write this... It seems likely to make it much more likely to encounter. It may not be reasonable to somehow change arithmetic to not produce evenly between values.
Anyways, not disagreeing, just suggesting its even better motivated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I agree that working around such things will be awkward. On the other hand, we'd still need to refute the statistical argument from #143, that such exact ties are unlikely to come up by chance if your computation doesn't put heavy skew into the distribution of resultant mantissas. I don't think it's going to be all that hard to contrive a computation where that'd happen, but I think such easy-to-find examples are likely to amount to computing one of the simple base-10 values that hit this problem or a variant of one of those.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(discussed, and fine to move forward as is for now)