UNPKG

locutus

Version:

Locutus other languages' standard libraries to JavaScript for fun and educational purposes

78 lines (77 loc) 2.29 kB
export function strtol(str, base = 10) { // discuss at: https://locutus.io/c/stdlib/strtol/ // parity verified: C 23 // original by: Kevin van Zonneveld (https://kvz.io) // note 1: Parses a string as a signed integer with optional radix support. // note 2: Supports base 0 auto-detection (0x => 16, leading 0 => 8, otherwise 10). // example 1: strtol('42', 10) // returns 1: 42 // example 2: strtol(' -0x2a', 0) // returns 2: -42 // example 3: strtol('077', 0) // returns 3: 63 const input = String(str); let index = 0; while (index < input.length && /\s/.test(input[index] ?? '')) { index += 1; } let sign = 1; if (input[index] === '+' || input[index] === '-') { if (input[index] === '-') { sign = -1; } index += 1; } const normalizedBase = normalizeBase(base, input, index); if (normalizedBase === 0) { return 0; } if (normalizedBase === 16 && (input.slice(index, index + 2) === '0x' || input.slice(index, index + 2) === '0X')) { index += 2; } let value = 0; let digits = 0; while (index < input.length) { const digit = charToDigit(input[index] ?? ''); if (digit < 0 || digit >= normalizedBase) { break; } value = value * normalizedBase + digit; digits += 1; index += 1; } if (digits === 0) { return 0; } return sign * value; } function normalizeBase(base, input, index) { const raw = Number(base); if (!Number.isFinite(raw)) { return 0; } if (raw === 0) { if (input.slice(index, index + 2) === '0x' || input.slice(index, index + 2) === '0X') { return 16; } if (input[index] === '0') { return 8; } return 10; } const radix = Math.trunc(raw); if (radix < 2 || radix > 36) { return 0; } return radix; } function charToDigit(char) { if (char >= '0' && char <= '9') { return char.charCodeAt(0) - 48; } const lower = char.toLowerCase(); if (lower >= 'a' && lower <= 'z') { return lower.charCodeAt(0) - 87; } return -1; }