| ... | ... | @@ -2,6 +2,7 @@ const std = @import("../index.zig"); |
| 2 | 2 | const math = std.math; |
| 3 | 3 | const debug = std.debug; |
| 4 | 4 | const assert = debug.assert; |
| 5 | const assertError = debug.assertError; |
| 5 | 6 | const mem = std.mem; |
| 6 | 7 | const builtin = @import("builtin"); |
| 7 | 8 | const errol = @import("errol/index.zig"); |
| ... | ... | @@ -811,13 +812,41 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) ParseUnsigned |
| 811 | 812 | |
| 812 | 813 | for (buf) |c| { |
| 813 | 814 | const digit = try charToDigit(c, radix); |
| 814 | | x = try math.mul(T, x, radix); |
| 815 | | x = try math.add(T, x, digit); |
| 815 | |
| 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 | } |
| 817 | 819 | |
| 818 | 820 | return x; |
| 819 | 821 | } |
| 820 | 822 | |
| 823 | test "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 | |
| 821 | 850 | pub fn charToDigit(c: u8, radix: u8) (error{InvalidCharacter}!u8) { |
| 822 | 851 | const value = switch (c) { |
| 823 | 852 | '0'...'9' => c - '0', |