| ... | @@ -245,25 +245,20 @@ pub fn floatExponentBits(comptime T: type) comptime_int { | ... | @@ -245,25 +245,20 @@ pub fn floatExponentBits(comptime T: type) comptime_int { |
| 245 | /// Given two types, returns the smallest one which is capable of holding the | 245 | /// Given two types, returns the smallest one which is capable of holding the |
| 246 | /// full range of the minimum value. | 246 | /// full range of the minimum value. |
| 247 | pub fn Min(comptime A: type, comptime B: type) type { | 247 | pub fn Min(comptime A: type, comptime B: type) type { |
| 248 | return switch (@typeInfo(A)) { | 248 | switch (@typeInfo(A)) { |
| 249 | .Int => |a_info| switch (@typeInfo(B)) { | 249 | .Int => |a_info| switch (@typeInfo(B)) { |
| 250 | .Int => |b_info| blk: { | 250 | .Int => |b_info| if (!a_info.is_signed and !b_info.is_signed) { |
| 251 | if (a_info.is_signed == b_info.is_signed) { | 251 | if (a_info.bits < b_info.bits) { |
| 252 | break :blk if (a_info.bits < b_info.bits) A else B; | 252 | return A; |
| 253 | } else if (a_info.is_signed) { | | |
| 254 | break :blk A; | | |
| 255 | } else { | 253 | } else { |
| 256 | break :blk B; | 254 | return B; |
| 257 | } | 255 | } |
| 258 | }, | 256 | }, |
| 259 | .ComptimeInt => A, | 257 | else => {}, |
| 260 | else => @compileError("unsupported type: " ++ @typeName(B)), | | |
| 261 | }, | 258 | }, |
| 262 | .Float => |a_info| if (a_info.bits < @typeInfo(B).Float.bits) A else B, | 259 | else => {}, |
| 263 | .ComptimeInt => B, | 260 | } |
| 264 | .ComptimeFloat => B, | 261 | return @typeOf(A(0) + B(0)); |
| 265 | else => @compileError("unsupported type: " ++ @typeName(A)), | | |
| 266 | }; | | |
| 267 | } | 262 | } |
| 268 | | 263 | |
| 269 | /// Returns the smaller number. When one of the parameter's type's full range fits in the other, | 264 | /// Returns the smaller number. When one of the parameter's type's full range fits in the other, |
| ... | @@ -275,7 +270,6 @@ pub fn min(x: var, y: var) Min(@typeOf(x), @typeOf(y)) { | ... | @@ -275,7 +270,6 @@ pub fn min(x: var, y: var) Min(@typeOf(x), @typeOf(y)) { |
| 275 | // scope it is known to fit in the return type. | 270 | // scope it is known to fit in the return type. |
| 276 | switch (@typeInfo(Result)) { | 271 | switch (@typeInfo(Result)) { |
| 277 | .Int => return @intCast(Result, x), | 272 | .Int => return @intCast(Result, x), |
| 278 | .Float => return @floatCast(Result, x), | | |
| 279 | else => return x, | 273 | else => return x, |
| 280 | } | 274 | } |
| 281 | } else { | 275 | } else { |
| ... | @@ -283,7 +277,6 @@ pub fn min(x: var, y: var) Min(@typeOf(x), @typeOf(y)) { | ... | @@ -283,7 +277,6 @@ pub fn min(x: var, y: var) Min(@typeOf(x), @typeOf(y)) { |
| 283 | // scope it is known to fit in the return type. | 277 | // scope it is known to fit in the return type. |
| 284 | switch (@typeInfo(Result)) { | 278 | switch (@typeInfo(Result)) { |
| 285 | .Int => return @intCast(Result, y), | 279 | .Int => return @intCast(Result, y), |
| 286 | .Float => return @floatCast(Result, y), | | |
| 287 | else => return y, | 280 | else => return y, |
| 288 | } | 281 | } |
| 289 | } | 282 | } |
| ... | @@ -302,9 +295,16 @@ test "math.min" { | ... | @@ -302,9 +295,16 @@ test "math.min" { |
| 302 | var a: f64 = 10.34; | 295 | var a: f64 = 10.34; |
| 303 | var b: f32 = 999.12; | 296 | var b: f32 = 999.12; |
| 304 | var result = min(a, b); | 297 | var result = min(a, b); |
| 305 | testing.expect(@typeOf(result) == f32); | 298 | testing.expect(@typeOf(result) == f64); |
| 306 | testing.expect(result == 10.34); | 299 | testing.expect(result == 10.34); |
| 307 | } | 300 | } |
| | 301 | { |
| | 302 | var a: i8 = -127; |
| | 303 | var b: i16 = -200; |
| | 304 | var result = min(a, b); |
| | 305 | testing.expect(@typeOf(result) == i16); |
| | 306 | testing.expect(result == -200); |
| | 307 | } |
| 308 | } | 308 | } |
| 309 | | 309 | |
| 310 | pub fn max(x: var, y: var) @typeOf(x + y) { | 310 | pub fn max(x: var, y: var) @typeOf(x + y) { |