// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. // Shared functionality used by multiple classes and their implementations. int validateRadix(int radix) => RangeError.checkValueInInterval(radix, 2, 36, 'radix'); /// Converts radix digits into their numeric values. /// /// Converts the characters `0`-`9` into the values 0 through 9, /// and the letters `a`-`z` or `A`-`Z` into values 10 through 35, /// and return that value. /// Any other character returns a value above 35, which means it's /// not a valid digit in any radix in the range 2 through 36. int decodeDigit(int c) { // Hex digit char codes const c0 = 48; // '0'.codeUnitAt(0) const ca = 97; // 'a'.codeUnitAt(0) var digit = c ^ c0; if (digit < 10) return digit; var letter = (c | 0x20) - ca; if (letter >= 0) { // Returns values above 36 for invalid digits. // The value is checked against the actual radix where the return // value is used, so this is safe. return letter + 10; } else { return 255; // Never a valid radix. } } // Assumes i is <= 32-bit int numberOfLeadingZeros(int i) { i |= i >> 1; i |= i >> 2; i |= i >> 4; i |= i >> 8; i |= i >> 16; return bitCount(~i); } int numberOfTrailingZeros(int i) => bitCount((i & -i) - 1); // Assumes i is <= 32-bit. int bitCount(int i) { // See "Hacker's Delight", section 5-1, "Counting 1-Bits". // The basic strategy is to use "divide and conquer" to // add pairs (then quads, etc.) of bits together to obtain // sub-counts. // // A straightforward approach would look like: // // i = (i & 0x55555555) + ((i >> 1) & 0x55555555); // i = (i & 0x33333333) + ((i >> 2) & 0x33333333); // i = (i & 0x0F0F0F0F) + ((i >> 4) & 0x0F0F0F0F); // i = (i & 0x00FF00FF) + ((i >> 8) & 0x00FF00FF); // i = (i & 0x0000FFFF) + ((i >> 16) & 0x0000FFFF); // // The code below removes unnecessary &'s and uses a // trick to remove one instruction in the first line. i -= (i >> 1) & 0x55555555; i = (i & 0x33333333) + ((i >> 2) & 0x33333333); i = (i + (i >> 4)) & 0x0F0F0F0F; i += i >> 8; i += i >> 16; return i & 0x0000003F; }