fuchsia_wayland_core/
fixed.rs

1// Copyright 2018 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use std::fmt;
6
7/// A 24.8 fixed point number.
8///
9/// Internally this is stored as a single `i32` value, with methods to convert
10/// to/from `f32` floating point values.
11#[derive(Copy, Clone, Eq, PartialEq)]
12pub struct Fixed(i32);
13
14impl Fixed {
15    /// Creates a `Fixed` from raw bytes.
16    pub fn from_bits(v: i32) -> Self {
17        Fixed(v)
18    }
19
20    /// Creates a `Fixed` from a floating point value.
21    pub fn from_float(v: f32) -> Self {
22        Fixed((v * 256.0) as i32)
23    }
24
25    /// Returns a floating point representation of this value.
26    pub fn to_float(self) -> f32 {
27        (self.0 as f32) / 256.0
28    }
29
30    /// Returns the underlying integer representation of this value.
31    pub fn bits(self) -> i32 {
32        self.0
33    }
34}
35
36impl fmt::Display for Fixed {
37    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
38        write!(fmt, "{}", self.to_float())
39    }
40}
41
42impl fmt::Debug for Fixed {
43    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
44        write!(fmt, "{:?}", self.to_float())
45    }
46}
47
48impl From<f32> for Fixed {
49    fn from(v: f32) -> Self {
50        Self::from_float(v)
51    }
52}
53
54impl From<i32> for Fixed {
55    fn from(v: i32) -> Self {
56        Self::from_bits(v)
57    }
58}
59
60impl Into<f32> for Fixed {
61    fn into(self) -> f32 {
62        self.to_float()
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use zerocopy::transmute;
69
70    use super::*;
71
72    #[test]
73    fn fixed_to_float() {
74        let fixed: Fixed = 256.into();
75        assert_eq!(1.0, fixed.to_float());
76
77        let fixed: Fixed = 257.into();
78        assert_eq!(1.00390625, fixed.to_float());
79
80        let i: i32 = transmute!(0xffffff00u32);
81        let fixed: Fixed = i.into();
82        assert_eq!(-1.0, fixed.to_float());
83
84        let i: i32 = transmute!(0xfffffeffu32);
85        let fixed: Fixed = i.into();
86        assert_eq!(-1.00390625, fixed.to_float());
87    }
88
89    #[test]
90    fn float_to_fixed() {
91        let fixed: Fixed = 1.0.into();
92        assert_eq!(256, fixed.bits());
93
94        let fixed: Fixed = 1.00390625.into();
95        assert_eq!(257, fixed.bits());
96
97        let fixed: Fixed = (-1.0).into();
98        let i: i32 = transmute!(0xffffff00u32);
99        assert_eq!(i, fixed.bits());
100
101        let fixed: Fixed = (-1.00390625).into();
102        let i: i32 = transmute!(0xfffffeffu32);
103        assert_eq!(i, fixed.bits());
104    }
105}