tcastint.nim 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. discard """
  2. output: "OK"
  3. """
  4. type
  5. Dollar = distinct int
  6. XCoord = distinct int32
  7. Digit = range[-9..0]
  8. # those are necessary for comparisons below.
  9. proc `==`(x, y: Dollar): bool {.borrow.}
  10. proc `==`(x, y: XCoord): bool {.borrow.}
  11. proc dummy[T](x: T): T = x
  12. proc test() =
  13. let U8 = 0b1011_0010'u8
  14. let I8 = 0b1011_0010'i8
  15. let C8 = 0b1011_0010'u8.char
  16. let C8_1 = 0b1011_0011'u8.char
  17. let U16 = 0b10100111_00101000'u16
  18. let I16 = 0b10100111_00101000'i16
  19. let U32 = 0b11010101_10011100_11011010_01010000'u32
  20. let I32 = 0b11010101_10011100_11011010_01010000'i32
  21. let U64A = 0b11000100_00111111_01111100_10001010_10011001_01001000_01111010_00010001'u64
  22. let I64A = 0b11000100_00111111_01111100_10001010_10011001_01001000_01111010_00010001'i64
  23. let U64B = 0b00110010_11011101_10001111_00101000_00000000_00000000_00000000_00000000'u64
  24. let I64B = 0b00110010_11011101_10001111_00101000_00000000_00000000_00000000_00000000'i64
  25. when sizeof(int) == 8:
  26. let UX = U64A.uint
  27. let IX = I64A.int
  28. elif sizeof(int) == 4:
  29. let UX = U32.uint
  30. let IX = I32.int
  31. elif sizeof(int) == 2:
  32. let UX = U16.uint
  33. let IX = I16.int
  34. else:
  35. let UX = U8.uint
  36. let IX = I8.int
  37. doAssert(cast[char](I8) == C8)
  38. doAssert(cast[uint8](I8) == U8)
  39. doAssert(cast[uint16](I16) == U16)
  40. doAssert(cast[uint32](I32) == U32)
  41. doAssert(cast[uint64](I64A) == U64A)
  42. doAssert(cast[uint64](I64B) == U64B)
  43. doAssert(cast[int8](U8) == I8)
  44. doAssert(cast[int16](U16) == I16)
  45. doAssert(cast[int32](U32) == I32)
  46. doAssert(cast[int64](U64A) == I64A)
  47. doAssert(cast[int64](U64B) == I64B)
  48. doAssert(cast[uint](IX) == UX)
  49. doAssert(cast[int](UX) == IX)
  50. doAssert(cast[char](I8 + 1) == C8_1)
  51. doAssert(cast[uint8](I8 + 1) == U8 + 1)
  52. doAssert(cast[uint16](I16 + 1) == U16 + 1)
  53. doAssert(cast[uint32](I32 + 1) == U32 + 1)
  54. doAssert(cast[uint64](I64A + 1) == U64A + 1)
  55. doAssert(cast[uint64](I64B + 1) == U64B + 1)
  56. doAssert(cast[int8](U8 + 1) == I8 + 1)
  57. doAssert(cast[int16](U16 + 1) == I16 + 1)
  58. doAssert(cast[int32](U32 + 1) == I32 + 1)
  59. doAssert(cast[int64](U64A + 1) == I64A + 1)
  60. doAssert(cast[int64](U64B + 1) == I64B + 1)
  61. doAssert(cast[uint](IX + 1) == UX + 1)
  62. doAssert(cast[int](UX + 1) == IX + 1)
  63. doAssert(cast[char](I8.dummy) == C8.dummy)
  64. doAssert(cast[uint8](I8.dummy) == U8.dummy)
  65. doAssert(cast[uint16](I16.dummy) == U16.dummy)
  66. doAssert(cast[uint32](I32.dummy) == U32.dummy)
  67. doAssert(cast[uint64](I64A.dummy) == U64A.dummy)
  68. doAssert(cast[uint64](I64B.dummy) == U64B.dummy)
  69. doAssert(cast[int8](U8.dummy) == I8.dummy)
  70. doAssert(cast[int16](U16.dummy) == I16.dummy)
  71. doAssert(cast[int32](U32.dummy) == I32.dummy)
  72. doAssert(cast[int64](U64A.dummy) == I64A.dummy)
  73. doAssert(cast[int64](U64B.dummy) == I64B.dummy)
  74. doAssert(cast[uint](IX.dummy) == UX.dummy)
  75. doAssert(cast[int](UX.dummy) == IX.dummy)
  76. doAssert(cast[int64](if false: U64B else: 0'u64) == (if false: I64B else: 0'i64))
  77. block:
  78. let raw = 3
  79. let money = Dollar(raw) # this must be a variable, is otherwise constant folded.
  80. doAssert(cast[int](money) == raw)
  81. doAssert(cast[Dollar](raw) == money)
  82. block:
  83. let raw = 150'i32
  84. let position = XCoord(raw) # this must be a variable, is otherwise constant folded.
  85. doAssert(cast[int32](position) == raw)
  86. doAssert(cast[XCoord](raw) == position)
  87. block:
  88. let raw = -2
  89. let digit = Digit(raw)
  90. doAssert(cast[int](digit) == raw)
  91. doAssert(cast[Digit](raw) == digit)
  92. when defined nimvm:
  93. doAssert(not compiles(cast[float](I64A)))
  94. doAssert(not compiles(cast[float32](I64A)))
  95. doAssert(not compiles(cast[char](I64A)))
  96. doAssert(not compiles(cast[uint16](I64A)))
  97. doAssert(not compiles(cast[uint32](I64A)))
  98. doAssert(not compiles(cast[uint16](I8)))
  99. doAssert(not compiles(cast[uint32](I8)))
  100. doAssert(not compiles(cast[uint64](I8)))
  101. proc test_float_cast =
  102. const
  103. exp_bias = 1023'i64
  104. exp_shift = 52
  105. exp_mask = 0x7ff'i64 shl exp_shift
  106. mantissa_mask = 0xfffffffffffff'i64
  107. let f = 8.0
  108. let fx = cast[int64](f)
  109. let exponent = ((fx and exp_mask) shr exp_shift) - exp_bias
  110. let mantissa = fx and mantissa_mask
  111. doAssert(exponent == 3, $exponent)
  112. doAssert(mantissa == 0, $mantissa)
  113. # construct 2^N float, where N is integer
  114. let x = -2'i64
  115. let xx = (x + exp_bias) shl exp_shift
  116. let xf = cast[float](xx)
  117. doAssert(xf == 0.25, $xf)
  118. proc test_float32_cast =
  119. const
  120. exp_bias = 127'i32
  121. exp_shift = 23
  122. exp_mask = 0x7f800000'i32
  123. mantissa_mask = 0x007ffff'i32
  124. let f = -0.5'f32
  125. let fx = cast[int32](f)
  126. let exponent = ((fx and exp_mask) shr exp_shift) - exp_bias
  127. let mantissa = fx and mantissa_mask
  128. doAssert(exponent == -1, $exponent)
  129. doAssert(mantissa == 0, $mantissa)
  130. # construct 2^N float32 where N is integer
  131. let x = 4'i32
  132. let xx = (x + exp_bias) shl exp_shift
  133. let xf = cast[float32](xx)
  134. doAssert(xf == 16.0'f32, $xf)
  135. test()
  136. test_float_cast()
  137. test_float32_cast()
  138. static:
  139. test()
  140. test_float_cast()
  141. test_float32_cast()
  142. echo "OK"