authorgravatar for quae@daurnimator.comdaurnimator <quae@daurnimator.com> 2018-11-26 21:12:16+11:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-11-27 10:19:06-05:00
log2baf0e2ffc154d7915e690ddb4d892d1bafd5db2
treef33add4650707feefdcae29dcf346a8e4911185d
parent6bbe4cf9f7e0af4d3a15d42aece015792153c518

add std.math.IntFittingRange


1 files changed, 63 insertions(+), 0 deletions(-)

std/math/index.zig+63
...@@ -365,6 +365,69 @@ pub fn Log2Int(comptime T: type) type {...@@ -365,6 +365,69 @@ pub fn Log2Int(comptime T: type) type {
365 return @IntType(false, count);365 return @IntType(false, count);
366}366}
367367
368pub fn IntFittingRange(comptime from: comptime_int, comptime to: comptime_int) type {
369 assert(from <= to);
370 if (from == 0 and to == 0) {
371 return u0;
372 }
373 const is_signed = from < 0;
374 const largest_positive_integer = max(if (from<0) (-from)-1 else from, to); // two's complement
375 const base = log2(largest_positive_integer);
376 const upper = (1 << base) - 1;
377 var magnitude_bits = if (upper >= largest_positive_integer) base else base + 1;
378 if (is_signed) {
379 magnitude_bits += 1;
380 }
381 return @IntType(is_signed, magnitude_bits);
382}
383
384test "math.IntFittingRange" {
385 assert(IntFittingRange(0, 0) == u0);
386 assert(IntFittingRange(0, 1) == u1);
387 assert(IntFittingRange(0, 2) == u2);
388 assert(IntFittingRange(0, 3) == u2);
389 assert(IntFittingRange(0, 4) == u3);
390 assert(IntFittingRange(0, 7) == u3);
391 assert(IntFittingRange(0, 8) == u4);
392 assert(IntFittingRange(0, 9) == u4);
393 assert(IntFittingRange(0, 15) == u4);
394 assert(IntFittingRange(0, 16) == u5);
395 assert(IntFittingRange(0, 17) == u5);
396 assert(IntFittingRange(0, 4095) == u12);
397 assert(IntFittingRange(2000, 4095) == u12);
398 assert(IntFittingRange(0, 4096) == u13);
399 assert(IntFittingRange(2000, 4096) == u13);
400 assert(IntFittingRange(0, 4097) == u13);
401 assert(IntFittingRange(2000, 4097) == u13);
402 assert(IntFittingRange(0, 123456789123456798123456789) == u87);
403 assert(IntFittingRange(0, 123456789123456798123456789123456789123456798123456789) == u177);
404
405 assert(IntFittingRange(-1, -1) == i1);
406 assert(IntFittingRange(-1, 0) == i1);
407 assert(IntFittingRange(-1, 1) == i2);
408 assert(IntFittingRange(-2, -2) == i2);
409 assert(IntFittingRange(-2, -1) == i2);
410 assert(IntFittingRange(-2, 0) == i2);
411 assert(IntFittingRange(-2, 1) == i2);
412 assert(IntFittingRange(-2, 2) == i3);
413 assert(IntFittingRange(-1, 2) == i3);
414 assert(IntFittingRange(-1, 3) == i3);
415 assert(IntFittingRange(-1, 4) == i4);
416 assert(IntFittingRange(-1, 7) == i4);
417 assert(IntFittingRange(-1, 8) == i5);
418 assert(IntFittingRange(-1, 9) == i5);
419 assert(IntFittingRange(-1, 15) == i5);
420 assert(IntFittingRange(-1, 16) == i6);
421 assert(IntFittingRange(-1, 17) == i6);
422 assert(IntFittingRange(-1, 4095) == i13);
423 assert(IntFittingRange(-4096, 4095) == i13);
424 assert(IntFittingRange(-1, 4096) == i14);
425 assert(IntFittingRange(-4097, 4095) == i14);
426 assert(IntFittingRange(-1, 4097) == i14);
427 assert(IntFittingRange(-1, 123456789123456798123456789) == i88);
428 assert(IntFittingRange(-1, 123456789123456798123456789123456789123456798123456789) == i178);
429}
430
368test "math overflow functions" {431test "math overflow functions" {
369 testOverflow();432 testOverflow();
370 comptime testOverflow();433 comptime testOverflow();