///|
fn eng_numeric_prefix_bound(
  state : EngFormatterState,
  maximum~ : Bool,
) -> ScalarNumber raise @core.DataError {
  let keys = eng_state_prefixes(state).keys()
  if keys.is_empty() {
    raise @core.DataError::InvalidTicks(
      message=if maximum {
        "ValueError: max() iterable argument is empty"
      } else {
        "ValueError: min() iterable argument is empty"
      },
    )
  }
  let mut bound = keys[0].value()
  for index in 1.. String raise @core.DataError {
  let format = eng_places_format(state.places)
  let zero = ScalarNumber::Integer(@bigint.BigInt::from_int(0))
  let mut value = value
  let mut sign = ScalarNumber::Integer(@bigint.BigInt::from_int(1))
  if scalar_numeric_less(value, zero) {
    sign = ScalarNumber::Integer(@bigint.BigInt::from_int(-1))
    value = scalar_numeric_op(zero, value, 1)
  }
  let phase = if scalar_numeric_truth(Some(value)) {
    scalar_numeric_floor(scalar_math_log10(value) / 3.0) *
    @bigint.BigInt::from_int(3)
  } else {
    value = ScalarNumber::Number(0.0)
    @bigint.BigInt::from_int(0)
  }
  let lower = eng_numeric_prefix_bound(state, maximum=false)
  let upper = eng_numeric_prefix_bound(state, maximum=true)
  let mut power = eng_math_clip(phase, lower, upper)
  let signed = scalar_numeric_op(sign, value, 2)
  let denominator = scalar_math_power10(power, float_base=true)
  let mut mantissa = scalar_numeric_op(signed, denominator, 3)
  let rendered = method_format_float(
    scalar_numeric_double(mantissa),
    method_parse_spec(format, "float"),
  )
  let rounded = if rendered == "inf" || rendered == "-inf" {
    1.0 / 0.0
  } else if rendered == "nan" {
    0.0 / 0.0
  } else {
    Double::abs(try! @string.parse_double(rendered[:]))
  }
  if rounded >= 1000.0 &&
    eng_prefix_less(power, eng_numeric_prefix_bound(state, maximum=true)) {
    mantissa = scalar_numeric_op(
      mantissa,
      ScalarNumber::Integer(@bigint.BigInt::from_int(1000)),
      3,
    )
    power = scalar_numeric_op(
      power,
      ScalarNumber::Integer(@bigint.BigInt::from_int(3)),
      0,
    )
  }
  let key = scalar_numeric_integer(power)
  let prefix = match eng_state_prefixes(state).get(ScalarNumber::Integer(key)) {
    Some(prefix) => prefix
    None =>
      raise @core.DataError::InvalidTicks(
        message="KeyError: " + scalar_percent_integer_str(key),
      )
  }
  let suffix = if state.unit != "" || prefix != "" {
    state.sep + prefix + state.unit
  } else {
    ""
  }
  let delimiters = if state.scalar.usetex || state.scalar.use_math_text {
    2L
  } else {
    0L
  }
  let reserved = Int64::from_int(suffix.length()) + delimiters
  let text = method_format_float(
    scalar_numeric_double(mantissa),
    method_parse_spec(format, "float"),
    available=2147483647L - reserved,
  )
  if state.scalar.usetex || state.scalar.use_math_text {
    "$" + text + "$" + suffix
  } else {
    text + suffix
  }
}

///|
fn eng_named_call(
  base : BaseFormatter,
  state : EngFormatterState,
  value : ScalarNumber,
  pos : Int32?,
) -> String raise @core.DataError {
  if base.locations.length() == 0 ||
    scalar_numeric_equal(
      state.scalar.offset.unwrap_or(ScalarNumber::Number(0.0 / 0.0)),
      ScalarNumber::Integer(@bigint.BigInt::from_int(0)),
    ) {
    BaseFormatter::fix_minus(eng_named_format_data(state, value))
  } else {
    scalar_named_call(base, state.scalar, value, pos)
  }
}

///|
fn eng_named_prepare(
  base : BaseFormatter,
  state : EngFormatterState,
) -> Unit raise @core.DataError {
  if base.locations.length() == 0 {
    return
  }
  let (lower, upper) = scalar_numeric_view(base, sort=true)
  if state.scalar.use_offset {
    scalar_prepare_offset(base, state.scalar)
    if !scalar_numeric_equal(
        state.scalar.offset.unwrap_or(ScalarNumber::Number(0.0 / 0.0)),
        ScalarNumber::Integer(@bigint.BigInt::from_int(0)),
      ) {
      let sum = scalar_numeric_op(lower, upper, 0)
      let midpoint = scalar_numeric_op(
        sum,
        ScalarNumber::Integer(@bigint.BigInt::from_int(2)),
        3,
      )
      state.scalar.offset = Some(scalar_math_round_digits(midpoint, 3))
    }
  }
  state.scalar.order = eng_math_order(scalar_numeric_op(upper, lower, 1))
  scalar_prepare_format(base, state.scalar)
}

///|
fn eng_named_offset(
  base : BaseFormatter,
  state : EngFormatterState,
) -> String raise @core.DataError {
  if base.locations.length() == 0 || !scalar_numeric_truth(state.scalar.offset) {
    return ""
  }
  let offset = state.scalar.offset.unwrap()
  let mut offset_text = eng_named_format_data(state, offset)
  if scalar_numeric_less(
      ScalarNumber::Integer(@bigint.BigInt::from_int(0)),
      offset,
    ) {
    offset_text = "+" + offset_text
  }
  let scientific = eng_named_format_data(
    state,
    scalar_math_power10(state.scalar.order, float_base=false),
  )
  let text = if state.scalar.use_math_text || state.scalar.usetex {
    "$" +
    (if scientific != "" { "\\times" + scientific } else { "" }) +
    offset_text +
    "$"
  } else {
    scientific + offset_text
  }
  BaseFormatter::fix_minus(text)
}