Guest User

Untitled

a guest
Apr 23rd, 2018
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.44 KB | None | 0 0
  1. extension UInt16 {
  2. var halfFloat: Float {
  3. // 1 bit sign
  4. // 5 bit exponent
  5. // 11 bit significand (10 bit explicitly stored)
  6. let sign = Float((self & 0b1000_0000_0000_0000) >> 15)
  7. let exponent = Float((self & 0b0111_1100_0000_0000) >> 10)
  8. let significand = Float(self & 0b0000_0011_1111_1111)
  9.  
  10. if exponent == 0b0_0000 {
  11. if significand == 0 {
  12. return pow(-1, sign) * 0
  13. } else {
  14. // (−1)^signbit × 2^(−14) × 0.significantbits
  15. let last = 0 + significand / 0b0011_1111_1111
  16. return pow(-1, sign) * pow(2, -14) * last
  17. }
  18. } else if exponent == 0b1_1111 {
  19. if significand == 0 {
  20. return pow(-1, sign) * .infinity
  21. } else {
  22. return .nan
  23. }
  24. } else {
  25. // (−1)^signbit × 2^(exponent−15) × 1.significantbits
  26. let last = 1 + significand / 0b0011_1111_1111
  27. return pow(-1, sign) * pow(2, exponent - 15) * last
  28. }
  29. }
  30. }
  31.  
  32. extension Float {
  33. var halfFloatBitPattern: UInt16 {
  34. var value = self
  35.  
  36. let signBytes: UInt16
  37. if value.sign == .plus {
  38. signBytes = 0b0000_0000_0000_0000
  39. } else {
  40. signBytes = 0b1000_0000_0000_0000
  41. value *= -1
  42. }
  43.  
  44. guard value.isNaN == false else {
  45. let exponentBytes: UInt16 = 0b1_1111
  46. let significandBytes: UInt16 = 0
  47. return signBytes | exponentBytes | significandBytes
  48. }
  49.  
  50. guard value != 0 else {
  51. return signBytes
  52. }
  53. let exponent = log2(value).rounded(.down)
  54. let exponentBytes: UInt16
  55. let significandBytes: UInt16
  56. if exponent == 1 {
  57. exponentBytes = 0
  58. let significand = value * 1024
  59. significandBytes = UInt16(significand)
  60. } else if exponent == .infinity {
  61. exponentBytes = 0b1111 << 10
  62. significandBytes = 0
  63. } else if exponent <= -15 {
  64. exponentBytes = 0
  65. let significand = value * 1024
  66. significandBytes = UInt16(significand)
  67. } else {
  68. exponentBytes = UInt16(exponent + 15) << 10
  69. value /= pow(2, exponent)
  70. let significand = (value - 1) * 1024
  71. significandBytes = UInt16(significand)
  72. }
  73. return signBytes | exponentBytes | significandBytes
  74. }
  75. }
Add Comment
Please, Sign In to add comment