diff --git a/palette/src/blend/blend.rs b/palette/src/blend/blend.rs
index 0ea51a12d..c27ff1b8b 100644
--- a/palette/src/blend/blend.rs
+++ b/palette/src/blend/blend.rs
@@ -2,7 +2,7 @@ use float::Float;
 use num_traits::{One, Zero};
 
 use blend::{BlendFunction, PreAlpha};
-use {cast, clamp, ComponentWise};
+use {clamp, ComponentWise};
 
 ///A trait for colors that can be blended together.
 ///
@@ -353,6 +353,10 @@ where
         let one = <Self::Color as ComponentWise>::Scalar::one();
         let zero = <Self::Color as ComponentWise>::Scalar::zero();
         let two = one + one;
+        let three = two + one;
+        let four = two + two;
+        let twelve = four + four + four;
+        let sixteen = twelve + four;
 
         let src = self.into_premultiplied();
         let dst = other.into_premultiplied();
@@ -369,14 +373,11 @@ where
                     b * (src.alpha + (two * a - src.alpha) * (one - m))
                         + a * (one - dst.alpha)
                         + b * (one - src.alpha)
-                } else if b * cast(4.0) <= dst.alpha {
+                } else if b * four <= dst.alpha {
                     let m2 = m * m;
                     let m3 = m2 * m;
 
-                    dst.alpha
-                        * (two * a - src.alpha)
-                        * (m3 * cast(16.0) - m2 * cast(12.0) - m * cast(3.0))
-                        + a
+                    dst.alpha * (two * a - src.alpha) * (m3 * sixteen - m2 * twelve - m * three) + a
                         - a * dst.alpha
                         + b
                 } else {
diff --git a/palette/src/chromatic_adaptation.rs b/palette/src/chromatic_adaptation.rs
index 9281674bf..cc0c6ac47 100644
--- a/palette/src/chromatic_adaptation.rs
+++ b/palette/src/chromatic_adaptation.rs
@@ -24,9 +24,10 @@
 //!```
 use float::Float;
 
-use {cast, Component, FromColor, IntoColor, Xyz};
+use from_f64;
+use matrix::{multiply_3x3, multiply_xyz, Mat3};
 use white_point::WhitePoint;
-use matrix::{multiply_xyz, Mat3, multiply_3x3};
+use {FloatComponent, FromColor, IntoColor, Xyz};
 
 ///Chromatic adaptation methods implemented in the library
 pub enum Method {
@@ -50,7 +51,7 @@ pub struct ConeResponseMatrices<T: Float> {
 ///one illuminant to another (Swp -> Dwp)
 pub trait TransformMatrix<Swp, Dwp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Swp: WhitePoint,
     Dwp: WhitePoint,
 {
@@ -86,7 +87,7 @@ where
 
 impl<Swp, Dwp, T> TransformMatrix<Swp, Dwp, T> for Method
 where
-    T: Component + Float,
+    T: FloatComponent,
     Swp: WhitePoint,
     Dwp: WhitePoint,
 {
@@ -95,38 +96,44 @@ where
         match *self {
              Method::Bradford => {
                 ConeResponseMatrices::<T> {
-                    ma: [cast(0.8951000), cast(0.2664000), cast(-0.1614000),
-                         cast(-0.7502000), cast(1.7135000), cast(0.0367000),
-                         cast(0.0389000), cast(-0.0685000), cast(1.0296000)
-                         ],
-                    inv_ma: [cast(0.9869929), cast(-0.1470543), cast(0.1599627),
-                             cast(0.4323053), cast(0.5183603), cast(0.0492912),
-                             cast(-0.0085287), cast(0.0400428), cast(0.9684867)
-                            ],
+                    ma: [
+                        from_f64(0.8951000), from_f64(0.2664000), from_f64(-0.1614000),
+                        from_f64(-0.7502000), from_f64(1.7135000), from_f64(0.0367000),
+                        from_f64(0.0389000), from_f64(-0.0685000), from_f64(1.0296000)
+                    ],
+                    inv_ma: [
+                        from_f64(0.9869929), from_f64(-0.1470543), from_f64(0.1599627),
+                        from_f64(0.4323053), from_f64(0.5183603), from_f64(0.0492912),
+                        from_f64(-0.0085287), from_f64(0.0400428), from_f64(0.9684867)
+                    ],
                 }
             }
              Method::VonKries => {
                 ConeResponseMatrices::<T> {
-                    ma: [cast(0.4002400), cast(0.7076000), cast(-0.0808100),
-                         cast(-0.2263000), cast(1.1653200), cast(0.0457000),
-                         cast(0.0000000), cast(0.0000000), cast(0.9182200)
-                         ],
-                    inv_ma: [cast(1.8599364), cast(-1.1293816), cast(0.2198974),
-                             cast(0.3611914), cast(0.6388125), cast(-0.0000064),
-                             cast(0.0000000), cast(0.0000000), cast(1.0890636)
-                             ],
+                    ma: [
+                        from_f64(0.4002400), from_f64(0.7076000), from_f64(-0.0808100),
+                        from_f64(-0.2263000), from_f64(1.1653200), from_f64(0.0457000),
+                        from_f64(0.0000000), from_f64(0.0000000), from_f64(0.9182200)
+                    ],
+                    inv_ma: [
+                        from_f64(1.8599364), from_f64(-1.1293816), from_f64(0.2198974),
+                        from_f64(0.3611914), from_f64(0.6388125), from_f64(-0.0000064),
+                        from_f64(0.0000000), from_f64(0.0000000), from_f64(1.0890636)
+                    ],
                 }
             }
              Method::XyzScaling => {
                 ConeResponseMatrices::<T> {
-                    ma: [cast(1.0000000), cast(0.0000000), cast(0.0000000),
-                         cast(0.0000000), cast(1.0000000), cast(0.0000000),
-                         cast(0.0000000), cast(0.0000000), cast(1.0000000)
-                         ],
-                    inv_ma: [cast(1.0000000), cast(0.0000000), cast(0.0000000),
-                             cast(0.0000000), cast(1.0000000), cast(0.0000000),
-                             cast(0.0000000), cast(0.0000000), cast(1.0000000)
-                             ],
+                    ma: [
+                        from_f64(1.0000000), from_f64(0.0000000), from_f64(0.0000000),
+                        from_f64(0.0000000), from_f64(1.0000000), from_f64(0.0000000),
+                        from_f64(0.0000000), from_f64(0.0000000), from_f64(1.0000000)
+                    ],
+                    inv_ma: [
+                        from_f64(1.0000000), from_f64(0.0000000), from_f64(0.0000000),
+                        from_f64(0.0000000), from_f64(1.0000000), from_f64(0.0000000),
+                        from_f64(0.0000000), from_f64(0.0000000), from_f64(1.0000000)
+                    ],
                 }
             }
         }
@@ -139,7 +146,7 @@ where
 ///Uses the bradford method for conversion by default.
 pub trait AdaptFrom<S, Swp, Dwp, T>: Sized
 where
-    T: Component + Float,
+    T: FloatComponent,
     Swp: WhitePoint,
     Dwp: WhitePoint,
 {
@@ -155,7 +162,7 @@ where
 
 impl<S, D, Swp, Dwp, T> AdaptFrom<S, Swp, Dwp, T> for D
 where
-    T: Component + Float,
+    T: FloatComponent,
     Swp: WhitePoint,
     Dwp: WhitePoint,
     S: IntoColor<Swp, T>,
@@ -175,7 +182,7 @@ where
 ///Uses the bradford method for conversion by default.
 pub trait AdaptInto<D, Swp, Dwp, T>: Sized
 where
-    T: Component + Float,
+    T: FloatComponent,
     Swp: WhitePoint,
     Dwp: WhitePoint,
 {
@@ -191,7 +198,7 @@ where
 
 impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for S
 where
-    T: Component + Float,
+    T: FloatComponent,
     Swp: WhitePoint,
     Dwp: WhitePoint,
     D: AdaptFrom<S, Swp, Dwp, T>,
@@ -204,9 +211,9 @@ where
 #[cfg(test)]
 mod test {
 
-    use Xyz;
-    use white_point::{D50, D65, A, C};
     use super::{AdaptFrom, AdaptInto, Method, TransformMatrix};
+    use white_point::{A, C, D50, D65};
+    use Xyz;
 
     #[test]
     fn d65_to_d50_matrix_xyz_scaling() {
diff --git a/palette/src/component.rs b/palette/src/component.rs
new file mode 100644
index 000000000..3ed1904bc
--- /dev/null
+++ b/palette/src/component.rs
@@ -0,0 +1,181 @@
+use num_traits::Zero;
+
+use float::Float;
+use {clamp, FromF64};
+
+/// Common trait for color components.
+pub trait Component: Copy + Zero + PartialOrd {
+    /// The highest displayable value this component type can reach. Higher
+    /// values are allowed, but they may be lowered to this before
+    /// converting to another format.
+    fn max_intensity() -> Self;
+}
+
+/// Common trait for floating point color components.
+pub trait FloatComponent: Component + Float + FromF64 {}
+
+impl<T: Component + Float + FromF64> FloatComponent for T {}
+
+macro_rules! impl_float_components {
+    ($($ty: ident),+) => {
+        $(
+            impl Component for $ty {
+                fn max_intensity() -> Self {
+                    1.0
+                }
+            }
+        )*
+    };
+}
+
+impl_float_components!(f32, f64);
+
+macro_rules! impl_uint_components {
+    ($($ty: ident),+) => {
+        $(
+            impl Component for $ty {
+                fn max_intensity() -> Self {
+                    core::$ty::MAX
+                }
+            }
+        )*
+    };
+}
+
+impl_uint_components!(u8, u16, u32, u64, u128);
+
+/// Converts from a color component type, while performing the appropriate scaling, rounding and clamping.
+///
+/// ```
+/// use palette::FromComponent;
+///
+/// // Scales the value up to u8::MAX while converting.
+/// let u8_component = u8::from_component(1.0f32);
+/// assert_eq!(u8_component, 255);
+/// ```
+pub trait FromComponent<T: Component> {
+    /// Converts `other` into `Self`, while performing the appropriate scaling, rounding and clamping.
+    fn from_component(other: T) -> Self;
+}
+
+impl<T: Component, U: IntoComponent<T> + Component> FromComponent<U> for T {
+    #[inline]
+    fn from_component(other: U) -> T {
+        other.into_component()
+    }
+}
+
+/// Converts into a color component type, while performing the appropriate scaling, rounding and clamping.
+///
+/// ```
+/// use palette::IntoComponent;
+///
+/// // Scales the value up to u8::MAX while converting.
+/// let u8_component: u8 = 1.0f32.into_component();
+/// assert_eq!(u8_component, 255);
+/// ```
+pub trait IntoComponent<T: Component> {
+    /// Converts `self` into `T`, while performing the appropriate scaling, rounding and clamping.
+    fn into_component(self) -> T;
+}
+
+impl<T: Component> IntoComponent<T> for T {
+    #[inline]
+    fn into_component(self) -> T {
+        self
+    }
+}
+
+macro_rules! convert_float_to_uint {
+    ($float: ident; direct ($($direct_target: ident),+); $(via $temporary: ident ($($target: ident),+);)*) => {
+        $(
+            impl IntoComponent<$direct_target> for $float {
+                #[inline]
+                fn into_component(self) -> $direct_target {
+                    let max = $direct_target::max_intensity() as $float;
+                    let scaled = self * max;
+                    clamp(scaled.round(), 0.0, max) as $direct_target
+                }
+            }
+        )+
+
+        $(
+            $(
+                impl IntoComponent<$target> for $float {
+                    #[inline]
+                    fn into_component(self) -> $target {
+                        let max = $target::max_intensity() as $temporary;
+                        let scaled = self as $temporary * max;
+                        clamp(scaled.round(), 0.0, max) as $target
+                    }
+                }
+            )+
+        )*
+    };
+}
+
+macro_rules! convert_uint_to_float {
+    ($uint: ident; $(via $temporary: ident ($($target: ident),+);)*) => {
+        $(
+            $(
+                impl IntoComponent<$target> for $uint {
+                    #[inline]
+                    fn into_component(self) -> $target {
+                        let max = $uint::max_intensity() as $temporary;
+                        let scaled = self as $temporary / max;
+                        scaled as $target
+                    }
+                }
+            )+
+        )*
+    };
+}
+
+macro_rules! convert_uint_to_uint {
+    ($uint: ident; $(via $temporary: ident ($($target: ident),+);)*) => {
+        $(
+            $(
+                impl IntoComponent<$target> for $uint {
+                    #[inline]
+                    fn into_component(self) -> $target {
+                        let target_max = $target::max_intensity() as $temporary;
+                        let own_max = $uint::max_intensity() as $temporary;
+                        let scaled = (self as $temporary / own_max) * target_max;
+                        clamp(scaled.round(), 0.0, target_max) as $target
+                    }
+                }
+            )+
+        )*
+    };
+}
+
+impl IntoComponent<f64> for f32 {
+    #[inline]
+    fn into_component(self) -> f64 {
+        self as f64
+    }
+}
+convert_float_to_uint!(f32; direct (u8, u16); via f64 (u32, u64, u128););
+
+impl IntoComponent<f32> for f64 {
+    #[inline]
+    fn into_component(self) -> f32 {
+        self as f32
+    }
+}
+convert_float_to_uint!(f64; direct (u8, u16, u32, u64, u128););
+
+convert_uint_to_float!(u8; via f32 (f32); via f64 (f64););
+convert_uint_to_uint!(u8; via f32 (u16); via f64 (u32, u64, u128););
+
+convert_uint_to_float!(u16; via f32 (f32); via f64 (f64););
+convert_uint_to_uint!(u16; via f32 (u8); via f64 (u32, u64, u128););
+
+convert_uint_to_float!(u32; via f64 (f32, f64););
+convert_uint_to_uint!(u32; via f64 (u8, u16, u64, u128););
+
+convert_uint_to_float!(u64; via f64 (f32, f64););
+convert_uint_to_uint!(u64; via f64 (u8, u16, u32, u128););
+
+convert_uint_to_float!(u128; via f64 (f32, f64););
+convert_uint_to_uint!(u128; via f64 (u8, u16, u32, u64););
diff --git a/palette/src/convert.rs b/palette/src/convert.rs
index ee3c1fb51..5a7bd2412 100644
--- a/palette/src/convert.rs
+++ b/palette/src/convert.rs
@@ -1,11 +1,9 @@
-use float::Float;
-
 use core::fmt::{self, Display, Formatter};
-use {Component, Limited, Hsl, Hsv, Hwb, Lab, Lch, Xyz, Yxy};
-use white_point::{D65, WhitePoint};
-use rgb::{Rgb, RgbSpace};
-use luma::Luma;
 use encoding::Linear;
+use luma::Luma;
+use rgb::{Rgb, RgbSpace};
+use white_point::{WhitePoint, D65};
+use {FloatComponent, Hsl, Hsv, Hwb, Lab, Lch, Limited, Xyz, Yxy};
 
 /// FromColor provides conversion from the colors.
 ///
@@ -102,11 +100,10 @@ use encoding::Linear;
 /// #[macro_use]
 /// extern crate approx;
 ///
-/// use palette::{Component, FromColor, Hsv, Pixel, Srgb};
+/// use palette::{FloatComponent, FromColor, Hsv, Pixel, Srgb};
 /// use palette::rgb::{Rgb, RgbSpace};
 /// use palette::encoding::Linear;
 /// use palette::white_point::D65;
-/// use palette::float::Float;
 ///
 /// /// sRGB, but with a reversed memory layout.
 /// #[derive(PartialEq, Debug, FromColor, Pixel)]
@@ -123,7 +120,7 @@ use encoding::Linear;
 /// // implementing a private conversion function and letting it
 /// // derive `From` automatically. It will take a round trip
 /// // through linear format, but that's fine in this case.
-/// impl<T: Component + Float> Bgr<T> {
+/// impl<T: FloatComponent> Bgr<T> {
 ///     // It converts from any linear Rgb type that has the D65
 ///     // white point, which is the default if we don't specify
 ///     // anything else with the `palette_white_point` attribute.
@@ -209,7 +206,7 @@ use encoding::Linear;
 /// ```
 pub trait FromColor<Wp = D65, T = f32>: Sized
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     ///Convert from XYZ color space
@@ -343,11 +340,10 @@ where
 /// #[macro_use]
 /// extern crate approx;
 ///
-/// use palette::{Component, Hsv, IntoColor, Pixel, Srgb};
+/// use palette::{FloatComponent, Hsv, IntoColor, Pixel, Srgb};
 /// use palette::rgb::{Rgb, RgbSpace};
 /// use palette::encoding::{Linear, self};
 /// use palette::white_point::D65;
-/// use palette::float::Float;
 ///
 /// type Hsv64 = Hsv<encoding::Srgb, f64>;
 ///
@@ -365,7 +361,7 @@ where
 /// // Rgb is a bit more complex than other colors, so we are
 /// // implementing a private conversion function and letting it
 /// // derive `Into` automatically.
-/// impl<T: Component + Float> Bgr<T> {
+/// impl<T: FloatComponent> Bgr<T> {
 ///     // It converts from any linear Rgb type that has the D65
 ///     // white point, which is the default if we don't specify
 ///     // anything else with the `palette_white_point` attribute.
@@ -441,7 +437,7 @@ where
 /// ```
 pub trait IntoColor<Wp = D65, T = f32>: Sized
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     ///Convert into XYZ space
@@ -619,7 +615,10 @@ pub trait ConvertFrom<T>: From<T> {
     fn try_convert_from(_: T) -> Result<Self, OutOfBounds<Self>>;
 }
 
-impl<T, U> ConvertFrom<T> for U where U: From<T> + Limited {
+impl<T, U> ConvertFrom<T> for U
+where
+    U: From<T> + Limited,
+{
     fn convert_from(t: T) -> U {
         let mut this = U::from(t);
         if !this.is_valid() {
@@ -639,7 +638,10 @@ impl<T, U> ConvertFrom<T> for U where U: From<T> + Limited {
 }
 
 // ConvertFrom implies ConvertInto
-impl<T, U> ConvertInto<U> for T where U: ConvertFrom<T> {
+impl<T, U> ConvertInto<U> for T
+where
+    U: ConvertFrom<T>,
+{
     #[inline]
     fn convert_into(self) -> U {
         U::convert_from(self)
@@ -660,7 +662,7 @@ macro_rules! impl_into_color {
     ($self_ty: ident, $from_fn: ident) => {
         impl<Wp, T> IntoColor<Wp, T> for $self_ty<Wp, T>
         where
-            T: Component + Float,
+            T: FloatComponent,
             Wp: WhitePoint,
         {
             fn into_xyz(self) -> Xyz<Wp, T> {
@@ -702,7 +704,7 @@ macro_rules! impl_into_color_rgb {
     ($self_ty: ident, $from_fn: ident) => {
         impl<S, Wp, T> IntoColor<Wp, T> for $self_ty<S, T>
         where
-            T: Component + Float,
+            T: FloatComponent,
             Wp: WhitePoint,
             S: RgbSpace<WhitePoint = Wp>,
         {
@@ -752,11 +754,10 @@ impl_into_color_rgb!(Hwb, from_hwb);
 #[cfg(test)]
 mod tests {
     use core::marker::PhantomData;
-    use float::Float;
-    use Component;
     use encoding::linear::Linear;
-    use rgb::{Rgb, RgbSpace};
     use luma::Luma;
+    use rgb::{Rgb, RgbSpace};
+    use FloatComponent;
     use {Hsl, Hsv, Hwb, Lab, Lch, Xyz, Yxy};
 
     #[derive(Copy, Clone, FromColor, IntoColor)]
@@ -797,9 +798,9 @@ mod tests {
     #[palette_component = "T"]
     #[palette_rgb_space = "(::encoding::Srgb, ::white_point::E)"]
     #[palette_internal]
-    struct WithoutXyz<T: Component + Float>(PhantomData<T>);
+    struct WithoutXyz<T: FloatComponent>(PhantomData<T>);
 
-    impl<T: Component + Float> WithoutXyz<T> {
+    impl<T: FloatComponent> WithoutXyz<T> {
         fn from_luma_internal(_color: Luma<Linear<::white_point::E>, T>) -> Self {
             WithoutXyz(PhantomData)
         }
@@ -809,13 +810,13 @@ mod tests {
         }
     }
 
-    impl<T: Component + Float> From<Lch<::white_point::E, T>> for WithoutXyz<T> {
+    impl<T: FloatComponent> From<Lch<::white_point::E, T>> for WithoutXyz<T> {
         fn from(_color: Lch<::white_point::E, T>) -> Self {
             WithoutXyz(PhantomData)
         }
     }
 
-    impl<T: Component + Float> Into<Lch<::white_point::E, T>> for WithoutXyz<T> {
+    impl<T: FloatComponent> Into<Lch<::white_point::E, T>> for WithoutXyz<T> {
         fn into(self) -> Lch<::white_point::E, T> {
             Lch::with_wp(T::one(), T::zero(), T::zero())
         }
diff --git a/palette/src/encoding/gamma.rs b/palette/src/encoding/gamma.rs
index e270167dd..71d96de51 100644
--- a/palette/src/encoding/gamma.rs
+++ b/palette/src/encoding/gamma.rs
@@ -4,11 +4,11 @@ use core::marker::PhantomData;
 
 use float::Float;
 
-use cast;
-use rgb::{RgbSpace, RgbStandard};
-use luma::LumaStandard;
 use encoding::TransferFn;
+use luma::LumaStandard;
+use rgb::{RgbSpace, RgbStandard};
 use white_point::WhitePoint;
+use {from_f64, FromF64};
 
 /// Gamma encoding.
 ///
@@ -40,25 +40,25 @@ impl<Wp: WhitePoint, N: Number> LumaStandard for Gamma<Wp, N> {
 pub struct GammaFn<N: Number = F2p2>(PhantomData<N>);
 
 impl<N: Number> TransferFn for GammaFn<N> {
-    fn into_linear<T: Float>(x: T) -> T {
-        x.powf(T::one() / cast(N::VALUE))
+    fn into_linear<T: Float + FromF64>(x: T) -> T {
+        x.powf(T::one() / from_f64(N::VALUE))
     }
 
-    fn from_linear<T: Float>(x: T) -> T {
-        x.powf(cast(N::VALUE))
+    fn from_linear<T: Float + FromF64>(x: T) -> T {
+        x.powf(from_f64(N::VALUE))
     }
 }
 
 /// A type level float constant.
 pub trait Number {
     /// The represented number.
-    const VALUE: f32;
+    const VALUE: f64;
 }
 
-/// Represents `2.2f32`.
+/// Represents `2.2f64`.
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct F2p2;
 
 impl Number for F2p2 {
-    const VALUE: f32 = 2.2;
+    const VALUE: f64 = 2.2;
 }
diff --git a/palette/src/encoding/mod.rs b/palette/src/encoding/mod.rs
index a8ebba26f..0dff417ce 100644
--- a/palette/src/encoding/mod.rs
+++ b/palette/src/encoding/mod.rs
@@ -1,21 +1,22 @@
 //! Various encoding traits, types and standards.
 
 use float::Float;
+use FromF64;
 
-pub use self::srgb::Srgb;
 pub use self::gamma::{F2p2, Gamma};
 pub use self::linear::Linear;
+pub use self::srgb::Srgb;
 
-pub mod srgb;
 pub mod gamma;
 pub mod linear;
 pub mod pixel;
+pub mod srgb;
 
 /// A transfer function to and from linear space.
 pub trait TransferFn {
     /// Convert the color component `x` from linear space.
-    fn from_linear<T: Float>(x: T) -> T;
+    fn from_linear<T: Float + FromF64>(x: T) -> T;
 
     /// Convert the color component `x` into linear space.
-    fn into_linear<T: Float>(x: T) -> T;
+    fn into_linear<T: Float + FromF64>(x: T) -> T;
 }
diff --git a/palette/src/encoding/srgb.rs b/palette/src/encoding/srgb.rs
index 522a8ede1..a92ec1cab 100644
--- a/palette/src/encoding/srgb.rs
+++ b/palette/src/encoding/srgb.rs
@@ -1,26 +1,26 @@
 //! The sRGB standard.
 
+use encoding::TransferFn;
 use float::Float;
-
-use rgb::{Primaries, RgbSpace, RgbStandard};
 use luma::LumaStandard;
-use encoding::TransferFn;
-use white_point::{D65, WhitePoint};
-use {cast, Component, Yxy};
+use rgb::{Primaries, RgbSpace, RgbStandard};
+use white_point::{WhitePoint, D65};
+use {from_f64, FromF64};
+use {FloatComponent, Yxy};
 
 ///The sRGB color space.
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct Srgb;
 
 impl Primaries for Srgb {
-    fn red<Wp: WhitePoint, T: Component + Float>() -> Yxy<Wp, T> {
-        Yxy::with_wp(cast(0.6400), cast(0.3300), cast(0.212656))
+    fn red<Wp: WhitePoint, T: FloatComponent>() -> Yxy<Wp, T> {
+        Yxy::with_wp(from_f64(0.6400), from_f64(0.3300), from_f64(0.212656))
     }
-    fn green<Wp: WhitePoint, T: Component + Float>() -> Yxy<Wp, T> {
-        Yxy::with_wp(cast(0.3000), cast(0.6000), cast(0.715158))
+    fn green<Wp: WhitePoint, T: FloatComponent>() -> Yxy<Wp, T> {
+        Yxy::with_wp(from_f64(0.3000), from_f64(0.6000), from_f64(0.715158))
     }
-    fn blue<Wp: WhitePoint, T: Component + Float>() -> Yxy<Wp, T> {
-        Yxy::with_wp(cast(0.1500), cast(0.0600), cast(0.072186))
+    fn blue<Wp: WhitePoint, T: FloatComponent>() -> Yxy<Wp, T> {
+        Yxy::with_wp(from_f64(0.1500), from_f64(0.0600), from_f64(0.072186))
     }
 }
 
@@ -40,19 +40,19 @@ impl LumaStandard for Srgb {
 }
 
 impl TransferFn for Srgb {
-    fn into_linear<T: Float>(x: T) -> T {
-        if x <= cast(0.04045) {
-            x / cast(12.92)
+    fn into_linear<T: Float + FromF64>(x: T) -> T {
+        if x <= from_f64(0.04045) {
+            x / from_f64(12.92)
         } else {
-            ((x + cast(0.055)) / cast(1.055)).powf(cast(2.4))
+            ((x + from_f64(0.055)) / from_f64(1.055)).powf(from_f64(2.4))
         }
     }
 
-    fn from_linear<T: Float>(x: T) -> T {
-        if x <= cast(0.0031308) {
-            x * cast(12.92)
+    fn from_linear<T: Float + FromF64>(x: T) -> T {
+        if x <= from_f64(0.0031308) {
+            x * from_f64(12.92)
         } else {
-            x.powf(T::one() / cast(2.4)) * cast(1.055) - cast(0.055)
+            x.powf(T::one() / from_f64(2.4)) * from_f64(1.055) - from_f64(0.055)
         }
     }
 }
diff --git a/palette/src/equality.rs b/palette/src/equality.rs
index 95de209dd..a933eb8a9 100644
--- a/palette/src/equality.rs
+++ b/palette/src/equality.rs
@@ -2,14 +2,14 @@ use float::Float;
 
 use approx::{AbsDiffEq, RelativeEq, UlpsEq};
 
-use {cast, Component, Lab, LabHue, Lch, RgbHue, Xyz, Yxy};
 use white_point::WhitePoint;
+use {from_f64, FloatComponent, FromF64, Lab, LabHue, Lch, RgbHue, Xyz, Yxy};
 
 macro_rules! impl_eq {
     (  $self_ty: ident , [$($element: ident),+]) => {
         impl<Wp, T> AbsDiffEq for $self_ty<Wp, T>
-        where T: Component + Float + AbsDiffEq,
-            T::Epsilon: Copy + Float,
+        where T: FloatComponent + AbsDiffEq,
+            T::Epsilon: Copy + FloatComponent,
             Wp: WhitePoint + PartialEq
         {
             type Epsilon = T::Epsilon;
@@ -27,8 +27,8 @@ macro_rules! impl_eq {
         }
 
         impl<Wp, T> RelativeEq for $self_ty<Wp, T>
-        where T: Component + Float + RelativeEq,
-            T::Epsilon: Copy + Float,
+        where T: FloatComponent + RelativeEq,
+            T::Epsilon: Copy + FloatComponent,
             Wp: WhitePoint + PartialEq
         {
             fn default_max_relative() -> T::Epsilon {
@@ -44,8 +44,8 @@ macro_rules! impl_eq {
         }
 
         impl<Wp, T> UlpsEq for $self_ty<Wp, T>
-        where T: Component + Float + UlpsEq,
-            T::Epsilon: Copy + Float,
+        where T: FloatComponent + UlpsEq,
+            T::Epsilon: Copy + FloatComponent,
             Wp: WhitePoint + PartialEq
         {
             fn default_max_ulps() -> u32 {
@@ -77,13 +77,14 @@ impl_eq!(Lch, [l, chroma, hue]);
 // ulps. Because of this we loose some precision for values close to 0.0.
 macro_rules! impl_eq_hue {
     (  $self_ty: ident ) => {
-        impl<T: Float + AbsDiffEq> AbsDiffEq for $self_ty<T>
-        where T::Epsilon: Float
+        impl<T: Float + FromF64 + AbsDiffEq> AbsDiffEq for $self_ty<T>
+        where
+            T::Epsilon: Float + FromF64,
         {
             type Epsilon = T::Epsilon;
 
             fn default_epsilon() -> Self::Epsilon {
-                T::default_epsilon() * cast(180.0)
+                T::default_epsilon() * from_f64(180.0)
             }
 
             fn abs_diff_eq(&self, other: &Self, epsilon: T::Epsilon) -> bool {
@@ -96,25 +97,37 @@ macro_rules! impl_eq_hue {
             }
         }
 
-        impl<T: Float + RelativeEq> RelativeEq for $self_ty<T>
-        where T::Epsilon: Float
+        impl<T: Float + FromF64 + RelativeEq> RelativeEq for $self_ty<T>
+        where
+            T::Epsilon: Float + FromF64,
         {
             fn default_max_relative() -> Self::Epsilon {
-                T::default_max_relative() * cast(180.0)
+                T::default_max_relative() * from_f64(180.0)
             }
 
-            fn relative_eq(&self, other: &Self, epsilon: T::Epsilon, max_relative: T::Epsilon) -> bool {
+            fn relative_eq(
+                &self,
+                other: &Self,
+                epsilon: T::Epsilon,
+                max_relative: T::Epsilon,
+            ) -> bool {
                 let diff: T = (*self - *other).to_degrees();
                 T::relative_eq(&diff, &T::zero(), epsilon, max_relative)
             }
-            fn relative_ne(&self, other: &Self, epsilon: Self::Epsilon, max_relative: Self::Epsilon) -> bool {
+            fn relative_ne(
+                &self,
+                other: &Self,
+                epsilon: Self::Epsilon,
+                max_relative: Self::Epsilon,
+            ) -> bool {
                 let diff: T = (*self - *other).to_degrees();
                 T::relative_ne(&diff, &T::zero(), epsilon, max_relative)
             }
         }
 
-        impl<T: Float + UlpsEq> UlpsEq for $self_ty<T>
-        where T::Epsilon: Float
+        impl<T: Float + FromF64 + UlpsEq> UlpsEq for $self_ty<T>
+        where
+            T::Epsilon: Float + FromF64,
         {
             fn default_max_ulps() -> u32 {
                 T::default_max_ulps() * 180
@@ -129,7 +142,7 @@ macro_rules! impl_eq_hue {
                 T::ulps_ne(&diff, &T::zero(), epsilon, max_ulps)
             }
         }
-    }
+    };
 }
 
 impl_eq_hue!(LabHue);
diff --git a/palette/src/gradient.rs b/palette/src/gradient.rs
index 76c57dd98..dc921ddf4 100644
--- a/palette/src/gradient.rs
+++ b/palette/src/gradient.rs
@@ -3,12 +3,12 @@
 //!This module is only available if the `std` feature is enabled (this is the
 //!default).
 
-use num_traits::{One, Zero};
+use approx::{AbsDiffEq, RelativeEq, UlpsEq};
 use float::Float;
+use num_traits::{One, Zero};
 use std::cmp::max;
-use approx::{AbsDiffEq, RelativeEq, UlpsEq};
 
-use cast;
+use {from_f64, FromF64};
 
 use Mix;
 
@@ -26,13 +26,16 @@ pub struct Gradient<C: Mix + Clone>(Vec<(C::Scalar, C)>);
 impl<C: Mix + Clone> Gradient<C> {
     ///Create a gradient of evenly spaced colors with the domain [0.0, 1.0].
     ///There must be at least one color.
-    pub fn new<I: IntoIterator<Item = C>>(colors: I) -> Gradient<C> {
+    pub fn new<I: IntoIterator<Item = C>>(colors: I) -> Gradient<C>
+    where
+        C::Scalar: FromF64,
+    {
         let mut points: Vec<_> = colors.into_iter().map(|c| (C::Scalar::zero(), c)).collect();
         assert!(points.len() > 0);
-        let step_size = C::Scalar::one() / cast(max(points.len() - 1, 1) as f64);
+        let step_size = C::Scalar::one() / from_f64(max(points.len() - 1, 1) as f64);
 
         for (i, &mut (ref mut p, _)) in points.iter_mut().enumerate() {
-            *p = cast::<C::Scalar, _>(i) * step_size;
+            *p = from_f64::<C::Scalar>(i as f64) * step_size;
         }
 
         Gradient(points)
@@ -51,7 +54,8 @@ impl<C: Mix + Clone> Gradient<C> {
     ///Get a color from the gradient. The color of the closest control point
     ///will be returned if `i` is outside the domain.
     pub fn get(&self, i: C::Scalar) -> C {
-        let &(mut min, ref min_color) = self.0
+        let &(mut min, ref min_color) = self
+            .0
             .get(0)
             .expect("a Gradient must contain at least one color");
         let mut min_color = min_color;
@@ -61,7 +65,8 @@ impl<C: Mix + Clone> Gradient<C> {
             return min_color.clone();
         }
 
-        let &(mut max, ref max_color) = self.0
+        let &(mut max, ref max_color) = self
+            .0
             .last()
             .expect("a Gradient must contain at least one color");
         let mut max_color = max_color;
@@ -143,10 +148,12 @@ impl<C: Mix + Clone> Gradient<C> {
 
     ///Get the limits of this gradient's domain.
     pub fn domain(&self) -> (C::Scalar, C::Scalar) {
-        let &(min, _) = self.0
+        let &(min, _) = self
+            .0
             .get(0)
             .expect("a Gradient must contain at least one color");
-        let &(max, _) = self.0
+        let &(max, _) = self
+            .0
             .last()
             .expect("a Gradient must contain at least one color");
         (min, max)
@@ -164,7 +171,10 @@ pub struct Take<'a, C: Mix + Clone + 'a> {
     from_end: usize,
 }
 
-impl<'a, C: Mix + Clone> Iterator for Take<'a, C> {
+impl<'a, C: Mix + Clone> Iterator for Take<'a, C>
+where
+    C::Scalar: FromF64,
+{
     type Item = C;
 
     fn next(&mut self) -> Option<C> {
@@ -173,7 +183,9 @@ impl<'a, C: Mix + Clone> Iterator for Take<'a, C> {
                 self.from_head += 1;
                 Some(self.gradient.get(self.from))
             } else {
-                let i = self.from + (self.diff / cast(self.len - 1)) * cast(self.from_head);
+                let i = self.from
+                    + (self.diff / from_f64((self.len - 1) as f64))
+                        * from_f64(self.from_head as f64);
                 self.from_head += 1;
                 Some(self.gradient.get(i))
             }
@@ -183,20 +195,27 @@ impl<'a, C: Mix + Clone> Iterator for Take<'a, C> {
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        (self.len - self.from_head - self.from_end, Some(self.len - self.from_head - self.from_end))
+        (
+            self.len - self.from_head - self.from_end,
+            Some(self.len - self.from_head - self.from_end),
+        )
     }
 }
 
-impl<'a, C: Mix + Clone> ExactSizeIterator for Take<'a, C> {}
+impl<'a, C: Mix + Clone> ExactSizeIterator for Take<'a, C> where C::Scalar: FromF64 {}
 
-impl<'a, C: Mix + Clone> DoubleEndedIterator for Take<'a, C> {
+impl<'a, C: Mix + Clone> DoubleEndedIterator for Take<'a, C>
+where
+    C::Scalar: FromF64,
+{
     fn next_back(&mut self) -> Option<Self::Item> {
         if self.from_head + self.from_end < self.len {
             if self.len == 1 {
                 self.from_end += 1;
                 Some(self.gradient.get(self.from))
             } else {
-                let i = self.from + (self.diff / cast(self.len - 1)) * cast(self.len - self.from_end - 1);
+                let i = self.from
+                    + (self.diff / from_f64((self.len - 1) as f64)) * from_f64((self.len - self.from_end - 1) as f64);
                 self.from_end += 1;
                 Some(self.gradient.get(i))
             }
@@ -490,13 +509,25 @@ mod test {
             LinSrgb::new(0.0, 0.0, 1.0),
         ]);
 
-        let v1: Vec<_> = g.take(10).collect::<Vec<_>>().iter().rev().cloned().collect();
+        let v1: Vec<_> = g
+            .take(10)
+            .collect::<Vec<_>>()
+            .iter()
+            .rev()
+            .cloned()
+            .collect();
         let v2: Vec<_> = g.take(10).rev().collect();
         for (t1, t2) in v1.iter().zip(v2.iter()) {
             assert_relative_eq!(t1, t2);
         }
         //make sure `take(1).rev()` doesn't produce NaN results
-        let v1: Vec<_> = g.take(1).collect::<Vec<_>>().iter().rev().cloned().collect();
+        let v1: Vec<_> = g
+            .take(1)
+            .collect::<Vec<_>>()
+            .iter()
+            .rev()
+            .cloned()
+            .collect();
         let v2: Vec<_> = g.take(1).rev().collect();
         for (t1, t2) in v1.iter().zip(v2.iter()) {
             assert_relative_eq!(t1, t2);
diff --git a/palette/src/hsl.rs b/palette/src/hsl.rs
index b0256d6de..2fbbd7845 100644
--- a/palette/src/hsl.rs
+++ b/palette/src/hsl.rs
@@ -9,8 +9,8 @@ use encoding::pixel::RawPixel;
 use encoding::{Linear, Srgb};
 use rgb::{Rgb, RgbSpace};
 use {
-    cast, clamp, Alpha, Component, FromColor, GetHue, Hsv, Hue, IntoColor, Limited, Mix, Pixel,
-    RgbHue, Saturate, Shade, Xyz,
+    clamp, from_f64, Alpha, Component, FloatComponent, FromColor, FromF64, GetHue, Hsv, Hue,
+    IntoColor, Limited, Mix, Pixel, RgbHue, Saturate, Shade, Xyz,
 };
 
 /// Linear HSL with an alpha component. See the [`Hsla` implementation in
@@ -38,7 +38,7 @@ pub type Hsla<S = Srgb, T = f32> = Alpha<Hsl<S, T>, T>;
 #[repr(C)]
 pub struct Hsl<S = Srgb, T = f32>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     ///The hue of the color, in degrees. Decides if it's red, blue, purple,
@@ -63,14 +63,14 @@ where
 
 impl<S, T> Copy for Hsl<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
 }
 
 impl<S, T> Clone for Hsl<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     fn clone(&self) -> Hsl<S, T> {
@@ -80,7 +80,7 @@ where
 
 impl<T> Hsl<Srgb, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
 {
     ///HSL for linear sRGB.
     pub fn new<H: Into<RgbHue<T>>>(hue: H, saturation: T, lightness: T) -> Hsl<Srgb, T> {
@@ -95,7 +95,7 @@ where
 
 impl<S, T> Hsl<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     ///Linear HSL.
@@ -135,16 +135,12 @@ where
             let (max, min, sep, coeff) = if rgb.red > rgb.green {
                 (rgb.red, rgb.green, rgb.green - rgb.blue, T::zero())
             } else {
-                (rgb.green, rgb.red, rgb.blue - rgb.red, cast(2.0))
+                (rgb.green, rgb.red, rgb.blue - rgb.red, from_f64(2.0))
             };
             if rgb.blue > max {
-                (rgb.blue, min, rgb.red - rgb.green, cast(4.0))
+                (rgb.blue, min, rgb.red - rgb.green, from_f64(4.0))
             } else {
-                let min_val = if rgb.blue < min {
-                    rgb.blue
-                } else {
-                    min
-                };
+                let min_val = if rgb.blue < min { rgb.blue } else { min };
                 (max, min_val, sep, coeff)
             }
         };
@@ -153,15 +149,15 @@ where
         let mut s = T::zero();
 
         let sum = max + min;
-        let l = sum / cast(2.0);
+        let l = sum / from_f64(2.0);
         if max != min {
             let d = max - min;
             s = if sum > T::one() {
-                d / (cast::<T, _>(2.0) - sum)
+                d / (from_f64::<T>(2.0) - sum)
             } else {
                 d / sum
             };
-            h = ((sep / d) + coeff) * cast(60.0);
+            h = ((sep / d) + coeff) * from_f64(60.0);
         };
 
         Hsl {
@@ -186,7 +182,7 @@ where
 ///<span id="Hsla"></span>[`Hsla`](type.Hsla.html) implementations.
 impl<T, A> Alpha<Hsl<Srgb, T>, A>
 where
-    T: Component + Float,
+    T: FloatComponent,
     A: Component,
 {
     ///HSL and transparency for linear sRGB.
@@ -201,7 +197,7 @@ where
 ///<span id="Hsla"></span>[`Hsla`](type.Hsla.html) implementations.
 impl<S, T, A> Alpha<Hsl<S, T>, A>
 where
-    T: Component + Float,
+    T: FloatComponent,
     A: Component,
     S: RgbSpace,
 {
@@ -228,7 +224,7 @@ where
 
 impl<S, T> From<Xyz<S::WhitePoint, T>> for Hsl<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     fn from(color: Xyz<S::WhitePoint, T>) -> Self {
@@ -239,14 +235,14 @@ where
 
 impl<S, Sp, T> From<Hsv<Sp, T>> for Hsl<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
     Sp: RgbSpace<WhitePoint = S::WhitePoint>,
 {
     fn from(color: Hsv<Sp, T>) -> Self {
         let hsv = Hsv::<S, T>::from_hsv(color);
 
-        let x = (cast::<T, _>(2.0) - hsv.saturation) * hsv.value;
+        let x = (from_f64::<T>(2.0) - hsv.saturation) * hsv.value;
         let saturation = if !hsv.value.is_normal() {
             T::zero()
         } else if x < T::one() {
@@ -256,7 +252,7 @@ where
                 T::zero()
             }
         } else {
-            let denom = cast::<T, _>(2.0) - x;
+            let denom = from_f64::<T>(2.0) - x;
             if denom.is_normal() {
                 hsv.saturation * hsv.value / denom
             } else {
@@ -267,25 +263,25 @@ where
         Hsl {
             hue: hsv.hue,
             saturation: saturation,
-            lightness: x / cast(2.0),
+            lightness: x / from_f64(2.0),
             space: PhantomData,
         }
     }
 }
 
-impl<S: RgbSpace, T: Component + Float, H: Into<RgbHue<T>>> From<(H, T, T)> for Hsl<S, T> {
+impl<S: RgbSpace, T: FloatComponent, H: Into<RgbHue<T>>> From<(H, T, T)> for Hsl<S, T> {
     fn from(components: (H, T, T)) -> Self {
         Self::from_components(components)
     }
 }
 
-impl<S: RgbSpace, T: Component + Float> Into<(RgbHue<T>, T, T)> for Hsl<S, T> {
+impl<S: RgbSpace, T: FloatComponent> Into<(RgbHue<T>, T, T)> for Hsl<S, T> {
     fn into(self) -> (RgbHue<T>, T, T) {
         self.into_components()
     }
 }
 
-impl<S: RgbSpace, T: Component + Float, H: Into<RgbHue<T>>, A: Component> From<(H, T, T, A)>
+impl<S: RgbSpace, T: FloatComponent, H: Into<RgbHue<T>>, A: Component> From<(H, T, T, A)>
     for Alpha<Hsl<S, T>, A>
 {
     fn from(components: (H, T, T, A)) -> Self {
@@ -293,7 +289,7 @@ impl<S: RgbSpace, T: Component + Float, H: Into<RgbHue<T>>, A: Component> From<(
     }
 }
 
-impl<S: RgbSpace, T: Component + Float, A: Component> Into<(RgbHue<T>, T, T, A)>
+impl<S: RgbSpace, T: FloatComponent, A: Component> Into<(RgbHue<T>, T, T, A)>
     for Alpha<Hsl<S, T>, A>
 {
     fn into(self) -> (RgbHue<T>, T, T, A) {
@@ -303,7 +299,7 @@ impl<S: RgbSpace, T: Component + Float, A: Component> Into<(RgbHue<T>, T, T, A)>
 
 impl<S, T> Limited for Hsl<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     #[cfg_attr(rustfmt, rustfmt_skip)]
@@ -326,7 +322,7 @@ where
 
 impl<S, T> Mix for Hsl<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     type Scalar = T;
@@ -346,7 +342,7 @@ where
 
 impl<S, T> Shade for Hsl<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     type Scalar = T;
@@ -363,7 +359,7 @@ where
 
 impl<S, T> GetHue for Hsl<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     type Hue = RgbHue<T>;
@@ -379,7 +375,7 @@ where
 
 impl<S, T> Hue for Hsl<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     fn with_hue<H: Into<Self::Hue>>(&self, hue: H) -> Hsl<S, T> {
@@ -403,7 +399,7 @@ where
 
 impl<S, T> Saturate for Hsl<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     type Scalar = T;
@@ -420,7 +416,7 @@ where
 
 impl<S, T> Default for Hsl<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     fn default() -> Hsl<S, T> {
@@ -430,7 +426,7 @@ where
 
 impl<S, T> Add<Hsl<S, T>> for Hsl<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     type Output = Hsl<S, T>;
@@ -447,7 +443,7 @@ where
 
 impl<S, T> Add<T> for Hsl<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     type Output = Hsl<S, T>;
@@ -463,9 +459,9 @@ where
 }
 
 impl<S, T> AddAssign<Hsl<S, T>> for Hsl<S, T>
-    where
-        T: Component + Float + AddAssign,
-        S: RgbSpace,
+where
+    T: FloatComponent + AddAssign,
+    S: RgbSpace,
 {
     fn add_assign(&mut self, other: Hsl<S, T>) {
         self.hue += other.hue;
@@ -475,9 +471,9 @@ impl<S, T> AddAssign<Hsl<S, T>> for Hsl<S, T>
 }
 
 impl<S, T> AddAssign<T> for Hsl<S, T>
-    where
-        T: Component + Float + AddAssign,
-        S: RgbSpace,
+where
+    T: FloatComponent + AddAssign,
+    S: RgbSpace,
 {
     fn add_assign(&mut self, c: T) {
         self.hue += c;
@@ -488,7 +484,7 @@ impl<S, T> AddAssign<T> for Hsl<S, T>
 
 impl<S, T> Sub<Hsl<S, T>> for Hsl<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     type Output = Hsl<S, T>;
@@ -505,7 +501,7 @@ where
 
 impl<S, T> Sub<T> for Hsl<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     type Output = Hsl<S, T>;
@@ -521,9 +517,9 @@ where
 }
 
 impl<S, T> SubAssign<Hsl<S, T>> for Hsl<S, T>
-    where
-        T: Component + Float + SubAssign,
-        S: RgbSpace,
+where
+    T: FloatComponent + SubAssign,
+    S: RgbSpace,
 {
     fn sub_assign(&mut self, other: Hsl<S, T>) {
         self.hue -= other.hue;
@@ -533,9 +529,9 @@ impl<S, T> SubAssign<Hsl<S, T>> for Hsl<S, T>
 }
 
 impl<S, T> SubAssign<T> for Hsl<S, T>
-    where
-        T: Component + Float + SubAssign,
-        S: RgbSpace,
+where
+    T: FloatComponent + SubAssign,
+    S: RgbSpace,
 {
     fn sub_assign(&mut self, c: T) {
         self.hue -= c;
@@ -546,7 +542,7 @@ impl<S, T> SubAssign<T> for Hsl<S, T>
 
 impl<S, T, P> AsRef<P> for Hsl<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
     P: RawPixel<T> + ?Sized,
 {
@@ -557,7 +553,7 @@ where
 
 impl<S, T, P> AsMut<P> for Hsl<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
     P: RawPixel<T> + ?Sized,
 {
@@ -568,8 +564,8 @@ where
 
 impl<S, T> AbsDiffEq for Hsl<S, T>
 where
-    T: Component + Float + AbsDiffEq,
-    T::Epsilon: Copy + Float,
+    T: FloatComponent + AbsDiffEq,
+    T::Epsilon: Copy + Float + FromF64,
     S: RgbSpace + PartialEq,
 {
     type Epsilon = T::Epsilon;
@@ -579,16 +575,16 @@ where
     }
 
     fn abs_diff_eq(&self, other: &Self, epsilon: T::Epsilon) -> bool {
-        self.hue.abs_diff_eq(&other.hue, epsilon) &&
-            self.saturation.abs_diff_eq(&other.saturation, epsilon) &&
-            self.lightness.abs_diff_eq(&other.lightness, epsilon)
+        self.hue.abs_diff_eq(&other.hue, epsilon)
+            && self.saturation.abs_diff_eq(&other.saturation, epsilon)
+            && self.lightness.abs_diff_eq(&other.lightness, epsilon)
     }
 }
 
 impl<S, T> RelativeEq for Hsl<S, T>
 where
-    T: Component + Float + RelativeEq,
-    T::Epsilon: Copy + Float,
+    T: FloatComponent + RelativeEq,
+    T::Epsilon: Copy + Float + FromF64,
     S: RgbSpace + PartialEq,
 {
     fn default_max_relative() -> Self::Epsilon {
@@ -610,8 +606,8 @@ where
 
 impl<S, T> UlpsEq for Hsl<S, T>
 where
-    T: Component + Float + UlpsEq,
-    T::Epsilon: Copy + Float,
+    T: FloatComponent + UlpsEq,
+    T::Epsilon: Copy + Float + FromF64,
     S: RgbSpace + PartialEq,
 {
     fn default_max_ulps() -> u32 {
@@ -684,7 +680,7 @@ mod test {
 
     #[test]
     fn ranges() {
-        assert_ranges!{
+        assert_ranges! {
             Hsl<Srgb, f64>;
             limited {
                 saturation: 0.0 => 1.0,
diff --git a/palette/src/hsv.rs b/palette/src/hsv.rs
index fd147f868..7296c5f03 100644
--- a/palette/src/hsv.rs
+++ b/palette/src/hsv.rs
@@ -8,9 +8,12 @@ use core::ops::{Add, AddAssign, Sub, SubAssign};
 use encoding::pixel::RawPixel;
 use encoding::{Linear, Srgb};
 use rgb::{Rgb, RgbSpace};
-use {cast, clamp};
+use {clamp, from_f64};
 use {Alpha, Hsl, Hwb, Xyz};
-use {Component, FromColor, GetHue, Hue, Limited, Mix, Pixel, RgbHue, Saturate, Shade};
+use {
+    Component, FloatComponent, FromColor, FromF64, GetHue, Hue, Limited, Mix, Pixel, RgbHue,
+    Saturate, Shade,
+};
 
 /// Linear HSV with an alpha component. See the [`Hsva` implementation in
 /// `Alpha`](struct.Alpha.html#Hsva).
@@ -34,7 +37,7 @@ pub type Hsva<S = Srgb, T = f32> = Alpha<Hsv<S, T>, T>;
 #[repr(C)]
 pub struct Hsv<S = Srgb, T = f32>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     ///The hue of the color, in degrees. Decides if it's red, blue, purple,
@@ -60,14 +63,14 @@ where
 
 impl<S, T> Copy for Hsv<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
 }
 
 impl<S, T> Clone for Hsv<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     fn clone(&self) -> Hsv<S, T> {
@@ -77,7 +80,7 @@ where
 
 impl<T> Hsv<Srgb, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
 {
     ///HSV for linear sRGB.
     pub fn new<H: Into<RgbHue<T>>>(hue: H, saturation: T, value: T) -> Hsv<Srgb, T> {
@@ -92,7 +95,7 @@ where
 
 impl<S, T> Hsv<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     ///Linear HSV.
@@ -132,16 +135,12 @@ where
             let (max, min, sep, coeff) = if rgb.red > rgb.green {
                 (rgb.red, rgb.green, rgb.green - rgb.blue, T::zero())
             } else {
-                (rgb.green, rgb.red, rgb.blue - rgb.red, cast(2.0))
+                (rgb.green, rgb.red, rgb.blue - rgb.red, from_f64(2.0))
             };
             if rgb.blue > max {
-                (rgb.blue, min, rgb.red - rgb.green, cast(4.0))
+                (rgb.blue, min, rgb.red - rgb.green, from_f64(4.0))
             } else {
-                let min_val = if rgb.blue < min {
-                    rgb.blue
-                } else {
-                    min
-                };
+                let min_val = if rgb.blue < min { rgb.blue } else { min };
                 (max, min_val, sep, coeff)
             }
         };
@@ -153,7 +152,7 @@ where
         if max != min {
             let d = max - min;
             s = d / max;
-            h = ((sep / d) + coeff) * cast(60.0);
+            h = ((sep / d) + coeff) * from_f64(60.0);
         };
 
         Hsv {
@@ -178,7 +177,7 @@ where
 ///<span id="Hsva"></span>[`Hsva`](type.Hsva.html) implementations.
 impl<T, A> Alpha<Hsv<Srgb, T>, A>
 where
-    T: Component + Float,
+    T: FloatComponent,
     A: Component,
 {
     ///HSV and transparency for linear sRGB.
@@ -193,7 +192,7 @@ where
 ///<span id="Hsva"></span>[`Hsva`](type.Hsva.html) implementations.
 impl<S, T, A> Alpha<Hsv<S, T>, A>
 where
-    T: Component + Float,
+    T: FloatComponent,
     A: Component,
     S: RgbSpace,
 {
@@ -220,7 +219,7 @@ where
 
 impl<S, T> From<Xyz<S::WhitePoint, T>> for Hsv<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     fn from(color: Xyz<S::WhitePoint, T>) -> Self {
@@ -231,24 +230,25 @@ where
 
 impl<S, Sp, T> From<Hsl<Sp, T>> for Hsv<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
     Sp: RgbSpace<WhitePoint = S::WhitePoint>,
 {
     fn from(color: Hsl<Sp, T>) -> Self {
         let hsl = Hsl::<S, T>::from_hsl(color);
 
-        let x = hsl.saturation * if hsl.lightness < cast(0.5) {
-            hsl.lightness
-        } else {
-            T::one() - hsl.lightness
-        };
+        let x = hsl.saturation
+            * if hsl.lightness < from_f64(0.5) {
+                hsl.lightness
+            } else {
+                T::one() - hsl.lightness
+            };
         let mut s = T::zero();
 
         // avoid divide by zero
         let denom = hsl.lightness + x;
         if denom.is_normal() {
-            s = x * cast(2.0) / denom;
+            s = x * from_f64(2.0) / denom;
         }
         Hsv {
             hue: hsl.hue,
@@ -261,7 +261,7 @@ where
 
 impl<S, Sp, T> From<Hwb<Sp, T>> for Hsv<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
     Sp: RgbSpace<WhitePoint = S::WhitePoint>,
 {
@@ -284,19 +284,19 @@ where
     }
 }
 
-impl<S: RgbSpace, T: Component + Float, H: Into<RgbHue<T>>> From<(H, T, T)> for Hsv<S, T> {
+impl<S: RgbSpace, T: FloatComponent, H: Into<RgbHue<T>>> From<(H, T, T)> for Hsv<S, T> {
     fn from(components: (H, T, T)) -> Self {
         Self::from_components(components)
     }
 }
 
-impl<S: RgbSpace, T: Component + Float> Into<(RgbHue<T>, T, T)> for Hsv<S, T> {
+impl<S: RgbSpace, T: FloatComponent> Into<(RgbHue<T>, T, T)> for Hsv<S, T> {
     fn into(self) -> (RgbHue<T>, T, T) {
         self.into_components()
     }
 }
 
-impl<S: RgbSpace, T: Component + Float, H: Into<RgbHue<T>>, A: Component> From<(H, T, T, A)>
+impl<S: RgbSpace, T: FloatComponent, H: Into<RgbHue<T>>, A: Component> From<(H, T, T, A)>
     for Alpha<Hsv<S, T>, A>
 {
     fn from(components: (H, T, T, A)) -> Self {
@@ -304,7 +304,7 @@ impl<S: RgbSpace, T: Component + Float, H: Into<RgbHue<T>>, A: Component> From<(
     }
 }
 
-impl<S: RgbSpace, T: Component + Float, A: Component> Into<(RgbHue<T>, T, T, A)>
+impl<S: RgbSpace, T: FloatComponent, A: Component> Into<(RgbHue<T>, T, T, A)>
     for Alpha<Hsv<S, T>, A>
 {
     fn into(self) -> (RgbHue<T>, T, T, A) {
@@ -314,7 +314,7 @@ impl<S: RgbSpace, T: Component + Float, A: Component> Into<(RgbHue<T>, T, T, A)>
 
 impl<S, T> Limited for Hsv<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     #[cfg_attr(rustfmt, rustfmt_skip)]
@@ -337,7 +337,7 @@ where
 
 impl<S, T> Mix for Hsv<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     type Scalar = T;
@@ -357,7 +357,7 @@ where
 
 impl<S, T> Shade for Hsv<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     type Scalar = T;
@@ -374,7 +374,7 @@ where
 
 impl<S, T> GetHue for Hsv<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     type Hue = RgbHue<T>;
@@ -390,7 +390,7 @@ where
 
 impl<S, T> Hue for Hsv<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     fn with_hue<H: Into<Self::Hue>>(&self, hue: H) -> Hsv<S, T> {
@@ -414,7 +414,7 @@ where
 
 impl<S, T> Saturate for Hsv<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     type Scalar = T;
@@ -431,7 +431,7 @@ where
 
 impl<S, T> Default for Hsv<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     fn default() -> Hsv<S, T> {
@@ -441,7 +441,7 @@ where
 
 impl<S, T> Add<Hsv<S, T>> for Hsv<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     type Output = Hsv<S, T>;
@@ -458,12 +458,12 @@ where
 
 impl<S, T> Add<T> for Hsv<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     type Output = Hsv<S, T>;
 
-    fn add(self, c: T) -> Self::Output{
+    fn add(self, c: T) -> Self::Output {
         Hsv {
             hue: self.hue + c,
             saturation: self.saturation + c,
@@ -474,9 +474,9 @@ where
 }
 
 impl<S, T> AddAssign<Hsv<S, T>> for Hsv<S, T>
-    where
-        T: Component + Float + AddAssign,
-        S: RgbSpace,
+where
+    T: FloatComponent + AddAssign,
+    S: RgbSpace,
 {
     fn add_assign(&mut self, other: Hsv<S, T>) {
         self.hue += other.hue;
@@ -486,9 +486,9 @@ impl<S, T> AddAssign<Hsv<S, T>> for Hsv<S, T>
 }
 
 impl<S, T> AddAssign<T> for Hsv<S, T>
-    where
-        T: Component + Float + AddAssign,
-        S: RgbSpace,
+where
+    T: FloatComponent + AddAssign,
+    S: RgbSpace,
 {
     fn add_assign(&mut self, c: T) {
         self.hue += c;
@@ -499,7 +499,7 @@ impl<S, T> AddAssign<T> for Hsv<S, T>
 
 impl<S, T> Sub<Hsv<S, T>> for Hsv<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     type Output = Hsv<S, T>;
@@ -516,7 +516,7 @@ where
 
 impl<S, T> Sub<T> for Hsv<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     type Output = Hsv<S, T>;
@@ -532,9 +532,9 @@ where
 }
 
 impl<S, T> SubAssign<Hsv<S, T>> for Hsv<S, T>
-    where
-        T: Component + Float + SubAssign,
-        S: RgbSpace,
+where
+    T: FloatComponent + SubAssign,
+    S: RgbSpace,
 {
     fn sub_assign(&mut self, other: Hsv<S, T>) {
         self.hue -= other.hue;
@@ -544,9 +544,9 @@ impl<S, T> SubAssign<Hsv<S, T>> for Hsv<S, T>
 }
 
 impl<S, T> SubAssign<T> for Hsv<S, T>
-    where
-        T: Component + Float + SubAssign,
-        S: RgbSpace,
+where
+    T: FloatComponent + SubAssign,
+    S: RgbSpace,
 {
     fn sub_assign(&mut self, c: T) {
         self.hue -= c;
@@ -557,7 +557,7 @@ impl<S, T> SubAssign<T> for Hsv<S, T>
 
 impl<S, T, P> AsRef<P> for Hsv<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
     P: RawPixel<T> + ?Sized,
 {
@@ -568,7 +568,7 @@ where
 
 impl<S, T, P> AsMut<P> for Hsv<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
     P: RawPixel<T> + ?Sized,
 {
@@ -579,8 +579,8 @@ where
 
 impl<S, T> AbsDiffEq for Hsv<S, T>
 where
-    T: Component + Float + AbsDiffEq,
-    T::Epsilon: Copy + Float,
+    T: FloatComponent + AbsDiffEq,
+    T::Epsilon: Copy + Float + FromF64,
     S: RgbSpace + PartialEq,
 {
     type Epsilon = T::Epsilon;
@@ -590,16 +590,16 @@ where
     }
 
     fn abs_diff_eq(&self, other: &Self, epsilon: T::Epsilon) -> bool {
-        self.hue.abs_diff_eq(&other.hue, epsilon) &&
-            self.saturation.abs_diff_eq(&other.saturation, epsilon) &&
-            self.value.abs_diff_eq(&other.value, epsilon)
+        self.hue.abs_diff_eq(&other.hue, epsilon)
+            && self.saturation.abs_diff_eq(&other.saturation, epsilon)
+            && self.value.abs_diff_eq(&other.value, epsilon)
     }
 }
 
 impl<S, T> RelativeEq for Hsv<S, T>
 where
-    T: Component + Float + RelativeEq,
-    T::Epsilon: Copy + Float,
+    T: FloatComponent + RelativeEq,
+    T::Epsilon: Copy + Float + FromF64,
     S: RgbSpace + PartialEq,
 {
     fn default_max_relative() -> Self::Epsilon {
@@ -621,8 +621,8 @@ where
 
 impl<S, T> UlpsEq for Hsv<S, T>
 where
-    T: Component + Float + UlpsEq,
-    T::Epsilon: Copy + Float,
+    T: FloatComponent + UlpsEq,
+    T::Epsilon: Copy + Float + FromF64,
     S: RgbSpace + PartialEq,
 {
     fn default_max_ulps() -> u32 {
@@ -695,7 +695,7 @@ mod test {
 
     #[test]
     fn ranges() {
-        assert_ranges!{
+        assert_ranges! {
             Hsv<Srgb, f64>;
             limited {
                 saturation: 0.0 => 1.0,
diff --git a/palette/src/hues.rs b/palette/src/hues.rs
index 42148c0cd..657d4d04e 100644
--- a/palette/src/hues.rs
+++ b/palette/src/hues.rs
@@ -1,10 +1,8 @@
 use float::Float;
 
-use core::f64::consts::PI;
 use core::cmp::PartialEq;
 use core::ops::{Add, AddAssign, Sub, SubAssign};
-
-use cast;
+use {from_f64, FromF64};
 
 macro_rules! make_hues {
     ($($(#[$doc:meta])+ struct $name:ident;)+) => ($(
@@ -20,7 +18,7 @@ macro_rules! make_hues {
         #[repr(C)]
         pub struct $name<T: Float = f32>(T);
 
-        impl<T: Float> $name<T> {
+        impl<T: Float + FromF64> $name<T> {
             /// Create a new hue from degrees.
             #[inline]
             pub fn from_degrees(degrees: T) -> $name<T> {
@@ -30,7 +28,7 @@ macro_rules! make_hues {
             /// Create a new hue from radians, instead of degrees.
             #[inline]
             pub fn from_radians(radians: T) -> $name<T> {
-                $name(radians * cast(180.0) / cast(PI))
+                $name(radians.to_degrees())
             }
 
             /// Get the hue as degrees, in the range `(-180, 180]`.
@@ -42,7 +40,7 @@ macro_rules! make_hues {
             /// Convert the hue to radians, in the range `(-π, π]`.
             #[inline]
             pub fn to_radians(self) -> T {
-                normalize_angle(self.0) * cast(PI) / cast(180.0)
+                normalize_angle(self.0).to_radians()
             }
 
             /// Convert the hue to positive degrees, in the range `[0, 360)`.
@@ -54,7 +52,7 @@ macro_rules! make_hues {
             /// Convert the hue to positive radians, in the range `[0, 2π)`.
             #[inline]
             pub fn to_positive_radians(self) -> T {
-                normalize_angle_positive(self.0) * cast(PI) / cast(180.0)
+                normalize_angle_positive(self.0).to_radians()
             }
 
             /// Get the internal representation, without normalizing it.
@@ -66,7 +64,7 @@ macro_rules! make_hues {
             /// Get the internal representation as radians, without normalizing it.
             #[inline]
             pub fn to_raw_radians(self) -> T {
-                self.0 * cast(PI) / cast(180.0)
+                self.0.to_radians()
             }
         }
 
@@ -97,7 +95,7 @@ macro_rules! make_hues {
             }
         }
 
-        impl<T: Float> PartialEq for $name<T> {
+        impl<T: Float + FromF64> PartialEq for $name<T> {
             #[inline]
             fn eq(&self, other: &$name<T>) -> bool {
                 let hue_s: T = (*self).to_degrees();
@@ -106,7 +104,7 @@ macro_rules! make_hues {
             }
         }
 
-        impl<T: Float> PartialEq<T> for $name<T> {
+        impl<T: Float + FromF64> PartialEq<T> for $name<T> {
             #[inline]
             fn eq(&self, other: &T) -> bool {
                 let hue: T = (*self).to_degrees();
@@ -213,7 +211,7 @@ macro_rules! make_hues {
                 $name(self - other.0)
             }
         }
-        
+
         impl<T: Float + SubAssign> SubAssign<$name<T>> for $name<T> {
             #[inline]
             fn sub_assign(&mut self, other: $name<T>) {
@@ -260,22 +258,22 @@ make_hues! {
 }
 
 #[inline]
-fn normalize_angle<T: Float>(deg: T) -> T {
-    let c360 = cast(360.0);
-    let c180 = cast(180.0);
+fn normalize_angle<T: Float + FromF64>(deg: T) -> T {
+    let c360 = from_f64(360.0);
+    let c180 = from_f64(180.0);
     deg - (((deg + c180) / c360) - T::one()).ceil() * c360
 }
 
 #[inline]
-fn normalize_angle_positive<T: Float>(deg: T) -> T {
-    let c360 = cast(360.0);
+fn normalize_angle_positive<T: Float + FromF64>(deg: T) -> T {
+    let c360 = from_f64(360.0);
     deg - ((deg / c360).floor() * c360)
 }
 
 #[cfg(test)]
 mod test {
-    use RgbHue;
     use super::{normalize_angle, normalize_angle_positive};
+    use RgbHue;
 
     #[test]
     fn normalize_angle_0_360() {
diff --git a/palette/src/hwb.rs b/palette/src/hwb.rs
index d8f375a88..042b47319 100644
--- a/palette/src/hwb.rs
+++ b/palette/src/hwb.rs
@@ -9,8 +9,8 @@ use encoding::pixel::RawPixel;
 use encoding::Srgb;
 use rgb::RgbSpace;
 use {
-    clamp, Alpha, Component, FromColor, GetHue, Hsv, Hue, IntoColor, Limited, Mix, Pixel, RgbHue,
-    Shade, Xyz,
+    clamp, Alpha, Component, FloatComponent, FromColor, FromF64, GetHue, Hsv, Hue, IntoColor,
+    Limited, Mix, Pixel, RgbHue, Shade, Xyz,
 };
 
 /// Linear HWB with an alpha component. See the [`Hwba` implementation in
@@ -36,7 +36,7 @@ pub type Hwba<S = Srgb, T = f32> = Alpha<Hwb<S, T>, T>;
 #[repr(C)]
 pub struct Hwb<S = Srgb, T = f32>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     ///The hue of the color, in degrees. Decides if it's red, blue, purple,
@@ -66,14 +66,14 @@ where
 
 impl<S, T> Copy for Hwb<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
 }
 
 impl<S, T> Clone for Hwb<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     fn clone(&self) -> Hwb<S, T> {
@@ -83,7 +83,7 @@ where
 
 impl<T> Hwb<Srgb, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
 {
     ///HWB for linear sRGB.
     pub fn new<H: Into<RgbHue<T>>>(hue: H, whiteness: T, blackness: T) -> Hwb<Srgb, T> {
@@ -98,7 +98,7 @@ where
 
 impl<S, T> Hwb<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     ///Linear HWB.
@@ -143,7 +143,7 @@ where
 ///<span id="Hwba"></span>[`Hwba`](type.Hwba.html) implementations.
 impl<T, A> Alpha<Hwb<Srgb, T>, A>
 where
-    T: Component + Float,
+    T: FloatComponent,
     A: Component,
 {
     ///HWB and transparency for linear sRGB.
@@ -158,7 +158,7 @@ where
 ///<span id="Hwba"></span>[`Hwba`](type.Hwba.html) implementations.
 impl<S, T, A> Alpha<Hwb<S, T>, A>
 where
-    T: Component + Float,
+    T: FloatComponent,
     A: Component,
     S: RgbSpace,
 {
@@ -185,7 +185,7 @@ where
 
 impl<S, T> From<Xyz<S::WhitePoint, T>> for Hwb<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     fn from(color: Xyz<S::WhitePoint, T>) -> Self {
@@ -196,7 +196,7 @@ where
 
 impl<S, T, Sp> From<Hsv<Sp, T>> for Hwb<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
     Sp: RgbSpace<WhitePoint = S::WhitePoint>,
 {
@@ -212,19 +212,19 @@ where
     }
 }
 
-impl<S: RgbSpace, T: Component + Float, H: Into<RgbHue<T>>> From<(H, T, T)> for Hwb<S, T> {
+impl<S: RgbSpace, T: FloatComponent, H: Into<RgbHue<T>>> From<(H, T, T)> for Hwb<S, T> {
     fn from(components: (H, T, T)) -> Self {
         Self::from_components(components)
     }
 }
 
-impl<S: RgbSpace, T: Component + Float> Into<(RgbHue<T>, T, T)> for Hwb<S, T> {
+impl<S: RgbSpace, T: FloatComponent> Into<(RgbHue<T>, T, T)> for Hwb<S, T> {
     fn into(self) -> (RgbHue<T>, T, T) {
         self.into_components()
     }
 }
 
-impl<S: RgbSpace, T: Component + Float, H: Into<RgbHue<T>>, A: Component> From<(H, T, T, A)>
+impl<S: RgbSpace, T: FloatComponent, H: Into<RgbHue<T>>, A: Component> From<(H, T, T, A)>
     for Alpha<Hwb<S, T>, A>
 {
     fn from(components: (H, T, T, A)) -> Self {
@@ -232,7 +232,7 @@ impl<S: RgbSpace, T: Component + Float, H: Into<RgbHue<T>>, A: Component> From<(
     }
 }
 
-impl<S: RgbSpace, T: Component + Float, A: Component> Into<(RgbHue<T>, T, T, A)>
+impl<S: RgbSpace, T: FloatComponent, A: Component> Into<(RgbHue<T>, T, T, A)>
     for Alpha<Hwb<S, T>, A>
 {
     fn into(self) -> (RgbHue<T>, T, T, A) {
@@ -242,7 +242,7 @@ impl<S: RgbSpace, T: Component + Float, A: Component> Into<(RgbHue<T>, T, T, A)>
 
 impl<S, T> Limited for Hwb<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     #[cfg_attr(rustfmt, rustfmt_skip)]
@@ -271,7 +271,7 @@ where
 
 impl<S, T> Mix for Hwb<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     type Scalar = T;
@@ -291,7 +291,7 @@ where
 
 impl<S, T> Shade for Hwb<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     type Scalar = T;
@@ -308,7 +308,7 @@ where
 
 impl<S, T> GetHue for Hwb<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     type Hue = RgbHue<T>;
@@ -324,7 +324,7 @@ where
 
 impl<S, T> Hue for Hwb<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     fn with_hue<H: Into<Self::Hue>>(&self, hue: H) -> Hwb<S, T> {
@@ -348,7 +348,7 @@ where
 
 impl<S, T> Default for Hwb<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     fn default() -> Hwb<S, T> {
@@ -358,7 +358,7 @@ where
 
 impl<S, T> Add<Hwb<S, T>> for Hwb<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     type Output = Hwb<S, T>;
@@ -375,7 +375,7 @@ where
 
 impl<S, T> Add<T> for Hwb<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     type Output = Hwb<S, T>;
@@ -391,9 +391,9 @@ where
 }
 
 impl<S, T> AddAssign<Hwb<S, T>> for Hwb<S, T>
-    where
-        T: Component + Float + AddAssign,
-        S: RgbSpace,
+where
+    T: FloatComponent + AddAssign,
+    S: RgbSpace,
 {
     fn add_assign(&mut self, other: Hwb<S, T>) {
         self.hue += other.hue;
@@ -403,9 +403,9 @@ impl<S, T> AddAssign<Hwb<S, T>> for Hwb<S, T>
 }
 
 impl<S, T> AddAssign<T> for Hwb<S, T>
-    where
-        T: Component + Float + AddAssign,
-        S: RgbSpace,
+where
+    T: FloatComponent + AddAssign,
+    S: RgbSpace,
 {
     fn add_assign(&mut self, c: T) {
         self.hue += c;
@@ -416,7 +416,7 @@ impl<S, T> AddAssign<T> for Hwb<S, T>
 
 impl<S, T> Sub<Hwb<S, T>> for Hwb<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     type Output = Hwb<S, T>;
@@ -433,7 +433,7 @@ where
 
 impl<S, T> Sub<T> for Hwb<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
 {
     type Output = Hwb<S, T>;
@@ -448,11 +448,10 @@ where
     }
 }
 
-
 impl<S, T> SubAssign<Hwb<S, T>> for Hwb<S, T>
-    where
-        T: Component + Float + SubAssign,
-        S: RgbSpace,
+where
+    T: FloatComponent + SubAssign,
+    S: RgbSpace,
 {
     fn sub_assign(&mut self, other: Hwb<S, T>) {
         self.hue -= other.hue;
@@ -462,9 +461,9 @@ impl<S, T> SubAssign<Hwb<S, T>> for Hwb<S, T>
 }
 
 impl<S, T> SubAssign<T> for Hwb<S, T>
-    where
-        T: Component + Float + SubAssign,
-        S: RgbSpace,
+where
+    T: FloatComponent + SubAssign,
+    S: RgbSpace,
 {
     fn sub_assign(&mut self, c: T) {
         self.hue -= c;
@@ -475,7 +474,7 @@ impl<S, T> SubAssign<T> for Hwb<S, T>
 
 impl<S, T, P> AsRef<P> for Hwb<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
     P: RawPixel<T> + ?Sized,
 {
@@ -486,7 +485,7 @@ where
 
 impl<S, T, P> AsMut<P> for Hwb<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: RgbSpace,
     P: RawPixel<T> + ?Sized,
 {
@@ -497,8 +496,8 @@ where
 
 impl<S, T> AbsDiffEq for Hwb<S, T>
 where
-    T: Component + Float + AbsDiffEq,
-    T::Epsilon: Copy + Float,
+    T: FloatComponent + AbsDiffEq,
+    T::Epsilon: Copy + Float + FromF64,
     S: RgbSpace + PartialEq,
 {
     type Epsilon = T::Epsilon;
@@ -508,12 +507,8 @@ where
     }
 
     fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
-        let equal_shade = self
-            .whiteness
-            .abs_diff_eq(&other.whiteness, epsilon)
-            && self
-            .blackness
-            .abs_diff_eq(&other.blackness, epsilon);
+        let equal_shade = self.whiteness.abs_diff_eq(&other.whiteness, epsilon)
+            && self.blackness.abs_diff_eq(&other.blackness, epsilon);
 
         // The hue doesn't matter that much when the color is gray, and may fluctuate
         // due to precision errors. This is a blunt tool, but works for now.
@@ -529,8 +524,8 @@ where
 
 impl<S, T> RelativeEq for Hwb<S, T>
 where
-    T: Component + Float + RelativeEq,
-    T::Epsilon: Copy + Float,
+    T: FloatComponent + RelativeEq,
+    T::Epsilon: Copy + Float + FromF64,
     S: RgbSpace + PartialEq,
 {
     fn default_max_relative() -> Self::Epsilon {
@@ -547,8 +542,8 @@ where
             .whiteness
             .relative_eq(&other.whiteness, epsilon, max_relative)
             && self
-            .blackness
-            .relative_eq(&other.blackness, epsilon, max_relative);
+                .blackness
+                .relative_eq(&other.blackness, epsilon, max_relative);
 
         // The hue doesn't matter that much when the color is gray, and may fluctuate
         // due to precision errors. This is a blunt tool, but works for now.
@@ -564,8 +559,8 @@ where
 
 impl<S, T> UlpsEq for Hwb<S, T>
 where
-    T: Component + Float + UlpsEq,
-    T::Epsilon: Copy + Float,
+    T: FloatComponent + UlpsEq,
+    T::Epsilon: Copy + Float + FromF64,
     S: RgbSpace + PartialEq,
 {
     fn default_max_ulps() -> u32 {
@@ -573,12 +568,8 @@ where
     }
 
     fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
-        let equal_shade = self
-            .whiteness
-            .ulps_eq(&other.whiteness, epsilon, max_ulps)
-            && self
-            .blackness
-            .ulps_eq(&other.blackness, epsilon, max_ulps);
+        let equal_shade = self.whiteness.ulps_eq(&other.whiteness, epsilon, max_ulps)
+            && self.blackness.ulps_eq(&other.blackness, epsilon, max_ulps);
 
         // The hue doesn't matter that much when the color is gray, and may fluctuate
         // due to precision errors. This is a blunt tool, but works for now.
diff --git a/palette/src/lab.rs b/palette/src/lab.rs
index 8ae7af8d3..6e18c9a2f 100644
--- a/palette/src/lab.rs
+++ b/palette/src/lab.rs
@@ -1,13 +1,11 @@
-use float::Float;
-
 use core::marker::PhantomData;
 use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
 
 use encoding::pixel::RawPixel;
-use white_point::{D65, WhitePoint};
-use {cast, clamp};
+use white_point::{WhitePoint, D65};
+use {clamp, from_f64};
 use {Alpha, LabHue, Lch, Xyz};
-use {Component, ComponentWise, GetHue, Limited, Mix, Pixel, Shade};
+use {Component, ComponentWise, FloatComponent, GetHue, Limited, Mix, Pixel, Shade};
 
 /// CIE L\*a\*b\* (CIELAB) with an alpha component. See the [`Laba`
 /// implementation in `Alpha`](struct.Alpha.html#Laba).
@@ -33,7 +31,7 @@ pub type Laba<Wp, T = f32> = Alpha<Lab<Wp, T>, T>;
 #[repr(C)]
 pub struct Lab<Wp = D65, T = f32>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     ///L\* is the lightness of the color. 0.0 gives absolute black and 100
@@ -55,14 +53,14 @@ where
 
 impl<Wp, T> Copy for Lab<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
 }
 
 impl<Wp, T> Clone for Lab<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     fn clone(&self) -> Lab<Wp, T> {
@@ -72,7 +70,7 @@ where
 
 impl<T> Lab<D65, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
 {
     ///CIE L\*a\*b\* with white point D65.
     pub fn new(l: T, a: T, b: T) -> Lab<D65, T> {
@@ -87,7 +85,7 @@ where
 
 impl<Wp, T> Lab<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     ///CIE L\*a\*b\*.
@@ -114,7 +112,7 @@ where
 ///<span id="Laba"></span>[`Laba`](type.Laba.html) implementations.
 impl<T, A> Alpha<Lab<D65, T>, A>
 where
-    T: Component + Float,
+    T: FloatComponent,
     A: Component,
 {
     ///CIE L\*a\*b\* and transparency and white point D65.
@@ -129,7 +127,7 @@ where
 ///<span id="Laba"></span>[`Laba`](type.Laba.html) implementations.
 impl<Wp, T, A> Alpha<Lab<Wp, T>, A>
 where
-    T: Component + Float,
+    T: FloatComponent,
     A: Component,
     Wp: WhitePoint,
 {
@@ -154,7 +152,7 @@ where
 
 impl<Wp, T> From<Xyz<Wp, T>> for Lab<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     fn from(color: Xyz<Wp, T>) -> Self {
@@ -165,10 +163,10 @@ where
             ..
         } = color / Wp::get_xyz();
 
-        fn convert<T: Component + Float>(c: T) -> T {
-            let epsilon: T = (cast::<T, _>(6.0 / 29.0)).powi(3);
-            let kappa: T = cast(841.0 / 108.0);
-            let delta: T = cast(4.0 / 29.0);
+        fn convert<T: FloatComponent>(c: T) -> T {
+            let epsilon = from_f64::<T>(6.0 / 29.0).powi(3);
+            let kappa: T = from_f64(841.0 / 108.0);
+            let delta: T = from_f64(4.0 / 29.0);
             if c > epsilon {
                 c.cbrt()
             } else {
@@ -181,9 +179,9 @@ where
         z = convert(z);
 
         Lab {
-            l: ((y * cast(116.0)) - cast(16.0)),
-            a: ((x - y) * cast(500.0)),
-            b: ((y - z) * cast(200.0)),
+            l: ((y * from_f64(116.0)) - from_f64(16.0)),
+            a: ((x - y) * from_f64(500.0)),
+            b: ((y - z) * from_f64(200.0)),
             white_point: PhantomData,
         }
     }
@@ -191,7 +189,7 @@ where
 
 impl<Wp, T> From<Lch<Wp, T>> for Lab<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     fn from(color: Lch<Wp, T>) -> Self {
@@ -204,29 +202,25 @@ where
     }
 }
 
-impl<Wp: WhitePoint, T: Component + Float> From<(T, T, T)> for Lab<Wp, T> {
+impl<Wp: WhitePoint, T: FloatComponent> From<(T, T, T)> for Lab<Wp, T> {
     fn from(components: (T, T, T)) -> Self {
         Self::from_components(components)
     }
 }
 
-impl<Wp: WhitePoint, T: Component + Float> Into<(T, T, T)> for Lab<Wp, T> {
+impl<Wp: WhitePoint, T: FloatComponent> Into<(T, T, T)> for Lab<Wp, T> {
     fn into(self) -> (T, T, T) {
         self.into_components()
     }
 }
 
-impl<Wp: WhitePoint, T: Component + Float, A: Component> From<(T, T, T, A)>
-    for Alpha<Lab<Wp, T>, A>
-{
+impl<Wp: WhitePoint, T: FloatComponent, A: Component> From<(T, T, T, A)> for Alpha<Lab<Wp, T>, A> {
     fn from(components: (T, T, T, A)) -> Self {
         Self::from_components(components)
     }
 }
 
-impl<Wp: WhitePoint, T: Component + Float, A: Component> Into<(T, T, T, A)>
-    for Alpha<Lab<Wp, T>, A>
-{
+impl<Wp: WhitePoint, T: FloatComponent, A: Component> Into<(T, T, T, A)> for Alpha<Lab<Wp, T>, A> {
     fn into(self) -> (T, T, T, A) {
         self.into_components()
     }
@@ -234,14 +228,14 @@ impl<Wp: WhitePoint, T: Component + Float, A: Component> Into<(T, T, T, A)>
 
 impl<Wp, T> Limited for Lab<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     #[cfg_attr(rustfmt, rustfmt_skip)]
     fn is_valid(&self) -> bool {
-        self.l >= T::zero() && self.l <= cast(100.0) &&
-        self.a >= cast(-128) && self.a <= cast(127.0) &&
-        self.b >= cast(-128) && self.b <= cast(127.0)
+        self.l >= T::zero() && self.l <= from_f64(100.0) &&
+        self.a >= from_f64(-128.0) && self.a <= from_f64(127.0) &&
+        self.b >= from_f64(-128.0) && self.b <= from_f64(127.0)
     }
 
     fn clamp(&self) -> Lab<Wp, T> {
@@ -251,15 +245,15 @@ where
     }
 
     fn clamp_self(&mut self) {
-        self.l = clamp(self.l, T::zero(), cast(100.0));
-        self.a = clamp(self.a, cast(-128.0), cast(127.0));
-        self.b = clamp(self.b, cast(-128.0), cast(127.0));
+        self.l = clamp(self.l, T::zero(), from_f64(100.0));
+        self.a = clamp(self.a, from_f64(-128.0), from_f64(127.0));
+        self.b = clamp(self.b, from_f64(-128.0), from_f64(127.0));
     }
 }
 
 impl<Wp, T> Mix for Lab<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Scalar = T;
@@ -278,14 +272,14 @@ where
 
 impl<Wp, T> Shade for Lab<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Scalar = T;
 
     fn lighten(&self, amount: T) -> Lab<Wp, T> {
         Lab {
-            l: self.l + amount * cast(100.0),
+            l: self.l + amount * from_f64(100.0),
             a: self.a,
             b: self.b,
             white_point: PhantomData,
@@ -295,7 +289,7 @@ where
 
 impl<Wp, T> GetHue for Lab<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Hue = LabHue<T>;
@@ -311,7 +305,7 @@ where
 
 impl<Wp, T> ComponentWise for Lab<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Scalar = T;
@@ -337,7 +331,7 @@ where
 
 impl<Wp, T> Default for Lab<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     fn default() -> Lab<Wp, T> {
@@ -347,7 +341,7 @@ where
 
 impl<Wp, T> Add<Lab<Wp, T>> for Lab<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Lab<Wp, T>;
@@ -364,7 +358,7 @@ where
 
 impl<Wp, T> Add<T> for Lab<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Lab<Wp, T>;
@@ -380,9 +374,9 @@ where
 }
 
 impl<Wp, T> AddAssign<Lab<Wp, T>> for Lab<Wp, T>
-    where
-        T: Component + Float + AddAssign,
-        Wp: WhitePoint,
+where
+    T: FloatComponent + AddAssign,
+    Wp: WhitePoint,
 {
     fn add_assign(&mut self, other: Lab<Wp, T>) {
         self.l += other.l;
@@ -392,9 +386,9 @@ impl<Wp, T> AddAssign<Lab<Wp, T>> for Lab<Wp, T>
 }
 
 impl<Wp, T> AddAssign<T> for Lab<Wp, T>
-    where
-        T: Component + Float + AddAssign,
-        Wp: WhitePoint,
+where
+    T: FloatComponent + AddAssign,
+    Wp: WhitePoint,
 {
     fn add_assign(&mut self, c: T) {
         self.l += c;
@@ -405,7 +399,7 @@ impl<Wp, T> AddAssign<T> for Lab<Wp, T>
 
 impl<Wp, T> Sub<Lab<Wp, T>> for Lab<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Lab<Wp, T>;
@@ -422,7 +416,7 @@ where
 
 impl<Wp, T> Sub<T> for Lab<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Lab<Wp, T>;
@@ -438,21 +432,21 @@ where
 }
 
 impl<Wp, T> SubAssign<Lab<Wp, T>> for Lab<Wp, T>
-    where
-        T: Component + Float + SubAssign,
-        Wp: WhitePoint,
+where
+    T: FloatComponent + SubAssign,
+    Wp: WhitePoint,
 {
     fn sub_assign(&mut self, other: Lab<Wp, T>) {
-         self.l -= other.l;
-         self.a -= other.a;
-         self.b -= other.b;
+        self.l -= other.l;
+        self.a -= other.a;
+        self.b -= other.b;
     }
 }
 
 impl<Wp, T> SubAssign<T> for Lab<Wp, T>
-    where
-        T: Component + Float + SubAssign,
-        Wp: WhitePoint,
+where
+    T: FloatComponent + SubAssign,
+    Wp: WhitePoint,
 {
     fn sub_assign(&mut self, c: T) {
         self.l -= c;
@@ -463,7 +457,7 @@ impl<Wp, T> SubAssign<T> for Lab<Wp, T>
 
 impl<Wp, T> Mul<Lab<Wp, T>> for Lab<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Lab<Wp, T>;
@@ -480,7 +474,7 @@ where
 
 impl<Wp, T> Mul<T> for Lab<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Lab<Wp, T>;
@@ -496,9 +490,9 @@ where
 }
 
 impl<Wp, T> MulAssign<Lab<Wp, T>> for Lab<Wp, T>
-    where
-        T: Component + Float + MulAssign,
-        Wp: WhitePoint,
+where
+    T: FloatComponent + MulAssign,
+    Wp: WhitePoint,
 {
     fn mul_assign(&mut self, other: Lab<Wp, T>) {
         self.l *= other.l;
@@ -508,9 +502,9 @@ impl<Wp, T> MulAssign<Lab<Wp, T>> for Lab<Wp, T>
 }
 
 impl<Wp, T> MulAssign<T> for Lab<Wp, T>
-    where
-        T: Component + Float + MulAssign,
-        Wp: WhitePoint,
+where
+    T: FloatComponent + MulAssign,
+    Wp: WhitePoint,
 {
     fn mul_assign(&mut self, c: T) {
         self.l *= c;
@@ -521,7 +515,7 @@ impl<Wp, T> MulAssign<T> for Lab<Wp, T>
 
 impl<Wp, T> Div<Lab<Wp, T>> for Lab<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Lab<Wp, T>;
@@ -538,7 +532,7 @@ where
 
 impl<Wp, T> Div<T> for Lab<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Lab<Wp, T>;
@@ -554,9 +548,9 @@ where
 }
 
 impl<Wp, T> DivAssign<Lab<Wp, T>> for Lab<Wp, T>
-    where
-        T: Component + Float + DivAssign,
-        Wp: WhitePoint,
+where
+    T: FloatComponent + DivAssign,
+    Wp: WhitePoint,
 {
     fn div_assign(&mut self, other: Lab<Wp, T>) {
         self.l /= other.l;
@@ -566,9 +560,9 @@ impl<Wp, T> DivAssign<Lab<Wp, T>> for Lab<Wp, T>
 }
 
 impl<Wp, T> DivAssign<T> for Lab<Wp, T>
-    where
-        T: Component + Float + DivAssign,
-        Wp: WhitePoint,
+where
+    T: FloatComponent + DivAssign,
+    Wp: WhitePoint,
 {
     fn div_assign(&mut self, c: T) {
         self.l /= c;
@@ -579,7 +573,7 @@ impl<Wp, T> DivAssign<T> for Lab<Wp, T>
 
 impl<Wp, T, P> AsRef<P> for Lab<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
     P: RawPixel<T> + ?Sized,
 {
@@ -590,7 +584,7 @@ where
 
 impl<Wp, T, P> AsMut<P> for Lab<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
     P: RawPixel<T> + ?Sized,
 {
@@ -628,7 +622,7 @@ mod test {
 
     #[test]
     fn ranges() {
-        assert_ranges!{
+        assert_ranges! {
             Lab<D65, f64>;
             limited {
                 l: 0.0 => 100.0,
diff --git a/palette/src/lch.rs b/palette/src/lch.rs
index 13b06bf67..3cf705d94 100644
--- a/palette/src/lch.rs
+++ b/palette/src/lch.rs
@@ -1,13 +1,13 @@
-use float::Float;
-
 use core::marker::PhantomData;
 use core::ops::{Add, AddAssign, Sub, SubAssign};
 
 use encoding::pixel::RawPixel;
-use white_point::{D65, WhitePoint};
-use {cast, clamp};
+use white_point::{WhitePoint, D65};
+use {clamp, from_f64};
 use {Alpha, Hue, Lab, LabHue, Xyz};
-use {Component, FromColor, GetHue, IntoColor, Limited, Mix, Pixel, Saturate, Shade};
+use {
+    Component, FloatComponent, FromColor, GetHue, IntoColor, Limited, Mix, Pixel, Saturate, Shade,
+};
 
 /// CIE L\*C\*h° with an alpha component. See the [`Lcha` implementation in
 /// `Alpha`](struct.Alpha.html#Lcha).
@@ -28,7 +28,7 @@ pub type Lcha<Wp, T = f32> = Alpha<Lch<Wp, T>, T>;
 #[repr(C)]
 pub struct Lch<Wp = D65, T = f32>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     ///L\* is the lightness of the color. 0.0 gives absolute black and 100.0
@@ -55,14 +55,14 @@ where
 
 impl<Wp, T> Copy for Lch<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
 }
 
 impl<Wp, T> Clone for Lch<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     fn clone(&self) -> Lch<Wp, T> {
@@ -72,7 +72,7 @@ where
 
 impl<T> Lch<D65, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
 {
     ///CIE L\*C\*h° with white point D65.
     pub fn new<H: Into<LabHue<T>>>(l: T, chroma: T, hue: H) -> Lch<D65, T> {
@@ -87,7 +87,7 @@ where
 
 impl<Wp, T> Lch<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     ///CIE L\*C\*h°.
@@ -114,7 +114,7 @@ where
 ///<span id="Lcha"></span>[`Lcha`](type.Lcha.html) implementations.
 impl<T, A> Alpha<Lch<D65, T>, A>
 where
-    T: Component + Float,
+    T: FloatComponent,
     A: Component,
 {
     ///CIE L\*C\*h° and transparency with white point D65.
@@ -129,7 +129,7 @@ where
 ///<span id="Lcha"></span>[`Lcha`](type.Lcha.html) implementations.
 impl<Wp, T, A> Alpha<Lch<Wp, T>, A>
 where
-    T: Component + Float,
+    T: FloatComponent,
     A: Component,
     Wp: WhitePoint,
 {
@@ -154,7 +154,7 @@ where
 
 impl<Wp, T> From<Xyz<Wp, T>> for Lch<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     fn from(color: Xyz<Wp, T>) -> Self {
@@ -165,7 +165,7 @@ where
 
 impl<Wp, T> From<Lab<Wp, T>> for Lch<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     fn from(color: Lab<Wp, T>) -> Self {
@@ -178,19 +178,19 @@ where
     }
 }
 
-impl<Wp: WhitePoint, T: Component + Float, H: Into<LabHue<T>>> From<(T, T, H)> for Lch<Wp, T> {
+impl<Wp: WhitePoint, T: FloatComponent, H: Into<LabHue<T>>> From<(T, T, H)> for Lch<Wp, T> {
     fn from(components: (T, T, H)) -> Self {
         Self::from_components(components)
     }
 }
 
-impl<Wp: WhitePoint, T: Component + Float> Into<(T, T, LabHue<T>)> for Lch<Wp, T> {
+impl<Wp: WhitePoint, T: FloatComponent> Into<(T, T, LabHue<T>)> for Lch<Wp, T> {
     fn into(self) -> (T, T, LabHue<T>) {
         self.into_components()
     }
 }
 
-impl<Wp: WhitePoint, T: Component + Float, H: Into<LabHue<T>>, A: Component> From<(T, T, H, A)>
+impl<Wp: WhitePoint, T: FloatComponent, H: Into<LabHue<T>>, A: Component> From<(T, T, H, A)>
     for Alpha<Lch<Wp, T>, A>
 {
     fn from(components: (T, T, H, A)) -> Self {
@@ -198,7 +198,7 @@ impl<Wp: WhitePoint, T: Component + Float, H: Into<LabHue<T>>, A: Component> Fro
     }
 }
 
-impl<Wp: WhitePoint, T: Component + Float, A: Component> Into<(T, T, LabHue<T>, A)>
+impl<Wp: WhitePoint, T: FloatComponent, A: Component> Into<(T, T, LabHue<T>, A)>
     for Alpha<Lch<Wp, T>, A>
 {
     fn into(self) -> (T, T, LabHue<T>, A) {
@@ -208,11 +208,11 @@ impl<Wp: WhitePoint, T: Component + Float, A: Component> Into<(T, T, LabHue<T>,
 
 impl<Wp, T> Limited for Lch<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     fn is_valid(&self) -> bool {
-        self.l >= T::zero() && self.l <= cast(100.0) && self.chroma >= T::zero()
+        self.l >= T::zero() && self.l <= from_f64(100.0) && self.chroma >= T::zero()
     }
 
     fn clamp(&self) -> Lch<Wp, T> {
@@ -222,14 +222,14 @@ where
     }
 
     fn clamp_self(&mut self) {
-        self.l = clamp(self.l, T::zero(), cast(100.0));
+        self.l = clamp(self.l, T::zero(), from_f64(100.0));
         self.chroma = self.chroma.max(T::zero())
     }
 }
 
 impl<Wp, T> Mix for Lch<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Scalar = T;
@@ -248,14 +248,14 @@ where
 
 impl<Wp, T> Shade for Lch<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Scalar = T;
 
     fn lighten(&self, amount: T) -> Lch<Wp, T> {
         Lch {
-            l: self.l + amount * cast(100.0),
+            l: self.l + amount * from_f64(100.0),
             chroma: self.chroma,
             hue: self.hue,
             white_point: PhantomData,
@@ -265,7 +265,7 @@ where
 
 impl<Wp, T> GetHue for Lch<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Hue = LabHue<T>;
@@ -281,7 +281,7 @@ where
 
 impl<Wp, T> Hue for Lch<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     fn with_hue<H: Into<Self::Hue>>(&self, hue: H) -> Lch<Wp, T> {
@@ -305,7 +305,7 @@ where
 
 impl<Wp, T> Saturate for Lch<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Scalar = T;
@@ -322,7 +322,7 @@ where
 
 impl<Wp, T> Default for Lch<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     fn default() -> Lch<Wp, T> {
@@ -332,7 +332,7 @@ where
 
 impl<Wp, T> Add<Lch<Wp, T>> for Lch<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Lch<Wp, T>;
@@ -349,7 +349,7 @@ where
 
 impl<Wp, T> Add<T> for Lch<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Lch<Wp, T>;
@@ -366,7 +366,7 @@ where
 
 impl<Wp, T> AddAssign<Lch<Wp, T>> for Lch<Wp, T>
 where
-    T: Component + Float + AddAssign,
+    T: FloatComponent + AddAssign,
     Wp: WhitePoint,
 {
     fn add_assign(&mut self, other: Lch<Wp, T>) {
@@ -377,9 +377,9 @@ where
 }
 
 impl<Wp, T> AddAssign<T> for Lch<Wp, T>
-    where
-        T: Component + Float + AddAssign,
-        Wp: WhitePoint,
+where
+    T: FloatComponent + AddAssign,
+    Wp: WhitePoint,
 {
     fn add_assign(&mut self, c: T) {
         self.l += c;
@@ -390,7 +390,7 @@ impl<Wp, T> AddAssign<T> for Lch<Wp, T>
 
 impl<Wp, T> Sub<Lch<Wp, T>> for Lch<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Lch<Wp, T>;
@@ -407,7 +407,7 @@ where
 
 impl<Wp, T> Sub<T> for Lch<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Lch<Wp, T>;
@@ -424,7 +424,7 @@ where
 
 impl<Wp, T> SubAssign<Lch<Wp, T>> for Lch<Wp, T>
 where
-    T: Component + Float + SubAssign,
+    T: FloatComponent + SubAssign,
     Wp: WhitePoint,
 {
     fn sub_assign(&mut self, other: Lch<Wp, T>) {
@@ -436,7 +436,7 @@ where
 
 impl<Wp, T> SubAssign<T> for Lch<Wp, T>
 where
-    T: Component + Float + SubAssign,
+    T: FloatComponent + SubAssign,
     Wp: WhitePoint,
 {
     fn sub_assign(&mut self, c: T) {
@@ -448,7 +448,7 @@ where
 
 impl<Wp, T, P> AsRef<P> for Lch<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
     P: RawPixel<T> + ?Sized,
 {
@@ -459,7 +459,7 @@ where
 
 impl<Wp, T, P> AsMut<P> for Lch<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
     P: RawPixel<T> + ?Sized,
 {
@@ -475,7 +475,7 @@ mod test {
 
     #[test]
     fn ranges() {
-        assert_ranges!{
+        assert_ranges! {
             Lch<D65, f64>;
             limited {
                 l: 0.0 => 100.0
diff --git a/palette/src/lib.rs b/palette/src/lib.rs
index d78d493db..1e93d7212 100644
--- a/palette/src/lib.rs
+++ b/palette/src/lib.rs
@@ -137,7 +137,6 @@
 
 // Keep the standard library when running tests, too
 #![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
-
 #![doc(html_root_url = "https://docs.rs/palette/0.5.0/palette/")]
 #![cfg_attr(feature = "strict", deny(missing_docs))]
 #![cfg_attr(feature = "strict", deny(warnings))]
@@ -162,7 +161,6 @@ extern crate serde;
 #[cfg(all(test, feature = "serializing"))]
 extern crate serde_json;
 
-use num_traits::{NumCast, ToPrimitive, Zero};
 use float::Float;
 
 use luma::Luma;
@@ -185,7 +183,8 @@ pub use rgb::{GammaSrgb, GammaSrgba, LinSrgb, LinSrgba, Srgb, Srgba};
 pub use xyz::{Xyz, Xyza};
 pub use yxy::{Yxy, Yxya};
 
-pub use convert::{ConvertFrom, ConvertInto, OutOfBounds, FromColor, IntoColor};
+pub use component::*;
+pub use convert::{ConvertFrom, ConvertInto, FromColor, IntoColor, OutOfBounds};
 pub use encoding::pixel::Pixel;
 pub use hues::{LabHue, RgbHue};
 pub use matrix::Mat3;
@@ -341,7 +340,6 @@ macro_rules! assert_ranges {
     );
 }
 
-
 #[macro_use]
 mod macros;
 
@@ -366,6 +364,7 @@ mod yxy;
 mod hues;
 
 pub mod chromatic_adaptation;
+mod component;
 mod convert;
 pub mod encoding;
 mod equality;
@@ -544,135 +543,28 @@ pub trait ComponentWise {
     fn component_wise_self<F: FnMut(Self::Scalar) -> Self::Scalar>(&self, f: F) -> Self;
 }
 
-/// Common trait for color components.
-pub trait Component: Copy + Zero + PartialOrd + NumCast {
-    /// True if the max intensity is also the highest possible value of the
-    /// type. Conversion to limited types requires clamping.
-    const LIMITED: bool;
-
-    /// The highest displayable value this component type can reach. Higher
-    /// values are allowed, but they may be lowered to this before
-    /// converting to another format.
-    fn max_intensity() -> Self;
-
-    /// Convert into another color component type, including scaling.
-    fn convert<T: Component>(&self) -> T;
-}
-
-impl Component for f32 {
-    const LIMITED: bool = false;
-
-    fn max_intensity() -> Self {
-        1.0
-    }
-
-    fn convert<T: Component>(&self) -> T {
-        let scaled = *self * cast::<f32, _>(T::max_intensity());
-
-        if T::LIMITED {
-            cast(clamp(Float::round(scaled), 0.0, cast(T::max_intensity())))
-        } else {
-            cast(scaled)
-        }
-    }
-}
-
-impl Component for f64 {
-    const LIMITED: bool = false;
-
-    fn max_intensity() -> Self {
-        1.0
-    }
-
-    fn convert<T: Component>(&self) -> T {
-        let scaled = *self * cast::<f64, _>(T::max_intensity());
-
-        if T::LIMITED {
-            cast(clamp(Float::round(scaled), 0.0, cast(T::max_intensity())))
-        } else {
-            cast(scaled)
-        }
-    }
-}
-
-impl Component for u8 {
-    const LIMITED: bool = true;
-
-    fn max_intensity() -> Self {
-        core::u8::MAX
-    }
-
-    fn convert<T: Component>(&self) -> T {
-        let scaled = cast::<f64, _>(T::max_intensity())
-            * (cast::<f64, _>(*self) / cast::<f64, _>(Self::max_intensity()));
-
-        if T::LIMITED {
-            cast(clamp(Float::round(scaled), 0.0, cast(T::max_intensity())))
-        } else {
-            cast(scaled)
-        }
-    }
-}
-
-impl Component for u16 {
-    const LIMITED: bool = true;
-
-    fn max_intensity() -> Self {
-        core::u16::MAX
-    }
-
-    fn convert<T: Component>(&self) -> T {
-        let scaled = cast::<f64, _>(T::max_intensity())
-            * (cast::<f64, _>(*self) / cast::<f64, _>(Self::max_intensity()));
-
-        if T::LIMITED {
-            cast(clamp(Float::round(scaled), 0.0, cast(T::max_intensity())))
-        } else {
-            cast(scaled)
-        }
-    }
+/// A trait for infallible conversion from `f64`. The conversion may be lossy.
+pub trait FromF64 {
+    /// Creates a value from an `f64` constant.
+    fn from_f64(c: f64) -> Self;
 }
 
-impl Component for u32 {
-    const LIMITED: bool = true;
-
-    fn max_intensity() -> Self {
-        core::u32::MAX
-    }
-
-    fn convert<T: Component>(&self) -> T {
-        let scaled = cast::<f64, _>(T::max_intensity())
-            * (cast::<f64, _>(*self) / cast::<f64, _>(Self::max_intensity()));
-
-        if T::LIMITED {
-            cast(clamp(Float::round(scaled), 0.0, cast(T::max_intensity())))
-        } else {
-            cast(scaled)
-        }
+impl FromF64 for f32 {
+    #[inline]
+    fn from_f64(c: f64) -> Self {
+        c as f32
     }
 }
 
-impl Component for u64 {
-    const LIMITED: bool = true;
-
-    fn max_intensity() -> Self {
-        core::u64::MAX
-    }
-
-    fn convert<T: Component>(&self) -> T {
-        let scaled = cast::<f64, _>(T::max_intensity())
-            * (cast::<f64, _>(*self) / cast::<f64, _>(Self::max_intensity()));
-
-        if T::LIMITED {
-            cast(clamp(Float::round(scaled), 0.0, cast(T::max_intensity())))
-        } else {
-            cast(scaled)
-        }
+impl FromF64 for f64 {
+    #[inline]
+    fn from_f64(c: f64) -> Self {
+        c
     }
 }
 
 /// A convenience function to convert a constant number to Float Type
 #[inline]
-fn cast<T: NumCast, P: ToPrimitive>(prim: P) -> T {
-    NumCast::from(prim).unwrap()
+fn from_f64<T: FromF64>(c: f64) -> T {
+    T::from_f64(c)
 }
diff --git a/palette/src/luma/luma.rs b/palette/src/luma/luma.rs
index b8e9bae12..35dc64075 100644
--- a/palette/src/luma/luma.rs
+++ b/palette/src/luma/luma.rs
@@ -4,8 +4,6 @@ use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
 
 use approx::{AbsDiffEq, RelativeEq, UlpsEq};
 
-use float::Float;
-
 use blend::PreAlpha;
 use clamp;
 use encoding::linear::LinearFn;
@@ -14,7 +12,10 @@ use encoding::{Linear, Srgb, TransferFn};
 use luma::LumaStandard;
 use white_point::WhitePoint;
 use {Alpha, Xyz, Yxy};
-use {Blend, Component, ComponentWise, FromColor, IntoColor, Limited, Mix, Pixel, Shade};
+use {
+    Blend, Component, ComponentWise, FloatComponent, FromColor, FromComponent, IntoColor, Limited,
+    Mix, Pixel, Shade,
+};
 
 /// Luminance with an alpha component. See the [`Lumaa` implementation
 /// in `Alpha`](struct.Alpha.html#Lumaa).
@@ -79,15 +80,22 @@ where
     }
 
     /// Convert into another component type.
-    pub fn into_format<U: Component>(self) -> Luma<S, U> {
+    pub fn into_format<U>(self) -> Luma<S, U>
+    where
+        U: Component + FromComponent<T>,
+    {
         Luma {
-            luma: self.luma.convert(),
+            luma: U::from_component(self.luma),
             standard: PhantomData,
         }
     }
 
     /// Convert from another component type.
-    pub fn from_format<U: Component>(color: Luma<S, U>) -> Self {
+    pub fn from_format<U>(color: Luma<S, U>) -> Self
+    where
+        U: Component,
+        T: FromComponent<U>,
+    {
         color.into_format()
     }
 
@@ -104,7 +112,7 @@ where
 
 impl<S, T> Luma<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: LumaStandard,
 {
     /// Convert the color to linear luminance.
@@ -150,12 +158,22 @@ where
     }
 
     /// Convert into another component type.
-    pub fn into_format<U: Component, B: Component>(self) -> Alpha<Luma<S, U>, B> {
-        Alpha::<Luma<S, U>, B>::new(self.luma.convert(), self.alpha.convert())
+    pub fn into_format<U, B>(self) -> Alpha<Luma<S, U>, B>
+    where
+        U: Component + FromComponent<T>,
+        B: Component + FromComponent<A>,
+    {
+        Alpha::<Luma<S, U>, B>::new(U::from_component(self.luma), B::from_component(self.alpha))
     }
 
     /// Convert from another component type.
-    pub fn from_format<U: Component, B: Component>(color: Alpha<Luma<S, U>, B>) -> Self {
+    pub fn from_format<U, B>(color: Alpha<Luma<S, U>, B>) -> Self
+    where
+        T: FromComponent<U>,
+        U: Component,
+        A: FromComponent<B>,
+        B: Component,
+    {
         color.into_format()
     }
 
@@ -173,7 +191,7 @@ where
 ///<span id="Lumaa"></span>[`Lumaa`](type.Lumaa.html) implementations.
 impl<S, T, A> Alpha<Luma<S, T>, A>
 where
-    T: Component + Float,
+    T: FloatComponent,
     A: Component,
     S: LumaStandard,
 {
@@ -214,7 +232,7 @@ where
 impl<S, T> From<Xyz<S::WhitePoint, T>> for Luma<S, T>
 where
     S: LumaStandard,
-    T: Component + Float,
+    T: FloatComponent,
 {
     fn from(color: Xyz<S::WhitePoint, T>) -> Self {
         Self::from_linear(Luma {
@@ -227,7 +245,7 @@ where
 impl<S, T> From<Yxy<S::WhitePoint, T>> for Luma<S, T>
 where
     S: LumaStandard,
-    T: Component + Float,
+    T: FloatComponent,
 {
     fn from(color: Yxy<S::WhitePoint, T>) -> Self {
         Self::from_linear(Luma {
@@ -264,7 +282,7 @@ impl<S: LumaStandard, T: Component, A: Component> Into<(T, A)> for Alpha<Luma<S,
 impl<S, Wp, T> IntoColor<Wp, T> for Luma<S, T>
 where
     S: LumaStandard<WhitePoint = Wp>,
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     fn into_xyz(self) -> Xyz<Wp, T> {
@@ -302,7 +320,7 @@ where
 
 impl<S, T> Mix for Luma<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: LumaStandard<TransferFn = LinearFn>,
 {
     type Scalar = T;
@@ -319,7 +337,7 @@ where
 
 impl<S, T> Shade for Luma<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: LumaStandard<TransferFn = LinearFn>,
 {
     type Scalar = T;
@@ -334,7 +352,7 @@ where
 
 impl<S, T> Blend for Luma<S, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: LumaStandard<TransferFn = LinearFn>,
 {
     type Color = Luma<S, T>;
@@ -714,7 +732,7 @@ mod test {
 
     #[test]
     fn ranges() {
-        assert_ranges!{
+        assert_ranges! {
             Luma<Srgb, f64>;
             limited {
                 luma: 0.0 => 1.0
diff --git a/palette/src/matrix.rs b/palette/src/matrix.rs
index b6ac8da97..8bdddde0e 100644
--- a/palette/src/matrix.rs
+++ b/palette/src/matrix.rs
@@ -5,17 +5,17 @@ use float::Float;
 
 use core::marker::PhantomData;
 
-use {Component, Xyz};
-use white_point::WhitePoint;
-use rgb::{Primaries, Rgb, RgbSpace};
-use encoding::Linear;
 use convert::IntoColor;
+use encoding::Linear;
+use rgb::{Primaries, Rgb, RgbSpace};
+use white_point::WhitePoint;
+use {FloatComponent, Xyz};
 
 ///A 9 element array representing a 3x3 matrix
 pub type Mat3<T> = [T; 9];
 
 ///Multiply the 3x3 matrix with the XYZ color
-pub fn multiply_xyz<Swp: WhitePoint, Dwp: WhitePoint, T: Component + Float>(
+pub fn multiply_xyz<Swp: WhitePoint, Dwp: WhitePoint, T: FloatComponent>(
     c: &Mat3<T>,
     f: &Xyz<Swp, T>,
 ) -> Xyz<Dwp, T> {
@@ -27,7 +27,7 @@ pub fn multiply_xyz<Swp: WhitePoint, Dwp: WhitePoint, T: Component + Float>(
     }
 }
 ///Multiply the 3x3 matrix with the XYZ color into RGB color
-pub fn multiply_xyz_to_rgb<S: RgbSpace, T: Component + Float>(
+pub fn multiply_xyz_to_rgb<S: RgbSpace, T: FloatComponent>(
     c: &Mat3<T>,
     f: &Xyz<S::WhitePoint, T>,
 ) -> Rgb<Linear<S>, T> {
@@ -39,7 +39,7 @@ pub fn multiply_xyz_to_rgb<S: RgbSpace, T: Component + Float>(
     }
 }
 ///Multiply the 3x3 matrix with the  RGB into XYZ color
-pub fn multiply_rgb_to_xyz<S: RgbSpace, T: Component + Float>(
+pub fn multiply_rgb_to_xyz<S: RgbSpace, T: FloatComponent>(
     c: &Mat3<T>,
     f: &Rgb<Linear<S>, T>,
 ) -> Xyz<S::WhitePoint, T> {
@@ -99,7 +99,7 @@ pub fn matrix_inverse<T: Float>(a: &Mat3<T>) -> Mat3<T> {
 }
 
 ///Geneartes to Srgb to Xyz transformation matrix for the given white point
-pub fn rgb_to_xyz_matrix<S: RgbSpace, T: Component + Float>() -> Mat3<T> {
+pub fn rgb_to_xyz_matrix<S: RgbSpace, T: FloatComponent>() -> Mat3<T> {
     let r: Xyz<S::WhitePoint, T> = S::Primaries::red().into_xyz();
     let g: Xyz<S::WhitePoint, T> = S::Primaries::green().into_xyz();
     let b: Xyz<S::WhitePoint, T> = S::Primaries::blue().into_xyz();
@@ -124,7 +124,7 @@ pub fn rgb_to_xyz_matrix<S: RgbSpace, T: Component + Float>() -> Mat3<T> {
 }
 
 #[cfg_attr(rustfmt, rustfmt_skip)]
-fn mat3_from_primaries<T: Component + Float, Wp: WhitePoint>(r: Xyz<Wp, T>, g: Xyz<Wp, T>, b: Xyz<Wp, T>) -> Mat3<T> {
+fn mat3_from_primaries<T: FloatComponent, Wp: WhitePoint>(r: Xyz<Wp, T>, g: Xyz<Wp, T>, b: Xyz<Wp, T>) -> Mat3<T> {
     [
         r.x, g.x, b.x,
         r.y, g.y, b.y,
@@ -134,12 +134,12 @@ fn mat3_from_primaries<T: Component + Float, Wp: WhitePoint>(r: Xyz<Wp, T>, g: X
 
 #[cfg(test)]
 mod test {
-    use Xyz;
-    use rgb::Rgb;
-    use encoding::{Linear, Srgb};
+    use super::{matrix_inverse, multiply_3x3, multiply_xyz, rgb_to_xyz_matrix};
     use chromatic_adaptation::AdaptInto;
+    use encoding::{Linear, Srgb};
+    use rgb::Rgb;
     use white_point::D50;
-    use super::{matrix_inverse, multiply_xyz, rgb_to_xyz_matrix, multiply_3x3};
+    use Xyz;
 
     #[test]
     fn matrix_multiply_3x3() {
diff --git a/palette/src/rgb/mod.rs b/palette/src/rgb/mod.rs
index 9deb3d683..c09691b9b 100644
--- a/palette/src/rgb/mod.rs
+++ b/palette/src/rgb/mod.rs
@@ -1,10 +1,9 @@
 //!RGB types, spaces and standards.
 
-use float::Float;
 use core::any::Any;
 
-use {Component, Yxy};
 use white_point::WhitePoint;
+use {Component, FloatComponent, FromComponent, Yxy};
 
 use encoding::{Linear, TransferFn};
 
@@ -64,17 +63,17 @@ impl<P: Primaries, W: WhitePoint> RgbSpace for (P, W) {
 ///Represents the red, green and blue primaries of an RGB space.
 pub trait Primaries: Any {
     ///Primary red.
-    fn red<Wp: WhitePoint, T: Component + Float>() -> Yxy<Wp, T>;
+    fn red<Wp: WhitePoint, T: FloatComponent>() -> Yxy<Wp, T>;
     ///Primary green.
-    fn green<Wp: WhitePoint, T: Component + Float>() -> Yxy<Wp, T>;
+    fn green<Wp: WhitePoint, T: FloatComponent>() -> Yxy<Wp, T>;
     ///Primary blue.
-    fn blue<Wp: WhitePoint, T: Component + Float>() -> Yxy<Wp, T>;
+    fn blue<Wp: WhitePoint, T: FloatComponent>() -> Yxy<Wp, T>;
 }
 
 impl<T, U> From<LinSrgb<T>> for Srgb<U>
 where
-    T: Component + Float,
-    U: Component,
+    T: FloatComponent,
+    U: Component + FromComponent<T>,
 {
     fn from(lin_srgb: LinSrgb<T>) -> Self {
         let non_lin = Srgb::<T>::from_linear(lin_srgb);
@@ -84,19 +83,18 @@ where
 
 impl<T, U> From<Srgb<T>> for LinSrgb<U>
 where
-    T: Component + Float,
-    U: Component,
+    T: FloatComponent,
+    U: Component + FromComponent<T>,
 {
     fn from(srgb: Srgb<T>) -> Self {
-        srgb.into_linear()
-            .into_format()
+        srgb.into_linear().into_format()
     }
 }
 
 impl<T, U> From<LinSrgb<T>> for Srgba<U>
 where
-    T: Component + Float,
-    U: Component,
+    T: FloatComponent,
+    U: Component + FromComponent<T>,
 {
     fn from(lin_srgb: LinSrgb<T>) -> Self {
         let non_lin = Srgb::<T>::from_linear(lin_srgb);
@@ -107,8 +105,8 @@ where
 
 impl<T, U> From<LinSrgba<T>> for Srgba<U>
 where
-    T: Component + Float,
-    U: Component,
+    T: FloatComponent,
+    U: Component + FromComponent<T>,
 {
     fn from(lin_srgba: LinSrgba<T>) -> Self {
         let non_lin = Srgba::<T>::from_linear(lin_srgba);
@@ -118,23 +116,20 @@ where
 
 impl<T, U> From<Srgb<T>> for LinSrgba<U>
 where
-    T: Component + Float,
-    U: Component,
+    T: FloatComponent,
+    U: Component + FromComponent<T>,
 {
     fn from(srgb: Srgb<T>) -> Self {
-        srgb.into_linear()
-            .into_format()
-            .into()
+        srgb.into_linear().into_format().into()
     }
 }
 
 impl<T, U> From<Srgba<T>> for LinSrgba<U>
 where
-    T: Component + Float,
-    U: Component,
+    T: FloatComponent,
+    U: Component + FromComponent<T>,
 {
     fn from(srgba: Srgba<T>) -> Self {
-        srgba.into_linear()
-            .into_format()
+        srgba.into_linear().into_format()
     }
 }
diff --git a/palette/src/rgb/rgb.rs b/palette/src/rgb/rgb.rs
index ba2273b3f..4f79323a4 100644
--- a/palette/src/rgb/rgb.rs
+++ b/palette/src/rgb/rgb.rs
@@ -1,12 +1,11 @@
 use core::any::TypeId;
 use core::fmt;
 use core::marker::PhantomData;
+use core::num::ParseIntError;
 use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
 use core::str::FromStr;
-use core::num::ParseIntError;
 
 use approx::{AbsDiffEq, RelativeEq, UlpsEq};
-use float::Float;
 
 use alpha::Alpha;
 use blend::PreAlpha;
@@ -18,8 +17,11 @@ use luma::LumaStandard;
 use matrix::{matrix_inverse, multiply_xyz_to_rgb, rgb_to_xyz_matrix};
 use rgb::{RgbSpace, RgbStandard, TransferFn};
 use white_point::WhitePoint;
-use {cast, clamp};
-use {Blend, Component, ComponentWise, GetHue, Limited, Mix, Pixel, Shade};
+use {clamp, from_f64};
+use {
+    Blend, Component, ComponentWise, FloatComponent, FromComponent, GetHue, Limited, Mix, Pixel,
+    Shade,
+};
 use {Hsl, Hsv, Hwb, Lab, Lch, Luma, RgbHue, Xyz, Yxy};
 
 /// Generic RGB with an alpha component. See the [`Rgba` implementation in
@@ -84,17 +86,24 @@ impl<S: RgbStandard, T: Component> Rgb<S, T> {
     }
 
     /// Convert into another component type.
-    pub fn into_format<U: Component>(self) -> Rgb<S, U> {
+    pub fn into_format<U>(self) -> Rgb<S, U>
+    where
+        U: Component + FromComponent<T>,
+    {
         Rgb {
-            red: self.red.convert(),
-            green: self.green.convert(),
-            blue: self.blue.convert(),
+            red: U::from_component(self.red),
+            green: U::from_component(self.green),
+            blue: U::from_component(self.blue),
             standard: PhantomData,
         }
     }
 
     /// Convert from another component type.
-    pub fn from_format<U: Component>(color: Rgb<S, U>) -> Self {
+    pub fn from_format<U>(color: Rgb<S, U>) -> Self
+    where
+        T: FromComponent<U>,
+        U: Component,
+    {
         color.into_format()
     }
 
@@ -109,7 +118,7 @@ impl<S: RgbStandard, T: Component> Rgb<S, T> {
     }
 }
 
-impl<S: RgbStandard, T: Component + Float> Rgb<S, T> {
+impl<S: RgbStandard, T: FloatComponent> Rgb<S, T> {
     /// Convert the color to linear RGB.
     pub fn into_linear(self) -> Rgb<Linear<S::Space>, T> {
         Rgb::new(
@@ -184,17 +193,27 @@ impl<S: RgbStandard, T: Component, A: Component> Alpha<Rgb<S, T>, A> {
     }
 
     /// Convert into another component type.
-    pub fn into_format<U: Component, B: Component>(self) -> Alpha<Rgb<S, U>, B> {
+    pub fn into_format<U, B>(self) -> Alpha<Rgb<S, U>, B>
+    where
+        U: Component + FromComponent<T>,
+        B: Component + FromComponent<A>,
+    {
         Alpha::<Rgb<S, U>, B>::new(
-            self.red.convert(),
-            self.green.convert(),
-            self.blue.convert(),
-            self.alpha.convert(),
+            U::from_component(self.red),
+            U::from_component(self.green),
+            U::from_component(self.blue),
+            B::from_component(self.alpha),
         )
     }
 
     /// Convert from another component type.
-    pub fn from_format<U: Component, B: Component>(color: Alpha<Rgb<S, U>, B>) -> Self {
+    pub fn from_format<U, B>(color: Alpha<Rgb<S, U>, B>) -> Self
+    where
+        T: FromComponent<U>,
+        U: Component,
+        A: FromComponent<B>,
+        B: Component,
+    {
         color.into_format()
     }
 
@@ -210,7 +229,7 @@ impl<S: RgbStandard, T: Component, A: Component> Alpha<Rgb<S, T>, A> {
 }
 
 /// <span id="Rgba"></span>[`Rgba`](rgb/type.Rgba.html) implementations.
-impl<S: RgbStandard, T: Component + Float, A: Component> Alpha<Rgb<S, T>, A> {
+impl<S: RgbStandard, T: FloatComponent, A: Component> Alpha<Rgb<S, T>, A> {
     /// Convert the color to linear RGB with transparency.
     pub fn into_linear(self) -> Alpha<Rgb<Linear<S::Space>, T>, A> {
         Alpha::<Rgb<Linear<S::Space>, T>, A>::new(
@@ -280,7 +299,7 @@ where
 impl<S, T> Mix for Rgb<S, T>
 where
     S: RgbStandard<TransferFn = LinearFn>,
-    T: Component + Float,
+    T: FloatComponent,
 {
     type Scalar = T;
 
@@ -299,7 +318,7 @@ where
 impl<S, T> Shade for Rgb<S, T>
 where
     S: RgbStandard<TransferFn = LinearFn>,
-    T: Component + Float,
+    T: FloatComponent,
 {
     type Scalar = T;
 
@@ -316,19 +335,19 @@ where
 impl<S, T> GetHue for Rgb<S, T>
 where
     S: RgbStandard<TransferFn = LinearFn>,
-    T: Component + Float,
+    T: FloatComponent,
 {
     type Hue = RgbHue<T>;
 
     fn get_hue(&self) -> Option<RgbHue<T>> {
-        let sqrt_3: T = cast(1.73205081);
+        let sqrt_3: T = from_f64(1.73205081);
 
         if self.red == self.green && self.red == self.blue {
             None
         } else {
             Some(RgbHue::from_radians(
                 (sqrt_3 * (self.green - self.blue))
-                    .atan2(self.red * cast(2.0) - self.green - self.blue),
+                    .atan2(self.red * from_f64(2.0) - self.green - self.blue),
             ))
         }
     }
@@ -337,7 +356,7 @@ where
 impl<S, T> Blend for Rgb<S, T>
 where
     S: RgbStandard<TransferFn = LinearFn>,
-    T: Component + Float,
+    T: FloatComponent,
 {
     type Color = Rgb<S, T>;
 
@@ -629,7 +648,7 @@ where
 impl<S, Wp, T> From<Xyz<Wp, T>> for Rgb<S, T>
 where
     S: RgbStandard,
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
     S::Space: RgbSpace<WhitePoint = Wp>,
 {
@@ -642,7 +661,7 @@ where
 impl<S, T, Sp, Wp> From<Hsl<Sp, T>> for Rgb<S, T>
 where
     S: RgbStandard,
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
     S::Space: RgbSpace<WhitePoint = Wp>,
     Sp: RgbSpace<WhitePoint = Wp>,
@@ -650,20 +669,20 @@ where
     fn from(color: Hsl<Sp, T>) -> Self {
         let hsl = Hsl::<S::Space, T>::from_hsl(color);
 
-        let c = (T::one() - (hsl.lightness * cast(2.0) - T::one()).abs()) * hsl.saturation;
-        let h = hsl.hue.to_positive_degrees() / cast(60.0);
-        let x = c * (T::one() - (h % cast(2.0) - T::one()).abs());
-        let m = hsl.lightness - c * cast(0.5);
+        let c = (T::one() - (hsl.lightness * from_f64(2.0) - T::one()).abs()) * hsl.saturation;
+        let h = hsl.hue.to_positive_degrees() / from_f64(60.0);
+        let x = c * (T::one() - (h % from_f64(2.0) - T::one()).abs());
+        let m = hsl.lightness - c * from_f64(0.5);
 
         let (red, green, blue) = if h >= T::zero() && h < T::one() {
             (c, x, T::zero())
-        } else if h >= T::one() && h < cast(2.0) {
+        } else if h >= T::one() && h < from_f64(2.0) {
             (x, c, T::zero())
-        } else if h >= cast(2.0) && h < cast(3.0) {
+        } else if h >= from_f64(2.0) && h < from_f64(3.0) {
             (T::zero(), c, x)
-        } else if h >= cast(3.0) && h < cast(4.0) {
+        } else if h >= from_f64(3.0) && h < from_f64(4.0) {
             (T::zero(), x, c)
-        } else if h >= cast(4.0) && h < cast(5.0) {
+        } else if h >= from_f64(4.0) && h < from_f64(5.0) {
             (x, T::zero(), c)
         } else {
             (c, T::zero(), x)
@@ -681,7 +700,7 @@ where
 impl<S, T, Sp, Wp> From<Hsv<Sp, T>> for Rgb<S, T>
 where
     S: RgbStandard,
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
     S::Space: RgbSpace<WhitePoint = Wp>,
     Sp: RgbSpace<WhitePoint = Wp>,
@@ -690,19 +709,19 @@ where
         let hsv = Hsv::<S::Space, T>::from_hsv(color);
 
         let c = hsv.value * hsv.saturation;
-        let h = hsv.hue.to_positive_degrees() / cast(60.0);
-        let x = c * (T::one() - (h % cast(2.0) - T::one()).abs());
+        let h = hsv.hue.to_positive_degrees() / from_f64(60.0);
+        let x = c * (T::one() - (h % from_f64(2.0) - T::one()).abs());
         let m = hsv.value - c;
 
         let (red, green, blue) = if h >= T::zero() && h < T::one() {
             (c, x, T::zero())
-        } else if h >= T::one() && h < cast(2.0) {
+        } else if h >= T::one() && h < from_f64(2.0) {
             (x, c, T::zero())
-        } else if h >= cast(2.0) && h < cast(3.0) {
+        } else if h >= from_f64(2.0) && h < from_f64(3.0) {
             (T::zero(), c, x)
-        } else if h >= cast(3.0) && h < cast(4.0) {
+        } else if h >= from_f64(3.0) && h < from_f64(4.0) {
             (T::zero(), x, c)
-        } else if h >= cast(4.0) && h < cast(5.0) {
+        } else if h >= from_f64(4.0) && h < from_f64(5.0) {
             (x, T::zero(), c)
         } else {
             (c, T::zero(), x)
@@ -720,7 +739,7 @@ where
 impl<S, T, St, Wp> From<Luma<St, T>> for Rgb<S, T>
 where
     S: RgbStandard,
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
     S::Space: RgbSpace<WhitePoint = Wp>,
     St: LumaStandard<WhitePoint = Wp>,
@@ -764,7 +783,7 @@ impl<S: RgbStandard, T: Component, A: Component> Into<(T, T, T, A)> for Alpha<Rg
 impl<S, T, Wp> IntoColor<Wp, T> for Rgb<S, T>
 where
     S: RgbStandard,
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
     S::Space: RgbSpace<WhitePoint = Wp>,
 {
@@ -827,9 +846,9 @@ where
     }
 
     fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
-        self.red.abs_diff_eq(&other.red, epsilon) &&
-            self.green.abs_diff_eq(&other.green, epsilon) &&
-            self.blue.abs_diff_eq(&other.blue, epsilon)
+        self.red.abs_diff_eq(&other.red, epsilon)
+            && self.green.abs_diff_eq(&other.green, epsilon)
+            && self.blue.abs_diff_eq(&other.blue, epsilon)
     }
 }
 
@@ -958,7 +977,7 @@ where
 #[derive(Debug)]
 pub enum FromHexError {
     ParseIntError(ParseIntError),
-    HexFormatError(&'static str)
+    HexFormatError(&'static str),
 }
 
 impl From<ParseIntError> for FromHexError {
@@ -975,18 +994,17 @@ impl From<&'static str> for FromHexError {
 impl core::fmt::Display for FromHexError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match &*self {
-            FromHexError::ParseIntError(e) => {
-                write!(f, "{}", e)
-            }
-            FromHexError::HexFormatError(s) => {
-                write!(f, "{}, please use format '#fff', 'fff', '#ffffff' or\
-                'ffffff'.", s)
-            }
+            FromHexError::ParseIntError(e) => write!(f, "{}", e),
+            FromHexError::HexFormatError(s) => write!(
+                f,
+                "{}, please use format '#fff', 'fff', '#ffffff' or 'ffffff'.",
+                s
+            ),
         }
     }
 }
 
-#[cfg(feature="std")]
+#[cfg(feature = "std")]
 impl std::error::Error for FromHexError {
     fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
         match &*self {
@@ -996,28 +1014,19 @@ impl std::error::Error for FromHexError {
     }
 }
 
-
 impl<S: RgbStandard> FromStr for Rgb<S, u8> {
     type Err = FromHexError;
 
     // Parses a color hex code of format '#ff00bb' or '#abc' into a
     // Rgb<S, u8> instance.
     fn from_str(hex: &str) -> Result<Self, Self::Err> {
-        let hex_code = if hex.starts_with('#') {
-            &hex[1..]
-        } else {
-            hex
-        };
+        let hex_code = if hex.starts_with('#') { &hex[1..] } else { hex };
         match hex_code.len() {
             3 => {
                 let red = u8::from_str_radix(&hex_code[..1], 16)?;
                 let green = u8::from_str_radix(&hex_code[1..2], 16)?;
                 let blue = u8::from_str_radix(&hex_code[2..3], 16)?;
-                let col: Rgb<S, u8> = Rgb::new(
-                    red * 17,
-                    green * 17,
-                    blue * 17,
-                );
+                let col: Rgb<S, u8> = Rgb::new(red * 17, green * 17, blue * 17);
                 Ok(col)
             }
             6 => {
@@ -1035,8 +1044,8 @@ impl<S: RgbStandard> FromStr for Rgb<S, u8> {
 #[cfg(test)]
 mod test {
     use super::Rgb;
-    use encoding::Srgb;
     use core::str::FromStr;
+    use encoding::Srgb;
 
     #[test]
     fn ranges() {
@@ -1166,44 +1175,44 @@ mod test {
     fn from_str() {
         let c = Rgb::<Srgb, u8>::from_str("#ffffff");
         assert!(c.is_ok());
-        assert_eq!(c.unwrap(), Rgb::<Srgb,u8>::new(255,255,255));
+        assert_eq!(c.unwrap(), Rgb::<Srgb, u8>::new(255, 255, 255));
         let c = Rgb::<Srgb, u8>::from_str("#gggggg");
         assert!(c.is_err());
-        let c = Rgb::<Srgb,u8>::from_str("#fff");
+        let c = Rgb::<Srgb, u8>::from_str("#fff");
         assert!(c.is_ok());
-        assert_eq!(c.unwrap(),Rgb::<Srgb,u8>::new(255,255,255));
-        let c = Rgb::<Srgb,u8>::from_str("#000000");
+        assert_eq!(c.unwrap(), Rgb::<Srgb, u8>::new(255, 255, 255));
+        let c = Rgb::<Srgb, u8>::from_str("#000000");
         assert!(c.is_ok());
-        assert_eq!(c.unwrap(), Rgb::<Srgb,u8>::new(0,0,0));
-        let c = Rgb::<Srgb,u8>::from_str("");
+        assert_eq!(c.unwrap(), Rgb::<Srgb, u8>::new(0, 0, 0));
+        let c = Rgb::<Srgb, u8>::from_str("");
         assert!(c.is_err());
-        let c = Rgb::<Srgb,u8>::from_str("#123456");
+        let c = Rgb::<Srgb, u8>::from_str("#123456");
         assert!(c.is_ok());
-        assert_eq!(c.unwrap(), Rgb::<Srgb,u8>::new(18, 52, 86));
-        let c = Rgb::<Srgb,u8>::from_str("#iii");
+        assert_eq!(c.unwrap(), Rgb::<Srgb, u8>::new(18, 52, 86));
+        let c = Rgb::<Srgb, u8>::from_str("#iii");
         assert!(c.is_err());
         assert_eq!(
             format!("{}", c.err().unwrap()),
             "invalid digit found in string"
         );
-        let c = Rgb::<Srgb,u8>::from_str("#08f");
-        assert_eq!(c.unwrap(), Rgb::<Srgb,u8>::new(0, 136, 255));
-        let c = Rgb::<Srgb,u8>::from_str("08f");
-        assert_eq!(c.unwrap(), Rgb::<Srgb,u8>::new(0, 136,255));
-        let c = Rgb::<Srgb,u8>::from_str("ffffff");
-        assert_eq!(c.unwrap(), Rgb::<Srgb,u8>::new(255,255,255));
-        let c = Rgb::<Srgb,u8>::from_str("#12");
+        let c = Rgb::<Srgb, u8>::from_str("#08f");
+        assert_eq!(c.unwrap(), Rgb::<Srgb, u8>::new(0, 136, 255));
+        let c = Rgb::<Srgb, u8>::from_str("08f");
+        assert_eq!(c.unwrap(), Rgb::<Srgb, u8>::new(0, 136, 255));
+        let c = Rgb::<Srgb, u8>::from_str("ffffff");
+        assert_eq!(c.unwrap(), Rgb::<Srgb, u8>::new(255, 255, 255));
+        let c = Rgb::<Srgb, u8>::from_str("#12");
         assert!(c.is_err());
         assert_eq!(
-            format!("{}", c.err().unwrap()), 
+            format!("{}", c.err().unwrap()),
             "invalid hex code format, \
-        please use format \'#fff\', \'fff\', \'#ffffff\' or\'ffffff\'."
+             please use format \'#fff\', \'fff\', \'#ffffff\' or \'ffffff\'."
         );
-        let c = Rgb::<Srgb,u8>::from_str("da0bce");
-        assert_eq!(c.unwrap(), Rgb::<Srgb,u8>::new(218,11,206));
-        let c = Rgb::<Srgb,u8>::from_str("f034e6");
-        assert_eq!(c.unwrap(), Rgb::<Srgb,u8>::new(240,52,230));
-        let c = Rgb::<Srgb,u8>::from_str("abc");
-        assert_eq!(c.unwrap(), Rgb::<Srgb,u8>::new(170,187,204));
+        let c = Rgb::<Srgb, u8>::from_str("da0bce");
+        assert_eq!(c.unwrap(), Rgb::<Srgb, u8>::new(218, 11, 206));
+        let c = Rgb::<Srgb, u8>::from_str("f034e6");
+        assert_eq!(c.unwrap(), Rgb::<Srgb, u8>::new(240, 52, 230));
+        let c = Rgb::<Srgb, u8>::from_str("abc");
+        assert_eq!(c.unwrap(), Rgb::<Srgb, u8>::new(170, 187, 204));
     }
 }
diff --git a/palette/src/white_point.rs b/palette/src/white_point.rs
index ff0c412c7..91408fd9d 100644
--- a/palette/src/white_point.rs
+++ b/palette/src/white_point.rs
@@ -6,9 +6,7 @@
 //! unacceptable results when attempting to color-correct a photograph taken with incandescent
 //! lighting.
 
-use float::Float;
-
-use {cast, Component, Xyz};
+use {from_f64, FloatComponent, Xyz};
 
 ///WhitePoint defines the Xyz color co-ordinates for a given white point.
 ///
@@ -20,7 +18,7 @@ use {cast, Component, Xyz};
 ///and can be used in place of the ones defined in this library.
 pub trait WhitePoint {
     ///Get the Xyz chromacity co-ordinates for the white point.
-    fn get_xyz<Wp: WhitePoint, T: Component + Float>() -> Xyz<Wp, T>;
+    fn get_xyz<Wp: WhitePoint, T: FloatComponent>() -> Xyz<Wp, T>;
 }
 
 /// CIE standard illuminant A
@@ -31,8 +29,8 @@ pub trait WhitePoint {
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct A;
 impl WhitePoint for A {
-    fn get_xyz<Wp: WhitePoint, T: Component + Float>() -> Xyz<Wp, T> {
-        Xyz::with_wp(cast(1.09850), T::one(), cast(0.35585))
+    fn get_xyz<Wp: WhitePoint, T: FloatComponent>() -> Xyz<Wp, T> {
+        Xyz::with_wp(from_f64(1.09850), T::one(), from_f64(0.35585))
     }
 }
 /// CIE standard illuminant B
@@ -42,8 +40,8 @@ impl WhitePoint for A {
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct B;
 impl WhitePoint for B {
-    fn get_xyz<Wp: WhitePoint, T: Component + Float>() -> Xyz<Wp, T> {
-        Xyz::with_wp(cast(0.99072), T::one(), cast(0.85223))
+    fn get_xyz<Wp: WhitePoint, T: FloatComponent>() -> Xyz<Wp, T> {
+        Xyz::with_wp(from_f64(0.99072), T::one(), from_f64(0.85223))
     }
 }
 ///CIE standard illuminant C
@@ -53,8 +51,8 @@ impl WhitePoint for B {
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct C;
 impl WhitePoint for C {
-    fn get_xyz<Wp: WhitePoint, T: Component + Float>() -> Xyz<Wp, T> {
-        Xyz::with_wp(cast(0.98074), T::one(), cast(1.18232))
+    fn get_xyz<Wp: WhitePoint, T: FloatComponent>() -> Xyz<Wp, T> {
+        Xyz::with_wp(from_f64(0.98074), T::one(), from_f64(1.18232))
     }
 }
 ///CIE D series standard illuminant - D50
@@ -64,8 +62,8 @@ impl WhitePoint for C {
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct D50;
 impl WhitePoint for D50 {
-    fn get_xyz<Wp: WhitePoint, T: Component + Float>() -> Xyz<Wp, T> {
-        Xyz::with_wp(cast(0.96422), T::one(), cast(0.82521))
+    fn get_xyz<Wp: WhitePoint, T: FloatComponent>() -> Xyz<Wp, T> {
+        Xyz::with_wp(from_f64(0.96422), T::one(), from_f64(0.82521))
     }
 }
 ///CIE D series standard illuminant - D55
@@ -75,8 +73,8 @@ impl WhitePoint for D50 {
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct D55;
 impl WhitePoint for D55 {
-    fn get_xyz<Wp: WhitePoint, T: Component + Float>() -> Xyz<Wp, T> {
-        Xyz::with_wp(cast(0.95682), T::one(), cast(0.92149))
+    fn get_xyz<Wp: WhitePoint, T: FloatComponent>() -> Xyz<Wp, T> {
+        Xyz::with_wp(from_f64(0.95682), T::one(), from_f64(0.92149))
     }
 }
 ///CIE D series standard illuminant - D65
@@ -86,8 +84,8 @@ impl WhitePoint for D55 {
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct D65;
 impl WhitePoint for D65 {
-    fn get_xyz<Wp: WhitePoint, T: Component + Float>() -> Xyz<Wp, T> {
-        Xyz::with_wp(cast(0.95047), T::one(), cast(1.08883))
+    fn get_xyz<Wp: WhitePoint, T: FloatComponent>() -> Xyz<Wp, T> {
+        Xyz::with_wp(from_f64(0.95047), T::one(), from_f64(1.08883))
     }
 }
 ///CIE D series standard illuminant - D75
@@ -97,8 +95,8 @@ impl WhitePoint for D65 {
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct D75;
 impl WhitePoint for D75 {
-    fn get_xyz<Wp: WhitePoint, T: Component + Float>() -> Xyz<Wp, T> {
-        Xyz::with_wp(cast(0.94972), T::one(), cast(1.22638))
+    fn get_xyz<Wp: WhitePoint, T: FloatComponent>() -> Xyz<Wp, T> {
+        Xyz::with_wp(from_f64(0.94972), T::one(), from_f64(1.22638))
     }
 }
 ///CIE standard illuminant E
@@ -108,7 +106,7 @@ impl WhitePoint for D75 {
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct E;
 impl WhitePoint for E {
-    fn get_xyz<Wp: WhitePoint, T: Component + Float>() -> Xyz<Wp, T> {
+    fn get_xyz<Wp: WhitePoint, T: FloatComponent>() -> Xyz<Wp, T> {
         Xyz::with_wp(T::one(), T::one(), T::one())
     }
 }
@@ -118,8 +116,8 @@ impl WhitePoint for E {
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct F2;
 impl WhitePoint for F2 {
-    fn get_xyz<Wp: WhitePoint, T: Component + Float>() -> Xyz<Wp, T> {
-        Xyz::with_wp(cast(0.99186), T::one(), cast(0.67393))
+    fn get_xyz<Wp: WhitePoint, T: FloatComponent>() -> Xyz<Wp, T> {
+        Xyz::with_wp(from_f64(0.99186), T::one(), from_f64(0.67393))
     }
 }
 ///CIE fluorescent illuminant series - F7
@@ -128,8 +126,8 @@ impl WhitePoint for F2 {
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct F7;
 impl WhitePoint for F7 {
-    fn get_xyz<Wp: WhitePoint, T: Component + Float>() -> Xyz<Wp, T> {
-        Xyz::with_wp(cast(0.95041), T::one(), cast(1.08747))
+    fn get_xyz<Wp: WhitePoint, T: FloatComponent>() -> Xyz<Wp, T> {
+        Xyz::with_wp(from_f64(0.95041), T::one(), from_f64(1.08747))
     }
 }
 ///CIE fluorescent illuminant series - F11
@@ -138,8 +136,8 @@ impl WhitePoint for F7 {
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct F11;
 impl WhitePoint for F11 {
-    fn get_xyz<Wp: WhitePoint, T: Component + Float>() -> Xyz<Wp, T> {
-        Xyz::with_wp(cast(1.00962), T::one(), cast(0.64350))
+    fn get_xyz<Wp: WhitePoint, T: FloatComponent>() -> Xyz<Wp, T> {
+        Xyz::with_wp(from_f64(1.00962), T::one(), from_f64(0.64350))
     }
 }
 ///CIE D series standard illuminant - D50
@@ -149,8 +147,8 @@ impl WhitePoint for F11 {
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct D50Degree10;
 impl WhitePoint for D50Degree10 {
-    fn get_xyz<Wp: WhitePoint, T: Component + Float>() -> Xyz<Wp, T> {
-        Xyz::with_wp(cast(0.9672), T::one(), cast(0.8143))
+    fn get_xyz<Wp: WhitePoint, T: FloatComponent>() -> Xyz<Wp, T> {
+        Xyz::with_wp(from_f64(0.9672), T::one(), from_f64(0.8143))
     }
 }
 ///CIE D series standard illuminant - D55
@@ -160,8 +158,8 @@ impl WhitePoint for D50Degree10 {
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct D55Degree10;
 impl WhitePoint for D55Degree10 {
-    fn get_xyz<Wp: WhitePoint, T: Component + Float>() -> Xyz<Wp, T> {
-        Xyz::with_wp(cast(0.958), T::one(), cast(0.9093))
+    fn get_xyz<Wp: WhitePoint, T: FloatComponent>() -> Xyz<Wp, T> {
+        Xyz::with_wp(from_f64(0.958), T::one(), from_f64(0.9093))
     }
 }
 ///CIE D series standard illuminant - D65
@@ -171,8 +169,8 @@ impl WhitePoint for D55Degree10 {
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct D65Degree10;
 impl WhitePoint for D65Degree10 {
-    fn get_xyz<Wp: WhitePoint, T: Component + Float>() -> Xyz<Wp, T> {
-        Xyz::with_wp(cast(0.9481), T::one(), cast(1.073))
+    fn get_xyz<Wp: WhitePoint, T: FloatComponent>() -> Xyz<Wp, T> {
+        Xyz::with_wp(from_f64(0.9481), T::one(), from_f64(1.073))
     }
 }
 ///CIE D series standard illuminant - D75
@@ -182,7 +180,7 @@ impl WhitePoint for D65Degree10 {
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct D75Degree10;
 impl WhitePoint for D75Degree10 {
-    fn get_xyz<Wp: WhitePoint, T: Component + Float>() -> Xyz<Wp, T> {
-        Xyz::with_wp(cast(0.94416), T::one(), cast(1.2064))
+    fn get_xyz<Wp: WhitePoint, T: FloatComponent>() -> Xyz<Wp, T> {
+        Xyz::with_wp(from_f64(0.94416), T::one(), from_f64(1.2064))
     }
 }
diff --git a/palette/src/xyz.rs b/palette/src/xyz.rs
index 46da956fa..670d8bc0c 100644
--- a/palette/src/xyz.rs
+++ b/palette/src/xyz.rs
@@ -1,5 +1,3 @@
-use float::Float;
-
 use core::marker::PhantomData;
 use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
 
@@ -7,10 +5,10 @@ use encoding::pixel::RawPixel;
 use luma::LumaStandard;
 use matrix::{multiply_rgb_to_xyz, rgb_to_xyz_matrix};
 use rgb::{Rgb, RgbSpace, RgbStandard};
-use white_point::{D65, WhitePoint};
-use {cast, clamp};
+use white_point::{WhitePoint, D65};
+use {clamp, from_f64};
 use {Alpha, Lab, Luma, Yxy};
-use {Component, ComponentWise, Limited, Mix, Pixel, Shade};
+use {Component, ComponentWise, FloatComponent, Limited, Mix, Pixel, Shade};
 
 /// CIE 1931 XYZ with an alpha component. See the [`Xyza` implementation in
 /// `Alpha`](struct.Alpha.html#Xyza).
@@ -34,7 +32,7 @@ pub type Xyza<Wp = D65, T = f32> = Alpha<Xyz<Wp, T>, T>;
 #[repr(C)]
 pub struct Xyz<Wp = D65, T = f32>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     ///X is the scale of what can be seen as a response curve for the cone
@@ -59,14 +57,14 @@ where
 
 impl<Wp, T> Copy for Xyz<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
 }
 
 impl<Wp, T> Clone for Xyz<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     fn clone(&self) -> Xyz<Wp, T> {
@@ -76,7 +74,7 @@ where
 
 impl<T> Xyz<D65, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
 {
     ///CIE XYZ with whtie point D65.
     pub fn new(x: T, y: T, z: T) -> Xyz<D65, T> {
@@ -91,7 +89,7 @@ where
 
 impl<Wp, T> Xyz<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     ///CIE XYZ.
@@ -118,7 +116,7 @@ where
 ///<span id="Xyza"></span>[`Xyza`](type.Xyza.html) implementations.
 impl<T, A> Alpha<Xyz<D65, T>, A>
 where
-    T: Component + Float,
+    T: FloatComponent,
     A: Component,
 {
     ///CIE Yxy and transparency with white point D65.
@@ -133,7 +131,7 @@ where
 ///<span id="Xyza"></span>[`Xyza`](type.Xyza.html) implementations.
 impl<Wp, T, A> Alpha<Xyz<Wp, T>, A>
 where
-    T: Component + Float,
+    T: FloatComponent,
     A: Component,
     Wp: WhitePoint,
 {
@@ -158,7 +156,7 @@ where
 
 impl<Wp, T, S> From<Rgb<S, T>> for Xyz<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
     S: RgbStandard,
     S::Space: RgbSpace<WhitePoint = Wp>,
@@ -171,7 +169,7 @@ where
 
 impl<Wp, T> From<Yxy<Wp, T>> for Xyz<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     fn from(color: Yxy<Wp, T>) -> Self {
@@ -190,18 +188,18 @@ where
 
 impl<Wp, T> From<Lab<Wp, T>> for Xyz<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     fn from(color: Lab<Wp, T>) -> Self {
-        let y = (color.l + cast(16.0)) / cast(116.0);
-        let x = y + (color.a / cast(500.0));
-        let z = y - (color.b / cast(200.0));
+        let y = (color.l + from_f64(16.0)) / from_f64(116.0);
+        let x = y + (color.a / from_f64(500.0));
+        let z = y - (color.b / from_f64(200.0));
 
-        fn convert<T: Component + Float>(c: T) -> T {
-            let epsilon: T = cast(6.0 / 29.0);
-            let kappa: T = cast(108.0 / 841.0);
-            let delta: T = cast(4.0 / 29.0);
+        fn convert<T: FloatComponent>(c: T) -> T {
+            let epsilon: T = from_f64(6.0 / 29.0);
+            let kappa: T = from_f64(108.0 / 841.0);
+            let delta: T = from_f64(4.0 / 29.0);
 
             if c > epsilon {
                 c.powi(3)
@@ -216,7 +214,7 @@ where
 
 impl<Wp, T, S> From<Luma<S, T>> for Xyz<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
     S: LumaStandard<WhitePoint = Wp>,
 {
@@ -225,29 +223,25 @@ where
     }
 }
 
-impl<Wp: WhitePoint, T: Component + Float> From<(T, T, T)> for Xyz<Wp, T> {
+impl<Wp: WhitePoint, T: FloatComponent> From<(T, T, T)> for Xyz<Wp, T> {
     fn from(components: (T, T, T)) -> Self {
         Self::from_components(components)
     }
 }
 
-impl<Wp: WhitePoint, T: Component + Float> Into<(T, T, T)> for Xyz<Wp, T> {
+impl<Wp: WhitePoint, T: FloatComponent> Into<(T, T, T)> for Xyz<Wp, T> {
     fn into(self) -> (T, T, T) {
         self.into_components()
     }
 }
 
-impl<Wp: WhitePoint, T: Component + Float, A: Component> From<(T, T, T, A)>
-    for Alpha<Xyz<Wp, T>, A>
-{
+impl<Wp: WhitePoint, T: FloatComponent, A: Component> From<(T, T, T, A)> for Alpha<Xyz<Wp, T>, A> {
     fn from(components: (T, T, T, A)) -> Self {
         Self::from_components(components)
     }
 }
 
-impl<Wp: WhitePoint, T: Component + Float, A: Component> Into<(T, T, T, A)>
-    for Alpha<Xyz<Wp, T>, A>
-{
+impl<Wp: WhitePoint, T: FloatComponent, A: Component> Into<(T, T, T, A)> for Alpha<Xyz<Wp, T>, A> {
     fn into(self) -> (T, T, T, A) {
         self.into_components()
     }
@@ -255,7 +249,7 @@ impl<Wp: WhitePoint, T: Component + Float, A: Component> Into<(T, T, T, A)>
 
 impl<Wp, T> Limited for Xyz<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     #[cfg_attr(rustfmt, rustfmt_skip)]
@@ -282,7 +276,7 @@ where
 
 impl<Wp, T> Mix for Xyz<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Scalar = T;
@@ -301,7 +295,7 @@ where
 
 impl<Wp, T> Shade for Xyz<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Scalar = T;
@@ -318,7 +312,7 @@ where
 
 impl<Wp, T> ComponentWise for Xyz<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Scalar = T;
@@ -344,7 +338,7 @@ where
 
 impl<Wp, T> Default for Xyz<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     fn default() -> Xyz<Wp, T> {
@@ -354,7 +348,7 @@ where
 
 impl<Wp, T> Add<Xyz<Wp, T>> for Xyz<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Xyz<Wp, T>;
@@ -371,7 +365,7 @@ where
 
 impl<Wp, T> Add<T> for Xyz<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Xyz<Wp, T>;
@@ -388,7 +382,7 @@ where
 
 impl<Wp, T> AddAssign<Xyz<Wp, T>> for Xyz<Wp, T>
 where
-    T: Component + Float + AddAssign,
+    T: FloatComponent + AddAssign,
     Wp: WhitePoint,
 {
     fn add_assign(&mut self, other: Xyz<Wp, T>) {
@@ -400,7 +394,7 @@ where
 
 impl<Wp, T> AddAssign<T> for Xyz<Wp, T>
 where
-    T: Component + Float + AddAssign,
+    T: FloatComponent + AddAssign,
     Wp: WhitePoint,
 {
     fn add_assign(&mut self, c: T) {
@@ -412,7 +406,7 @@ where
 
 impl<Wp, T> Sub<Xyz<Wp, T>> for Xyz<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Xyz<Wp, T>;
@@ -429,7 +423,7 @@ where
 
 impl<Wp, T> Sub<T> for Xyz<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Xyz<Wp, T>;
@@ -446,7 +440,7 @@ where
 
 impl<Wp, T> SubAssign<Xyz<Wp, T>> for Xyz<Wp, T>
 where
-    T: Component + Float + SubAssign,
+    T: FloatComponent + SubAssign,
     Wp: WhitePoint,
 {
     fn sub_assign(&mut self, other: Xyz<Wp, T>) {
@@ -458,7 +452,7 @@ where
 
 impl<Wp, T> SubAssign<T> for Xyz<Wp, T>
 where
-    T: Component + Float + SubAssign,
+    T: FloatComponent + SubAssign,
     Wp: WhitePoint,
 {
     fn sub_assign(&mut self, c: T) {
@@ -470,7 +464,7 @@ where
 
 impl<Wp, T> Mul<Xyz<Wp, T>> for Xyz<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Xyz<Wp, T>;
@@ -487,7 +481,7 @@ where
 
 impl<Wp, T> Mul<T> for Xyz<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Xyz<Wp, T>;
@@ -504,7 +498,7 @@ where
 
 impl<Wp, T> MulAssign<Xyz<Wp, T>> for Xyz<Wp, T>
 where
-    T: Component + Float + MulAssign,
+    T: FloatComponent + MulAssign,
     Wp: WhitePoint,
 {
     fn mul_assign(&mut self, other: Xyz<Wp, T>) {
@@ -516,7 +510,7 @@ where
 
 impl<Wp, T> MulAssign<T> for Xyz<Wp, T>
 where
-    T: Component + Float + MulAssign,
+    T: FloatComponent + MulAssign,
     Wp: WhitePoint,
 {
     fn mul_assign(&mut self, c: T) {
@@ -528,7 +522,7 @@ where
 
 impl<Wp, T> Div<Xyz<Wp, T>> for Xyz<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Xyz<Wp, T>;
@@ -545,7 +539,7 @@ where
 
 impl<Wp, T> Div<T> for Xyz<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Xyz<Wp, T>;
@@ -562,7 +556,7 @@ where
 
 impl<Wp, T> DivAssign<Xyz<Wp, T>> for Xyz<Wp, T>
 where
-    T: Component + Float + DivAssign,
+    T: FloatComponent + DivAssign,
     Wp: WhitePoint,
 {
     fn div_assign(&mut self, other: Xyz<Wp, T>) {
@@ -574,7 +568,7 @@ where
 
 impl<Wp, T> DivAssign<T> for Xyz<Wp, T>
 where
-    T: Component + Float + DivAssign,
+    T: FloatComponent + DivAssign,
     Wp: WhitePoint,
 {
     fn div_assign(&mut self, c: T) {
@@ -586,7 +580,7 @@ where
 
 impl<Wp, T, P> AsRef<P> for Xyz<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
     P: RawPixel<T> + ?Sized,
 {
@@ -597,7 +591,7 @@ where
 
 impl<Wp, T, P> AsMut<P> for Xyz<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
     P: RawPixel<T> + ?Sized,
 {
@@ -646,7 +640,7 @@ mod test {
 
     #[test]
     fn ranges() {
-        assert_ranges!{
+        assert_ranges! {
             Xyz<D65, f64>;
             limited {
                 x: 0.0 => X_N,
diff --git a/palette/src/yxy.rs b/palette/src/yxy.rs
index 005920e90..b414660d8 100644
--- a/palette/src/yxy.rs
+++ b/palette/src/yxy.rs
@@ -1,14 +1,12 @@
-use float::Float;
-
 use core::marker::PhantomData;
 use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
 
 use clamp;
 use encoding::pixel::RawPixel;
 use luma::LumaStandard;
-use white_point::{D65, WhitePoint};
+use white_point::{WhitePoint, D65};
 use {Alpha, Luma, Xyz};
-use {Component, ComponentWise, IntoColor, Limited, Mix, Pixel, Shade};
+use {Component, ComponentWise, FloatComponent, IntoColor, Limited, Mix, Pixel, Shade};
 
 /// CIE 1931 Yxy (xyY) with an alpha component. See the [`Yxya` implementation
 /// in `Alpha`](struct.Alpha.html#Yxya).
@@ -30,7 +28,7 @@ pub type Yxya<Wp = D65, T = f32> = Alpha<Yxy<Wp, T>, T>;
 #[repr(C)]
 pub struct Yxy<Wp = D65, T = f32>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     ///x chromacity co-ordinate derived from XYZ color space as X/(X+Y+Z).
@@ -55,14 +53,14 @@ where
 
 impl<Wp, T> Copy for Yxy<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
 }
 
 impl<Wp, T> Clone for Yxy<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     fn clone(&self) -> Yxy<Wp, T> {
@@ -72,7 +70,7 @@ where
 
 impl<T> Yxy<D65, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
 {
     ///CIE Yxy with white point D65.
     pub fn new(x: T, y: T, luma: T) -> Yxy<D65, T> {
@@ -87,7 +85,7 @@ where
 
 impl<Wp, T> Yxy<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     ///CIE Yxy.
@@ -114,7 +112,7 @@ where
 ///<span id="Yxya"></span>[`Yxya`](type.Yxya.html) implementations.
 impl<T, A> Alpha<Yxy<D65, T>, A>
 where
-    T: Component + Float,
+    T: FloatComponent,
     A: Component,
 {
     ///CIE Yxy and transparency with white point D65.
@@ -128,7 +126,7 @@ where
 ///<span id="Yxya"></span>[`Yxya`](type.Yxya.html) implementations.
 impl<Wp, T, A> Alpha<Yxy<Wp, T>, A>
 where
-    T: Component + Float,
+    T: FloatComponent,
     A: Component,
     Wp: WhitePoint,
 {
@@ -153,7 +151,7 @@ where
 
 impl<Wp, T> From<Xyz<Wp, T>> for Yxy<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     fn from(xyz: Xyz<Wp, T>) -> Self {
@@ -175,7 +173,7 @@ where
 
 impl<S, T> From<Luma<S, T>> for Yxy<S::WhitePoint, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     S: LumaStandard,
 {
     fn from(luma: Luma<S, T>) -> Self {
@@ -186,29 +184,25 @@ where
     }
 }
 
-impl<Wp: WhitePoint, T: Component + Float> From<(T, T, T)> for Yxy<Wp, T> {
+impl<Wp: WhitePoint, T: FloatComponent> From<(T, T, T)> for Yxy<Wp, T> {
     fn from(components: (T, T, T)) -> Self {
         Self::from_components(components)
     }
 }
 
-impl<Wp: WhitePoint, T: Component + Float> Into<(T, T, T)> for Yxy<Wp, T> {
+impl<Wp: WhitePoint, T: FloatComponent> Into<(T, T, T)> for Yxy<Wp, T> {
     fn into(self) -> (T, T, T) {
         self.into_components()
     }
 }
 
-impl<Wp: WhitePoint, T: Component + Float, A: Component> From<(T, T, T, A)>
-    for Alpha<Yxy<Wp, T>, A>
-{
+impl<Wp: WhitePoint, T: FloatComponent, A: Component> From<(T, T, T, A)> for Alpha<Yxy<Wp, T>, A> {
     fn from(components: (T, T, T, A)) -> Self {
         Self::from_components(components)
     }
 }
 
-impl<Wp: WhitePoint, T: Component + Float, A: Component> Into<(T, T, T, A)>
-    for Alpha<Yxy<Wp, T>, A>
-{
+impl<Wp: WhitePoint, T: FloatComponent, A: Component> Into<(T, T, T, A)> for Alpha<Yxy<Wp, T>, A> {
     fn into(self) -> (T, T, T, A) {
         self.into_components()
     }
@@ -216,7 +210,7 @@ impl<Wp: WhitePoint, T: Component + Float, A: Component> Into<(T, T, T, A)>
 
 impl<Wp, T> Limited for Yxy<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     #[cfg_attr(rustfmt, rustfmt_skip)]
@@ -241,7 +235,7 @@ where
 
 impl<Wp, T> Mix for Yxy<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Scalar = T;
@@ -260,7 +254,7 @@ where
 
 impl<Wp, T> Shade for Yxy<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Scalar = T;
@@ -277,7 +271,7 @@ where
 
 impl<Wp, T> ComponentWise for Yxy<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Scalar = T;
@@ -303,7 +297,7 @@ where
 
 impl<Wp, T> Default for Yxy<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     fn default() -> Yxy<Wp, T> {
@@ -320,7 +314,7 @@ where
 
 impl<Wp, T> Add<Yxy<Wp, T>> for Yxy<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Yxy<Wp, T>;
@@ -337,7 +331,7 @@ where
 
 impl<Wp, T> Add<T> for Yxy<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Yxy<Wp, T>;
@@ -354,7 +348,7 @@ where
 
 impl<Wp, T> AddAssign<Yxy<Wp, T>> for Yxy<Wp, T>
 where
-    T: Component + Float + AddAssign,
+    T: FloatComponent + AddAssign,
     Wp: WhitePoint,
 {
     fn add_assign(&mut self, other: Yxy<Wp, T>) {
@@ -366,7 +360,7 @@ where
 
 impl<Wp, T> AddAssign<T> for Yxy<Wp, T>
 where
-    T: Component + Float + AddAssign,
+    T: FloatComponent + AddAssign,
     Wp: WhitePoint,
 {
     fn add_assign(&mut self, c: T) {
@@ -378,7 +372,7 @@ where
 
 impl<Wp, T> Sub<Yxy<Wp, T>> for Yxy<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Yxy<Wp, T>;
@@ -395,7 +389,7 @@ where
 
 impl<Wp, T> Sub<T> for Yxy<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Yxy<Wp, T>;
@@ -411,9 +405,9 @@ where
 }
 
 impl<Wp, T> SubAssign<Yxy<Wp, T>> for Yxy<Wp, T>
-    where
-        T: Component + Float + SubAssign,
-        Wp: WhitePoint,
+where
+    T: FloatComponent + SubAssign,
+    Wp: WhitePoint,
 {
     fn sub_assign(&mut self, other: Yxy<Wp, T>) {
         self.x -= other.x;
@@ -423,9 +417,9 @@ impl<Wp, T> SubAssign<Yxy<Wp, T>> for Yxy<Wp, T>
 }
 
 impl<Wp, T> SubAssign<T> for Yxy<Wp, T>
-    where
-        T: Component + Float + SubAssign,
-        Wp: WhitePoint,
+where
+    T: FloatComponent + SubAssign,
+    Wp: WhitePoint,
 {
     fn sub_assign(&mut self, c: T) {
         self.x -= c;
@@ -436,7 +430,7 @@ impl<Wp, T> SubAssign<T> for Yxy<Wp, T>
 
 impl<Wp, T> Mul<Yxy<Wp, T>> for Yxy<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Yxy<Wp, T>;
@@ -453,7 +447,7 @@ where
 
 impl<Wp, T> Mul<T> for Yxy<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Yxy<Wp, T>;
@@ -469,9 +463,9 @@ where
 }
 
 impl<Wp, T> MulAssign<Yxy<Wp, T>> for Yxy<Wp, T>
-    where
-        T: Component + Float + MulAssign,
-        Wp: WhitePoint,
+where
+    T: FloatComponent + MulAssign,
+    Wp: WhitePoint,
 {
     fn mul_assign(&mut self, other: Yxy<Wp, T>) {
         self.x *= other.x;
@@ -481,9 +475,9 @@ impl<Wp, T> MulAssign<Yxy<Wp, T>> for Yxy<Wp, T>
 }
 
 impl<Wp, T> MulAssign<T> for Yxy<Wp, T>
-    where
-        T: Component + Float + MulAssign,
-        Wp: WhitePoint,
+where
+    T: FloatComponent + MulAssign,
+    Wp: WhitePoint,
 {
     fn mul_assign(&mut self, c: T) {
         self.x *= c;
@@ -494,7 +488,7 @@ impl<Wp, T> MulAssign<T> for Yxy<Wp, T>
 
 impl<Wp, T> Div<Yxy<Wp, T>> for Yxy<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Yxy<Wp, T>;
@@ -511,7 +505,7 @@ where
 
 impl<Wp, T> Div<T> for Yxy<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
 {
     type Output = Yxy<Wp, T>;
@@ -527,9 +521,9 @@ where
 }
 
 impl<Wp, T> DivAssign<Yxy<Wp, T>> for Yxy<Wp, T>
-    where
-        T: Component + Float + DivAssign,
-        Wp: WhitePoint,
+where
+    T: FloatComponent + DivAssign,
+    Wp: WhitePoint,
 {
     fn div_assign(&mut self, other: Yxy<Wp, T>) {
         self.x /= other.x;
@@ -539,9 +533,9 @@ impl<Wp, T> DivAssign<Yxy<Wp, T>> for Yxy<Wp, T>
 }
 
 impl<Wp, T> DivAssign<T> for Yxy<Wp, T>
-    where
-        T: Component + Float + DivAssign,
-        Wp: WhitePoint,
+where
+    T: FloatComponent + DivAssign,
+    Wp: WhitePoint,
 {
     fn div_assign(&mut self, c: T) {
         self.x /= c;
@@ -552,7 +546,7 @@ impl<Wp, T> DivAssign<T> for Yxy<Wp, T>
 
 impl<Wp, T, P> AsRef<P> for Yxy<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
     P: RawPixel<T> + ?Sized,
 {
@@ -563,7 +557,7 @@ where
 
 impl<Wp, T, P> AsMut<P> for Yxy<Wp, T>
 where
-    T: Component + Float,
+    T: FloatComponent,
     Wp: WhitePoint,
     P: RawPixel<T> + ?Sized,
 {
@@ -609,7 +603,7 @@ mod test {
 
     #[test]
     fn ranges() {
-        assert_ranges!{
+        assert_ranges! {
             Yxy<D65, f64>;
             limited {
                 x: 0.0 => 1.0,
diff --git a/palette/tests/pointer_dataset/pointer_data.rs b/palette/tests/pointer_dataset/pointer_data.rs
index 1ed1c47ba..aeabb963a 100644
--- a/palette/tests/pointer_dataset/pointer_data.rs
+++ b/palette/tests/pointer_dataset/pointer_data.rs
@@ -11,16 +11,16 @@ u', v'		0.2008907213	0.4608888395
 Note: The xyz and yxy conversions do not use the updated conversion formula. So they are not used.
 */
 
+use csv;
 use num_traits::{NumCast, ToPrimitive};
 use palette::float::Float;
-use csv;
-use palette::{Component, IntoColor, Lab, Lch, Xyz};
 use palette::white_point::WhitePoint;
+use palette::{FloatComponent, IntoColor, Lab, Lch, Xyz};
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct PointerWP;
 impl WhitePoint for PointerWP {
-    fn get_xyz<Wp: WhitePoint, T: Component + Float>() -> Xyz<Wp, T> {
+    fn get_xyz<Wp: WhitePoint, T: FloatComponent>() -> Xyz<Wp, T> {
         Xyz::with_wp(flt(0.980722647624), T::one(), flt(1.182254189827))
     }
 }
@@ -68,8 +68,7 @@ macro_rules! impl_from_color_pointer {
                 }
             }
         }
-
-    }
+    };
 }
 
 impl_from_color_pointer!(Lch);
diff --git a/palette_derive/src/convert/shared.rs b/palette_derive/src/convert/shared.rs
index 79448eed4..826cfdb9b 100644
--- a/palette_derive/src/convert/shared.rs
+++ b/palette_derive/src/convert/shared.rs
@@ -77,7 +77,7 @@ pub fn rgb_space_type(rgb_space: Option<Type>, white_point: &Type, internal: boo
 }
 
 pub fn add_component_where_clause(component: &Type, generics: &mut Generics, internal: bool) {
-    let component_trait_path = util::path(&["Component"], internal);
+    let component_trait_path = util::path(&["FloatComponent"], internal);
 
     generics
         .make_where_clause()