///|
pub impl AddContextual for Double with fn add_contextual(left, right, _context) {
  Ok(ArithmeticOutcome::exact(left + right))
}

///|
pub impl SubContextual for Double with fn sub_contextual(left, right, _context) {
  Ok(ArithmeticOutcome::exact(left - right))
}

///|
pub impl MulContextual for Double with fn mul_contextual(left, right, _context) {
  Ok(ArithmeticOutcome::exact(left * right))
}

///|
pub impl DivContextual for Double with fn div_contextual(left, right, context) {
  DivChecked::div_checked(left, right, context).map(ArithmeticOutcome::exact)
}

///|
pub impl AbsContextual for Double with fn abs_contextual(value, _context) {
  Ok(ArithmeticOutcome::exact(value.abs()))
}

///|
pub impl SqrtContextual for Double with fn sqrt_contextual(value, context) {
  SqrtChecked::sqrt_checked(value, context).map(ArithmeticOutcome::exact)
}

///|
pub impl ExpContextual for Double with fn exp_contextual(value, _context) {
  Ok(ArithmeticOutcome::exact(Exponential::exp(value)))
}

///|
pub impl NumericFormatContextual for Double with fn zero_contextual(_context) {
  0.0
}

///|
pub impl NumericFormatContextual for Double with fn one_contextual(_context) {
  1.0
}

///|
pub impl NumericFormatContextual for Double with fn epsilon_contextual(_context) {
  2.220446049250313e-16
}

///|
pub impl NumericFormatContextual for Double with fn min_normal_contextual(
  _context,
) {
  2.2250738585072014e-308
}

///|
pub impl NumericFormatContextual for Double with fn max_finite_contextual(
  _context,
) {
  1.7976931348623157e308
}

///|
pub impl NumericFormatContextual for Double with fn classify_contextual(value) {
  if Double::is_nan(value) {
    FpClass::NaN
  } else if Double::is_inf(value) {
    FpClass::Infinity
  } else {
    FpClass::Finite
  }
}

///|
pub impl AddContextual for Float with fn add_contextual(left, right, _context) {
  Ok(ArithmeticOutcome::exact(left + right))
}

///|
pub impl SubContextual for Float with fn sub_contextual(left, right, _context) {
  Ok(ArithmeticOutcome::exact(left - right))
}

///|
pub impl MulContextual for Float with fn mul_contextual(left, right, _context) {
  Ok(ArithmeticOutcome::exact(left * right))
}

///|
pub impl DivContextual for Float with fn div_contextual(left, right, context) {
  DivChecked::div_checked(left, right, context).map(ArithmeticOutcome::exact)
}

///|
pub impl AbsContextual for Float with fn abs_contextual(value, _context) {
  Ok(ArithmeticOutcome::exact(value.abs()))
}

///|
pub impl SqrtContextual for Float with fn sqrt_contextual(value, context) {
  SqrtChecked::sqrt_checked(value, context).map(ArithmeticOutcome::exact)
}

///|
pub impl ExpContextual for Float with fn exp_contextual(value, _context) {
  Ok(ArithmeticOutcome::exact(Exponential::exp(value)))
}

///|
pub impl NumericFormatContextual for Float with fn zero_contextual(_context) {
  0.0F
}

///|
pub impl NumericFormatContextual for Float with fn one_contextual(_context) {
  1.0F
}

///|
pub impl NumericFormatContextual for Float with fn epsilon_contextual(_context) {
  1.1920929e-7F
}

///|
pub impl NumericFormatContextual for Float with fn min_normal_contextual(
  _context,
) {
  1.1754944e-38F
}

///|
pub impl NumericFormatContextual for Float with fn max_finite_contextual(
  _context,
) {
  3.4028235e38F
}

///|
pub impl NumericFormatContextual for Float with fn classify_contextual(value) {
  if Float::is_nan(value) {
    FpClass::NaN
  } else if Float::is_inf(value) {
    FpClass::Infinity
  } else {
    FpClass::Finite
  }
}