11const std = @import ("../std.zig" );
22const math = std .math ;
3+ const assert = std .debug .assert ;
34const expect = std .testing .expect ;
45const expectEqual = std .testing .expectEqual ;
56const expectApproxEqAbs = std .testing .expectApproxEqAbs ;
@@ -20,8 +21,10 @@ pub fn Frexp(comptime T: type) type {
2021/// - frexp(nan) = nan, undefined
2122pub fn frexp (x : anytype ) Frexp (@TypeOf (x )) {
2223 const T : type = @TypeOf (x );
24+ const info = @typeInfo (T );
25+ comptime assert (info == .float or info == .comptime_float );
2326
24- const bits : comptime_int = @typeInfo ( T ) .float .bits ;
27+ const bits : comptime_int = if ( info == .float ) info .float .bits else 128 ;
2528 const Int : type = std .meta .Int (.unsigned , bits );
2629
2730 const exp_bits : comptime_int = math .floatExponentBits (T );
@@ -43,7 +46,7 @@ pub fn frexp(x: anytype) Frexp(@TypeOf(x)) {
4346 const extra_denorm_shift : comptime_int = 1 - ones_place ;
4447
4548 var result : Frexp (T ) = undefined ;
46- var v : Int = @bitCast (x );
49+ var v : Int = if ( info == .float ) @bitCast (x ) else @bitCast ( @as ( f128 , x ) );
4750
4851 const m : MantInt = @truncate (v );
4952 const e : ExpInt = @truncate (v >> mant_bits );
@@ -81,7 +84,7 @@ pub fn frexp(x: anytype) Frexp(@TypeOf(x)) {
8184 },
8285 }
8386
84- result .significand = @bitCast (v );
87+ result .significand = if ( info == .float ) @bitCast (v ) else @as ( f128 , @bitCast ( v ) );
8588 return result ;
8689}
8790
@@ -91,23 +94,22 @@ fn FrexpTests(comptime Float: type) type {
9194 const T = Float ;
9295 test "normal" {
9396 const epsilon = 1e-6 ;
94- var r : Frexp (T ) = undefined ;
9597
96- r = frexp (@as (T , 1.3 ));
97- try expectApproxEqAbs (0.65 , r .significand , epsilon );
98- try expectEqual (1 , r .exponent );
98+ const r1 = frexp (@as (T , 1.3 ));
99+ try expectApproxEqAbs (0.65 , r1 .significand , epsilon );
100+ try expectEqual (1 , r1 .exponent );
99101
100- r = frexp (@as (T , 78.0234 ));
101- try expectApproxEqAbs (0.609558 , r .significand , epsilon );
102- try expectEqual (7 , r .exponent );
102+ const r2 = frexp (@as (T , 78.0234 ));
103+ try expectApproxEqAbs (0.609558 , r2 .significand , epsilon );
104+ try expectEqual (7 , r2 .exponent );
103105
104- r = frexp (@as (T , -1234.5678 ));
105- try expectEqual (11 , r .exponent );
106- try expectApproxEqAbs (-0.602816 , r .significand , epsilon );
106+ const r3 = frexp (@as (T , -1234.5678 ));
107+ try expectEqual (11 , r3 .exponent );
108+ try expectApproxEqAbs (-0.602816 , r3 .significand , epsilon );
107109 }
108110 test "max" {
109111 const exponent = math .floatExponentMax (T ) + 1 ;
110- const significand = 1.0 - math .floatEps (T ) / 2 ;
112+ const significand = 1.0 - math .floatEps (T ) / 2.0 ;
111113 const r : Frexp (T ) = frexp (math .floatMax (T ));
112114 try expectEqual (exponent , r .exponent );
113115 try expectEqual (significand , r .significand );
@@ -126,17 +128,16 @@ fn FrexpTests(comptime Float: type) type {
126128 try expectEqual (0.5 , r .significand );
127129 }
128130 test "zero" {
129- var r : Frexp (T ) = undefined ;
131+ const r1 = frexp (@as (T , 0.0 ));
132+ try expectEqual (0 , r1 .exponent );
133+ try expect (math .isPositiveZero (r1 .significand ));
130134
131- r = frexp (@as (T , 0.0 ));
132- try expectEqual (0 , r .exponent );
133- try expect (math .isPositiveZero (r .significand ));
134-
135- r = frexp (@as (T , -0.0 ));
136- try expectEqual (0 , r .exponent );
137- try expect (math .isNegativeZero (r .significand ));
135+ const r2 = frexp (@as (T , -0.0 ));
136+ try expectEqual (0 , r2 .exponent );
137+ try expect (math .isNegativeZero (r2 .significand ));
138138 }
139139 test "inf" {
140+ if (T == comptime_float ) return ;
140141 var r : Frexp (T ) = undefined ;
141142
142143 r = frexp (math .inf (T ));
@@ -148,6 +149,7 @@ fn FrexpTests(comptime Float: type) type {
148149 try expect (math .isNegativeInf (r .significand ));
149150 }
150151 test "nan" {
152+ if (T == comptime_float ) return ;
151153 const r : Frexp (T ) = frexp (math .nan (T ));
152154 try expect (math .isNan (r .significand ));
153155 }
@@ -156,53 +158,64 @@ fn FrexpTests(comptime Float: type) type {
156158
157159// Generate tests for each floating point type
158160comptime {
159- for ([_ ]type { f16 , f32 , f64 , f80 , f128 }) | T | {
161+ for ([_ ]type { f16 , f32 , f64 , f80 , f128 , comptime_float }) | T | {
160162 _ = FrexpTests (T );
161163 }
162164}
163165
164166test frexp {
165- inline for ([_ ]type { f16 , f32 , f64 , f80 , f128 }) | T | {
167+ @setEvalBranchQuota (1_500 );
168+
169+ inline for ([_ ]type { f16 , f32 , f64 , f80 , f128 , comptime_float }) | T | {
166170 const max_exponent = math .floatExponentMax (T ) + 1 ;
167171 const min_exponent = math .floatExponentMin (T ) + 1 ;
168172 const truemin_exponent = min_exponent - math .floatFractionalBits (T );
169173
170- var result : Frexp (T ) = undefined ;
171- comptime var x : T = undefined ;
172-
173174 // basic usage
174175 // value -> {significand, exponent},
175176 // value == significand * (2 ^ exponent)
176- x = 1234.5678 ;
177- result = frexp (x );
178- try expectEqual (11 , result .exponent );
179- try expectApproxEqAbs (0.602816 , result .significand , 1e-6 );
180- try expectEqual (x , math .ldexp (result .significand , result .exponent ));
177+ const x1 = 1234.5678 ;
178+ const result1 = frexp (x1 );
179+ try expectEqual (11 , result1 .exponent );
180+ try expectApproxEqAbs (0.602816 , result1 .significand , 1e-6 );
181+ try expectEqual (x1 , math .ldexp (result1 .significand , result1 .exponent ));
181182
182183 // float maximum
183- x = math .floatMax (T );
184- result = frexp (x );
185- try expectEqual (max_exponent , result .exponent );
186- try expectEqual (1.0 - math .floatEps (T ) / 2 , result .significand );
187- try expectEqual (x , math .ldexp (result .significand , result .exponent ));
184+ const x2 = math .floatMax (T );
185+ const result2 = frexp (x2 );
186+ try expectEqual (max_exponent , result2 .exponent );
187+ try expectEqual (1.0 - math .floatEps (T ) / 2.0 , result2 .significand );
188+ try expectEqual (x2 , math .ldexp (result2 .significand , result2 .exponent ));
188189
189190 // float minimum
190- x = math .floatMin (T );
191- result = frexp (x );
192- try expectEqual (min_exponent , result .exponent );
193- try expectEqual (0.5 , result .significand );
194- try expectEqual (x , math .ldexp (result .significand , result .exponent ));
191+ const x3 = math .floatMin (T );
192+ const result3 = frexp (x3 );
193+ try expectEqual (min_exponent , result3 .exponent );
194+ try expectEqual (0.5 , result3 .significand );
195+ try expectEqual (x3 , math .ldexp (result3 .significand , result3 .exponent ));
195196
196197 // float true minimum
197198 // subnormal -> {normal, exponent}
198- x = math .floatTrueMin (T );
199- result = frexp (x );
200- try expectEqual (truemin_exponent , result .exponent );
201- try expectEqual (0.5 , result .significand );
202- try expectEqual (x , math .ldexp (result .significand , result .exponent ));
199+ const x4 = math .floatTrueMin (T );
200+ const result4 = frexp (x4 );
201+ try expectEqual (truemin_exponent , result4 .exponent );
202+ try expectEqual (0.5 , result4 .significand );
203+ try expectEqual (x4 , math .ldexp (result4 .significand , result4 .exponent ));
204+
205+ // zero -> {zero, zero} (+)
206+ const result5 = frexp (@as (T , 0.0 ));
207+ try expectEqual (0 , result5 .exponent );
208+ try expect (math .isPositiveZero (result5 .significand ));
209+
210+ // zero -> {zero, zero} (-)
211+ const result6 = frexp (@as (T , -0.0 ));
212+ try expectEqual (0 , result6 .exponent );
213+ try expect (math .isNegativeZero (result6 .significand ));
214+
215+ if (T == comptime_float ) return ;
203216
204217 // infinity -> {infinity, zero} (+)
205- result = frexp (math .inf (T ));
218+ var result = frexp (math .inf (T ));
206219 try expectEqual (0 , result .exponent );
207220 try expect (math .isPositiveInf (result .significand ));
208221
@@ -211,16 +224,6 @@ test frexp {
211224 try expectEqual (0 , result .exponent );
212225 try expect (math .isNegativeInf (result .significand ));
213226
214- // zero -> {zero, zero} (+)
215- result = frexp (@as (T , 0.0 ));
216- try expectEqual (0 , result .exponent );
217- try expect (math .isPositiveZero (result .significand ));
218-
219- // zero -> {zero, zero} (-)
220- result = frexp (@as (T , -0.0 ));
221- try expectEqual (0 , result .exponent );
222- try expect (math .isNegativeZero (result .significand ));
223-
224227 // nan -> {nan, undefined}
225228 result = frexp (math .nan (T ));
226229 try expect (math .isNan (result .significand ));
0 commit comments