reem / rust-ordered-float Goto Github PK
View Code? Open in Web Editor NEWLicense: MIT License
License: MIT License
If this is a good idea, I could do a pull request
https://serde.rs/no-std.html
Otherwise OrderedFloat
is not ordered at all, breaking the assumptions of any algorithm that uses it.
The documentation for Ord
says
Implementations of PartialEq, PartialOrd, and Ord must agree with each other. It's easy to accidentally make them disagree by deriving some of the traits and manually implementing others.
The following test fails:
extern crate ordered_float;
use std::f64::NAN;
use ordered_float::OrderedFloat;
#[test]
fn less_than_nan() {
let x = OrderedFloat(1.0);
let y = OrderedFloat(NAN);
assert!(x < y);
}
None of the tests in this crate cover using the comparison operators; they all use Ord::cmp
directly. This should be fixed. The current code is unsound and could lead to unsafety.
Here's a thought experiment which would almost certainly be a breaking change, but something worth looking into nonetheless.
Right now, the inner representation of a NotNan<T>
is a T
. However, we know one thing about the value: it will never (soundly) be a NaN
. Using this information, we could optimize the inner representation of the type so that Option<NotNan<T>>
is a no-op. This could be done by using wrapping addition and subtraction combined with NonZeroU32/NonZeroU64
. What are your thoughts on this?
This way you could pass an ordered float to a generic function that requires Add+Ord. Same question for Sub/Mul/Div.
Per the rust docs, it seems that implementations of From
should be simple and infallible:
Note: this trait must not fail. If the conversion can fail, use TryFrom or a dedicated method which returns an Option or a Result<T, E>.
While this will obviously be a breaking change, we should considering removing the From
implementation, and implement TryFrom
, instead, when it becomes stable.
An old version of ordered-float
has dependencies specified with "*"
version requirement (stainless = "*"
).
Crates with such vague dependency versions became unusable, because *
allows picking too-new semver-incompatible dependencies.
It also breaks Cargo's minimal-versions
feature, because *
requirement allows picking very very old dependencies that aren't compatible with Rust 1.0.
Because this old version of ordered-float
is unusable and may cause problems for Cargo, I suggest yanking it:
cargo yank --vers 0.0.1
Hi, is there a plan to release a v3.1.0
or v3.0.1
to include PR #110?
I think it should be safe (although I might be wrong) to be able to convert safely a NotNaN<f32>
to a NotNaN<f64>
via Into
. One way to do so currently is with unsafe {NotNan::unchecked_new(x.into_inner() as f64)}
which is somewhat verbose.
In particular, UniformNotNan
and UniformOrdered
lack traits. Ideally, they should implement the same traits as UniformFloat
. At the very least, they should implement Debug
and Clone
. Additionally, they should implement Serde traits if serde
is enabled.
in my particular project, i need both increasing sort and decreasing sort.
could you please detail how i could specialize the order to reverse the default increasing sort?
or should i clone your library to duplicate the methods & structure of OrderedFloat.
Serde 0.9 release notes: https://github.com/serde-rs/serde/releases/tag/v0.9.0
Serde 1.0 release notes: https://github.com/serde-rs/serde/releases/tag/v1.0.0
Do you think it'd be a good idea to implement the num_traits traits for this crate's types?
Here are the release notes: https://github.com/serde-rs/serde/releases/tag/v0.9.0
Right now, ordered-float
is not formatted by rustfmt. Do people have strong feeling against setting up a rustfmt.toml
file and enforcing that the source code is formatted?
It seems we can satisfy the following behavior as long as we exclude NAN:
In particular Eq, Ord and Hash must be equivalent for borrowed and owned values: x.borrow() == y.borrow() should give the same result as x == y.
Now that it's been reintegrated, it shouldn't show up when you search for "ordered float".
Hi,
I'm wondering if it would be beneficial to implement the operations of float for this structs. It is cumbersome to always write NotNaN::unchecked_new(*self + *other)
etc.
Best regards
NotNaN's implementation prevents binary operators from receiving a NaN operand, but this is far from the only way that a NaN may arise;
NaN, the menace that it is, is something that all numeric binary operations are capable of producing!
fn main() {
let zero = NotNaN::new(0.).unwrap();
let infinity = NotNaN::new(1./0.).unwrap();
println!("{:?}", infinity + (-infinity)); // ==> NotNaN(NaN)
println!("{:?}", infinity - infinity); // ==> NotNaN(NaN)
println!("{:?}", zero * infinity); // ==> NotNaN(NaN)
println!("{:?}", zero / zero); // ==> NotNaN(NaN)
println!("{:?}", zero % zero); // ==> NotNaN(NaN)
}
Notice that due to unsafe optimizations in NotNaN, this enables undefined behavior in safe code.
https://github.com/LiveSplit/livesplit-core/runs/1835592754#step:6:188
error[E0433]: failed to resolve: use of undeclared crate or module `std`
--> /home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/ordered-float-2.1.0/src/lib.rs:349:26
|
349 | fn classify(self) -> std::num::FpCategory { self.0.classify() }
| ^^^ use of undeclared crate or module `std`
error[E0407]: method `mul_add` is not a member of trait `Float`
--> /home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/ordered-float-2.1.0/src/lib.rs:359:5
|
359 | fn mul_add(self, a: Self, b: Self) -> Self { OrderedFloat(self.0.mul_add(a.0, b.0)) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `Float`
....
Add an implementation of TryFrom
for NotNaN
, once TryFrom
is stable (rust-lang/rust#33417)
Issue #17 was not completely addressed. Adding two NotNaNs can produce a NaN.
Eg:
let a = NotNaN::new(std::f32::INFINITY).unwrap();
let b = NotNaN::new(std::f32::NEG_INFINITY).unwrap();
let c = a.add(b);
println!("{} + {} = {}", a, b, c);
why use into_inner and not into? why not implement as much Into's as possible so it would be easy use as a generic
new_unchecked
appears to be the standard word order. A bit of searching show only three crates that use unchecked_new
: ordered-float
, noisy_float
, and tidb_query_datatype
. The standard libraries prefer new_unchecked
and most other crates follow this convention.
Would you be interested in a PR that marks unchecked_new
as deprecated and adds new_unchecked
?
NotNan::unchecked_from()
is an unsafe way to bypass the usual NotNan
mechanism, by directly instantiating the struct with the desired float. However, it is not const
, despite the fact that it could be, allowing its use in constant contexts.
My use case for this is that I have a Color
struct:
pub struct Color {
r: NotNan<f32>,
g: NotNan<f32>,
b: NotNan<f32>,
a: NotNan<f32>,
}
impl Color {
pub unsafe fn new_no_nan_check(r: f32, g: f32, b: f32, a: f32) -> Self {
Self { r: NotNan::unchecked_new(r), g: NotNan::unchecked_new(g), b: NotNan::unchecked_new(b), a: NotNan::unchecked_new(a) }
}
}
It would be nice if I could make new_no_nan_check
const, so I could do something similar to:
const BLACK: Color = unsafe { Color::new_no_nan_check(0.0, 0.0, 0.0, 1.0) };
const WHITE: Color = unsafe { Color::new_no_nan_check(1.0, 1.0, 1.0, 1.0) };
I am willing to implement this feature if there is interest.
It would be nice to have these implementations behind an optional dependency on rand
. Would you accept a PR?
impl<T> Distribution<NonNan<T>> for Standard {}
impl<T> Distribution<NonNan<T>> for Open01 {}
impl<T> Distribution<NonNan<T>> for OpenClosed01 {}
impl<T> Distribution<OrderedFloat<T>> for Standard {}
impl<T> Distribution<OrderedFloat<T>> for Open01 {}
impl<T> Distribution<OrderedFloat<T>> for OpenClosed01 {}
It has been deprecated: announcement.
error[E0658]: the `#[repr(transparent)]` attribute is experimental (see issue #43036)
--> .cargo/registry/src/github.com-1ecc6299db9ec823/ordered-float-1.0.1/src/lib.rs:44:1
|
44 | #[repr(transparent)]
| ^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(repr_transparent)] to the crate attributes to enable
error[E0658]: the `#[repr(transparent)]` attribute is experimental (see issue #43036)
--> .cargo/registry/src/github.com-1ecc6299db9ec823/ordered-float-1.0.1/src/lib.rs:173:1
|
173 | #[repr(transparent)]
| ^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(repr_transparent)] to the crate attributes to enable
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.
error: Could not compile `ordered-float`.
Caused by:
process didn't exit successfully: `rustc --crate-name ordered_float .cargo/registry/src/github.com-1ecc6299db9ec823/ordered-float-1.0.1/src/lib.rs --crate-type lib --emit=dep-info,link -C debuginfo=2 --cfg feature="default" --cfg feature="std" -C metadata=f432133c0a2745ec -C extra-filename=-f432133c0a2745ec --out-dir /home/cratesfyi/cratesfyi/debug/deps -L dependency=/home/cratesfyi/cratesfyi/debug/deps --extern num_traits=/home/cratesfyi/cratesfyi/debug/deps/libnum_traits-7e393c06c3365063.rlib --extern-version num_traits=num-traits,0.2.6 --cap-lints allow` (exit code: 101)
thread 'main' panicked at 'Error(
CargoError(
build failed
),
State {
next_error: None,
backtrace: None
}
)', src/bin/cratesfyi.rs:142:13
The version on crates.io is 0.1.0, Cargo.toml says 0.0.2 in this repo here. Is this on purpose?
It implements AsRefDeref already. OrderedFloat already does implement AsMut/DerefMut. I think NotNan can/should also have it.
I'm trying to use OrderedFloat
with euclid
and am running into the following error:
--> src/chromosome.rs:31:38
|
31 | .map(|subpath| subpath.0.distance_to(subpath.1))
| ^^^^^^^^^^^ method not found in `&euclid::Point2D<OrderedFloat<f64>, MapSpace>`
|
::: /home/bemeurer/.cache/cargo/registry/src/github.com-1ecc6299db9ec823/ordered-float-2.0.1/src/lib.rs:43:1
|
43 | pub struct OrderedFloat<T>(pub T);
| ---------------------------------- doesn't satisfy `OrderedFloat<f64>: num_traits::float::Float`
|
= note: the method `distance_to` exists but the following trait bounds were not satisfied:
`OrderedFloat<f64>: num_traits::float::Float`
Is there some way to make it so that when T: Float
then OrderedFloat<T>: Float
? Or is this by design?
All the implementations for &NotNan
are missing. Without an implementation for, say, &NotNan<T> - &NotNan<T>
, these types cannot be used as drop-in replacements for f64
and f32
. Ideally NotNan
and OrderedFloat
would implement exactly the same traits as f64
and f32
.
Creating an empty project with the ordered-float = "2.7"
dependency does not compile. This is because of some T::ONE
and T::ZERO
calls that should have instead been T::one()
and T::zero()
. The version on GitHub does not have this issue.
For OrderedFloat
:
NaN is sorted as greater than all other values and equal to itself, in contradiction with the IEEE standard.
IEEE standard requires different NaNs to be not equal, positive NaN to be greater than +โ and negative NaN to be less than -โ. It also requires -0 to be less than +0. Why non-conformant behavior was chosen? Wouldn't it make more sense to implement total order as defined in standard instead?
This Stack Overflow answer is presumably providing a fast way to implement IEEE total order comparison.
#[derive(Hash)]
is used for the wrappers here, but f32 and f64 don't impl Hash because of NaN (or maybe other reasons)? Seems like the wrappers could manually provide unconditional Hash impls.
I notice that NotNan::new_unchecked()
has no T: Float
bound even though most other NotNan
functions and trait impls do. This means that it would be possible to construct a NotNan<char>
or NotNan<Vec<u8>>
or other such silly types, without violating the safety obligations as literally stated, because those types don't have anything considered a NaN
value.
I would like to know:
NotNan::new_unchecked
?T: Float
bound to statically prohibit it?Is there a reason why OrderedFloat
cannot be Signed
or would you accept a PR?
The current implementation of Hash
is pretty poor, and leads to lots of collisions for both fractional and whole numbers. For example, the following snippet yields only ~50% unique hash codes.
let state = RandomState::new();
let limit = 10000;
let mut set = ::std::collections::HashSet::with_capacity(limit);
for i in 0..limit {
let mut h = state.build_hasher();
OrderedFloat::from(i as f64).hash(&mut h);
set.insert(h.finish());
}
let pct_unique = set.len() as f64 / limit as f64;
println!("percent-unique={}", pct_unique);
A better implementation would be to interpret the Float
bits as a u64
and hash that value directly, taking into account NaN
and Zero
equivalencies. The JDK's Double.hashCode()
is a good example of this.
num_traits::float::FloatConst
, https://docs.rs/num-traits/0.2.15/num_traits/float/trait.FloatConst.html, could be implemented for both OrderedFloat
and NotNan
.
I wanted to write a struct containing an OrderedFloat
, but to implement various traits such as Eq
or Ord
, I need to use the Float
trait bound but this trait is defined in num-traits
instead of OrderedFloat
.
The current situation forces me to add num-traits
to my dependencies only to pull the Float
trait. It would be nicer if the traits used by OrderedFloat
were re-exported.
An important benefit to this is that it ensures that its the correct version of the trait in case there are multiple versions of num-traits
in the dependency tree.
Lines 102 to 106 in f02bf45
Can this be replaced with self.as_ref() == other.as_ref()
?
Since this feature it is now stable in 1.28.0
Would nice to have a function that did this. Maybe can just Implement From<&T>
for &OrderedFloat<T>
?
Ping @reem. Could you add some people to your various crates if you don't intend to maintain them anymore?
See the following code:
use std::collections::BTreeSet;
use ordered_float::NotNan;
fn main() {
let a = BTreeSet::<NotNan<f64>>::new();
let b = a.range(..);
}
In 2.8.0, this code compiles. In 2.9.0 and 2.10.0, it causes the following error:
error[E0283]: type annotations needed
--> src/main.rs:6:15
|
6 | let b = a.range(..);
| ^^^^^ cannot infer type for type parameter `K` declared on the associated function `range`
|
= note: cannot satisfy `_: Ord`
I cannot figure out at all why this error happens, but this is indeed a regression.
$ rustc --version
rustc 1.57.0 (f1edd0429 2021-11-29)
extern crate ordered_float;
fn main() {
println!("{}", ordered_float::NotNaN::new(::std::f64::NAN).unwrap_err());
}
FloatIsNan
This message (and Display output in general) should be designed to be human-readable and self explanatory. PascalCase belongs in Debug impls.
Recently, updating my dependencies in a project that depends on metrics
caused my build to fail in a place it wasn't failing previously due to a place where we were depending on the default type inference rules for std::ops::Add
to infer the type of an argument to a closure - something like:
struct MyType {}
impl Add for MyType { /* ... */ }
/* ... */
let y = MyType
let f = |x| x + y;
Simply having ordered_float in the dependency tree for my project - not even depended on directly! - causes that code to now fail with the following error message:
error[E0275]: overflow evaluating the requirement `&ordered_float::NotNan<_>: std::ops::Add`
--> code.rs
|
10 | x + y
| ^
|
= help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`my_crate`)
= note: required because of the requirements on the impl of `std::ops::Add` for `&ordered_float::OrderedFloat<ordered_float::NotNan<_>>`
= note: 127 redundant requirements hidden
= note: required because of the requirements on the impl of `std::ops::Add<&ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::NotNan<_>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` for `&ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::OrderedFloat<ordered_float::NotNan<_>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
(make sure to scroll to the right there - github's lack of wrapping for code blocks really doesn't do the size of the error message justice)
This issue was automatically generated. Feel free to close without ceremony if
you do not agree with re-licensing or if it is not possible for other reasons.
Respond to @cmr with any questions or concerns, or pop over to
#rust-offtopic
on IRC to discuss.
You're receiving this because someone (perhaps the project maintainer)
published a crates.io package with the license as "MIT" xor "Apache-2.0" and
the repository field pointing here.
TL;DR the Rust ecosystem is largely Apache-2.0. Being available under that
license is good for interoperation. The MIT license as an add-on can be nice
for GPLv2 projects to use your code.
The MIT license requires reproducing countless copies of the same copyright
header with different names in the copyright field, for every MIT library in
use. The Apache license does not have this drawback. However, this is not the
primary motivation for me creating these issues. The Apache license also has
protections from patent trolls and an explicit contribution licensing clause.
However, the Apache license is incompatible with GPLv2. This is why Rust is
dual-licensed as MIT/Apache (the "primary" license being Apache, MIT only for
GPLv2 compat), and doing so would be wise for this project. This also makes
this crate suitable for inclusion and unrestricted sharing in the Rust
standard distribution and other projects using dual MIT/Apache, such as my
personal ulterior motive, the Robigalia project.
Some ask, "Does this really apply to binary redistributions? Does MIT really
require reproducing the whole thing?" I'm not a lawyer, and I can't give legal
advice, but some Google Android apps include open source attributions using
this interpretation. Others also agree with
it.
But, again, the copyright notice redistribution is not the primary motivation
for the dual-licensing. It's stronger protections to licensees and better
interoperation with the wider Rust ecosystem.
To do this, get explicit approval from each contributor of copyrightable work
(as not all contributions qualify for copyright, due to not being a "creative
work", e.g. a typo fix) and then add the following to your README:
## License
Licensed under either of
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
additional terms or conditions.
and in your license headers, if you have them, use the following boilerplate
(based on that used in Rust):
// Copyright 2016 rust-ordered-float Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
It's commonly asked whether license headers are required. I'm not comfortable
making an official recommendation either way, but the Apache license
recommends it in their appendix on how to use the license.
Be sure to add the relevant LICENSE-{MIT,APACHE}
files. You can copy these
from the Rust repo for a plain-text
version.
And don't forget to update the license
metadata in your Cargo.toml
to:
license = "MIT OR Apache-2.0"
I'll be going through projects which agree to be relicensed and have approval
by the necessary contributors and doing this changes, so feel free to leave
the heavy lifting to me!
To agree to relicensing, comment with :
I license past and future contributions under the dual MIT/Apache-2.0 license, allowing licensees to chose either at their option.
Or, if you're a contributor, you can check the box in this repo next to your
name. My scripts will pick this exact phrase up and check your checkbox, but
I'll come through and manually review this issue later as well.
NotNan<f64>
should implement From<i8>
, From<i16>
, From<i32>
, From<u8>
, From<u16>
and From<u32>
, NotNan<f32>
should implement From<i8>
, From<i16>
, From<u8>
and From<u16>
.
Recently I was in the situation of having to convert from an i32
to a NotNan<f64>
due to a character size to percent of screen conversion (seems pointless, but has it's reasons). Since that conversion happened quite often in my program, I wanted to make the conversion as simple as possible, and ended up with this function:
fn i32_to_notnan_f64(source: i32) -> NotNan<f64> {
// SAFETY: source is an i32, and an i32 cannot hold a value that f64::from would convert to NaN
// as it doesn't have any "special" values
unsafe { NotNan::new_unchecked(f64::from(source)) }
}
And actually, I don't see any complications with this being the implementation of impl From<i32> for NotNan<f64>
. But it's very possible that I missed something, so I'm here opening this issue first before I break down the door with an PR.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.