@@ -15,17 +15,12 @@ trait InlineNumeric[T] extends Ordering[T]: // extends Numeric[T] // TODO can we
1515 transparent inline def toLong (inline x : T ): Long
1616 transparent inline def toFloat (inline x : T ): Float
1717 transparent inline def toDouble (inline x : T ): Double
18+ transparent inline def abs (inline x : T ): T
19+ transparent inline def sign (inline x : T ): T
1820
1921 transparent inline def zero = fromInt(0 )
2022 transparent inline def one = fromInt(1 )
2123
22- transparent inline def abs (inline x : T ): T = if lt(x, zero) then negate(x) else x
23-
24- transparent inline def sign (inline x : T ): T =
25- if lt(x, zero) then negate(one)
26- else if gt(x, zero) then one
27- else zero
28-
2924object InlineNumeric :
3025 extension [T ](inline x : T )(using inline num : InlineNumeric [T ])
3126 transparent inline def + (inline y : T ): T = num.plus(x, y)
@@ -36,12 +31,16 @@ object InlineNumeric:
3631 transparent inline def toLong : Long = num.toLong(x)
3732 transparent inline def toFloat : Float = num.toFloat(x)
3833 transparent inline def toDouble : Double = num.toDouble(x)
39-
4034 transparent inline def abs : T = num.abs(x)
41-
4235 transparent inline def sign : T = num.sign(x)
4336
4437trait InlineIntegral [T ] extends InlineNumeric [T ]:
38+ transparent inline def abs (inline x : T ): T = if lt(x, zero) then negate(x) else x
39+ transparent inline def sign (inline x : T ): T =
40+ if lt(x, zero) then negate(one)
41+ else if gt(x, zero) then one
42+ else zero
43+
4544 transparent inline def quot (inline x : T , inline y : T ): T
4645 transparent inline def rem (inline x : T , inline y : T ): T
4746
@@ -53,7 +52,16 @@ object InlineIntegral:
5352 transparent inline def /% (inline rhs : T ) = (int.quot(lhs, rhs), int.rem(lhs, rhs))
5453
5554trait InlineFractional [T ] extends InlineNumeric [T ]:
55+ transparent inline def abs (inline x : T ): T = if lt(x, zero) || isNegZero(x) then negate(x) else x
56+ transparent inline def sign (inline x : T ): T =
57+ if isNaN(x) || isNegZero(x) then x
58+ else if lt(x, zero) then negate(one)
59+ else if gt(x, zero) then one
60+ else zero
61+
5662 transparent inline def div (inline x : T , inline y : T ): T
63+ protected transparent inline def isNaN (inline x : T ): Boolean
64+ protected transparent inline def isNegZero (inline x : T ): Boolean
5765
5866object InlineFractional :
5967 // TODO: how are these imported/composed with Numeric/Fractional. Should the extension methods be defined in trait InlineFractional?
@@ -163,6 +171,8 @@ given FloatIsInlineFractional: InlineFractional[Float] with Ordering.Float.IeeeO
163171 transparent inline def toDouble (inline x : Float ): Double = x.toDouble
164172
165173 transparent inline def div (inline x : Float , inline y : Float ): Float = x / y
174+ protected transparent inline def isNaN (inline x : Float ): Boolean = x.isNaN
175+ protected transparent inline def isNegZero (inline x : Float ): Boolean = x.equals(- 0f )
166176
167177given DoubleIsInlineFractional : InlineFractional [Double ] with Ordering .Double .IeeeOrdering with
168178 transparent inline def plus (inline x : Double , inline y : Double ): Double = x + y
@@ -177,6 +187,8 @@ given DoubleIsInlineFractional: InlineFractional[Double] with Ordering.Double.Ie
177187 transparent inline def toDouble (inline x : Double ): Double = x
178188
179189 transparent inline def div (inline x : Double , inline y : Double ): Double = x / y
190+ protected transparent inline def isNaN (inline x : Double ): Boolean = x.isNaN
191+ protected transparent inline def isNegZero (inline x : Double ): Boolean = x.equals(- 0.0 )
180192
181193trait BigDecimalIsConflicted extends InlineNumeric [BigDecimal ] with Ordering .BigDecimalOrdering :
182194 transparent inline def plus (inline x : BigDecimal , inline y : BigDecimal ): BigDecimal = x + y
@@ -192,6 +204,9 @@ trait BigDecimalIsConflicted extends InlineNumeric[BigDecimal] with Ordering.Big
192204
193205given BigDecimalIsInlineFractional : BigDecimalIsConflicted with InlineFractional [BigDecimal ] with
194206 transparent inline def div (inline x : BigDecimal , inline y : BigDecimal ): BigDecimal = x / y
207+ protected transparent inline def isNaN (inline x : BigDecimal ): Boolean = false
208+ protected transparent inline def isNegZero (inline x : BigDecimal ): Boolean = false
209+
195210
196211given BigDecimalAsIfInlineIntegral : BigDecimalIsConflicted with InlineIntegral [BigDecimal ] with
197212 transparent inline def quot (inline x : BigDecimal , inline y : BigDecimal ): BigDecimal = x quot y
@@ -214,7 +229,8 @@ object tests:
214229
215230 inline def bar [T : InlineNumeric ](a : T ) = a.toInt
216231
217- inline def sign [T : InlineNumeric ](a : T ) = a.sign
232+ inline def signInt [T : InlineIntegral ](a : T ) = a.sign
233+ inline def signFrac [T : InlineFractional ](a : T ) = a.sign
218234
219235 def test (a : Int , b : Int ) =
220236 foo(a, b) // should be a + b * b // can check with -Xprint:inlining
@@ -226,6 +242,9 @@ object tests:
226242 bar(a.toFloat) // should be a.toFloat.toInt
227243 bar(a) // should be a
228244
229- sign(a)
230- sign(a.toChar)
231- sign(- 7F )
245+ signInt(a)
246+ signInt(a.toChar)
247+ signFrac(- 7F )
248+
249+ signInt(BigDecimal (a))
250+ signFrac(BigDecimal (a)) // the condition with isNan() should be removed
0 commit comments