mod.rs 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. use core::mem;
  2. pub mod add;
  3. /// Trait for some basic operations on floats
  4. pub trait Float: Sized {
  5. /// A uint of the same with as the float
  6. type Int;
  7. /// Returns the bitwidth of the float type
  8. fn bits() -> u32;
  9. /// Returns the bitwidth of the significand
  10. fn significand_bits() -> u32;
  11. /// Returns `self` transmuted to `Self::Int`
  12. fn repr(self) -> Self::Int;
  13. #[cfg(test)]
  14. /// Checks if two floats have the same bit representation. *Except* for NaNs! NaN can be
  15. /// represented in multiple different ways. This methods returns `true` if two NaNs are
  16. /// compared.
  17. fn eq_repr(self, rhs: Self) -> bool;
  18. /// Returns a `Self::Int` transmuted back to `Self`
  19. fn from_repr(a: Self::Int) -> Self;
  20. /// Returns (normalized exponent, normalized significand)
  21. fn normalize(significand: Self::Int) -> (i32, Self::Int);
  22. }
  23. impl Float for f32 {
  24. type Int = u32;
  25. fn bits() -> u32 {
  26. 32
  27. }
  28. fn significand_bits() -> u32 {
  29. 23
  30. }
  31. fn repr(self) -> Self::Int {
  32. unsafe { mem::transmute(self) }
  33. }
  34. #[cfg(test)]
  35. fn eq_repr(self, rhs: Self) -> bool {
  36. if self.is_nan() && rhs.is_nan() {
  37. true
  38. } else {
  39. self.repr() == rhs.repr()
  40. }
  41. }
  42. fn from_repr(a: Self::Int) -> Self {
  43. unsafe { mem::transmute(a) }
  44. }
  45. fn normalize(significand: Self::Int) -> (i32, Self::Int) {
  46. let shift = significand.leading_zeros()
  47. .wrapping_sub((1u32 << Self::significand_bits()).leading_zeros());
  48. (1i32.wrapping_sub(shift as i32), significand << shift as Self::Int)
  49. }
  50. }
  51. impl Float for f64 {
  52. type Int = u64;
  53. fn bits() -> u32 {
  54. 64
  55. }
  56. fn significand_bits() -> u32 {
  57. 52
  58. }
  59. fn repr(self) -> Self::Int {
  60. unsafe { mem::transmute(self) }
  61. }
  62. #[cfg(test)]
  63. fn eq_repr(self, rhs: Self) -> bool {
  64. if self.is_nan() && rhs.is_nan() {
  65. true
  66. } else {
  67. self.repr() == rhs.repr()
  68. }
  69. }
  70. fn from_repr(a: Self::Int) -> Self {
  71. unsafe { mem::transmute(a) }
  72. }
  73. fn normalize(significand: Self::Int) -> (i32, Self::Int) {
  74. let shift = significand.leading_zeros()
  75. .wrapping_sub((1u64 << Self::significand_bits()).leading_zeros());
  76. (1i32.wrapping_sub(shift as i32), significand << shift as Self::Int)
  77. }
  78. }