authorgravatar for dbandstra@protonmail.comdbandstra <dbandstra@protonmail.com> 2018-11-27 21:17:45-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-11-29 09:53:43-05:00
log53766e7a3a5c7141a64e21c30540f9ed571cdfdd
treebe77d2b811c4381921bc63bcf32b822593802582
parent4ecb3ceafb7e82f1d2b44059b9bbb266aa1dce00

make parseUnsigned handle types <8 bits wide


1 files changed, 31 insertions(+), 2 deletions(-)

std/fmt/index.zig+31-2
...@@ -2,6 +2,7 @@ const std = @import("../index.zig");...@@ -2,6 +2,7 @@ const std = @import("../index.zig");
2const math = std.math;2const math = std.math;
3const debug = std.debug;3const debug = std.debug;
4const assert = debug.assert;4const assert = debug.assert;
5const assertError = debug.assertError;
5const mem = std.mem;6const mem = std.mem;
6const builtin = @import("builtin");7const builtin = @import("builtin");
7const errol = @import("errol/index.zig");8const errol = @import("errol/index.zig");
...@@ -811,13 +812,41 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) ParseUnsigned...@@ -811,13 +812,41 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) ParseUnsigned
811812
812 for (buf) |c| {813 for (buf) |c| {
813 const digit = try charToDigit(c, radix);814 const digit = try charToDigit(c, radix);
814 x = try math.mul(T, x, radix);815
815 x = try math.add(T, x, digit);816 if (x != 0) x = try math.mul(T, x, try math.cast(T, radix));
817 x = try math.add(T, x, try math.cast(T, digit));
816 }818 }
817819
818 return x;820 return x;
819}821}
820822
823test "parseUnsigned" {
824 assert((try parseUnsigned(u16, "050124", 10)) == 50124);
825 assert((try parseUnsigned(u16, "65535", 10)) == 65535);
826 assertError(parseUnsigned(u16, "65536", 10), error.Overflow);
827
828 assert((try parseUnsigned(u64, "0ffffffffffffffff", 16)) == 0xffffffffffffffff);
829 assertError(parseUnsigned(u64, "10000000000000000", 16), error.Overflow);
830
831 assert((try parseUnsigned(u32, "DeadBeef", 16)) == 0xDEADBEEF);
832
833 assert((try parseUnsigned(u7, "1", 10)) == 1);
834 assert((try parseUnsigned(u7, "1000", 2)) == 8);
835
836 assertError(parseUnsigned(u32, "f", 10), error.InvalidCharacter);
837 assertError(parseUnsigned(u8, "109", 8), error.InvalidCharacter);
838
839 assert((try parseUnsigned(u32, "NUMBER", 36)) == 1442151747);
840
841 // these numbers should fit even though the radix itself doesn't fit in the destination type
842 assert((try parseUnsigned(u1, "0", 10)) == 0);
843 assert((try parseUnsigned(u1, "1", 10)) == 1);
844 assertError(parseUnsigned(u1, "2", 10), error.Overflow);
845 assert((try parseUnsigned(u1, "001", 16)) == 1);
846 assert((try parseUnsigned(u2, "3", 16)) == 3);
847 assertError(parseUnsigned(u2, "4", 16), error.Overflow);
848}
849
821pub fn charToDigit(c: u8, radix: u8) (error{InvalidCharacter}!u8) {850pub fn charToDigit(c: u8, radix: u8) (error{InvalidCharacter}!u8) {
822 const value = switch (c) {851 const value = switch (c) {
823 '0'...'9' => c - '0',852 '0'...'9' => c - '0',