TheAlgorithms/Go · error

integer must be between 1 and 3999

Error message

integer must be between 1 and 3999

What it means

Sentinel-style guard in IntToRoman: the lookup-table approach only covers roman numerals for 1-3999, so any integer outside that range (including 0 and negatives) is rejected rather than producing a wrong numeral.

Source

Thrown at conversion/inttoroman.go:25

package conversion

import (
	"errors"
)

var (
	// lookup arrays used for converting from an int to a roman numeral extremely quickly.
	r0 = []string{"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"} // 1 - 9
	r1 = []string{"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"} // 10 - 90
	r2 = []string{"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"} // 100 - 900
	r3 = []string{"", "M", "MM", "MMM"}                                       // 1,000 - 3,000
)

// IntToRoman converts an integer value to a roman numeral string. An error is
// returned if the integer is not between 1 and 3999.
func IntToRoman(n int) (string, error) {
	if n < 1 || n > 3999 {
		return "", errors.New("integer must be between 1 and 3999")
	}
	// Concatenate strings for each of 4 lookup array categories.
	//
	// Key behavior to note here is how math with integers is handled. Values are floored to the
	// nearest int, not rounded up. For example, 26/10 = 2 even though the actual result is 2.6.
	//
	// For example, lets use an input value of 126:
	// `r3[n%1e4/1e3]` --> 126 % 10_000 = 126 --> 126 / 1_000 = 0.126 (0 as int) --> r3[0] = ""
	// `r2[n%1e3/1e2]` --> 126 % 1_000 = 126 --> 126 / 100 = 1.26 (1 as int) --> r2[1] = "C"
	// `r1[n%100/10]` --> 126 % 100 = 26 --> 26 / 10 = 2.6 (2 as int) --> r1[2] = "XX"
	// `r0[n%10]` --> 126 % 10 = 6 --> r0[6] = "VI"
	// FINAL --> "" + "C" + "XX" + "VI" = "CXXVI"
	//
	// This is efficient in Go. The 4 operands are evaluated,
	// then a single allocation is made of the exact size needed for the result.
	return r3[n%1e4/1e3] + r2[n%1e3/1e2] + r1[n%100/10] + r0[n%10], nil
}

View on GitHub (pinned to 5ba447ec5f)

Solutions

  1. Clamp or reject the value at the call site before calling IntToRoman
  2. For values >3999, use an overline/extended notation library or format as repeated 'M' prefix manually
  3. Return a domain-specific error to the caller explaining the supported range
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at conversion/inttoroman.go:25 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of TheAlgorithms/Go@5ba447ec5f (2026-09-02). Data as JSON: /api/errors/cb72e021e7caa688. Report an issue: GitHub.