Implement precise string-based decimal addition
Company: Mixpanel
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Given two non-empty strings representing decimal numbers (e.g., "123.456" and "6234.42432"), implement a function that returns their exact sum as a string without using floating-point arithmetic or big-number libraries and without precision loss. Inputs may be very large (up to 1e5 total digits) and may contain leading/trailing zeros and decimal points but no scientific notation. Describe how you align fractional parts, propagate carries across the decimal point, and normalize the output (e.g., removing unnecessary leading/trailing zeros while preserving a fractional zero when needed). State time and space complexity and provide tests for edge cases such as different fractional lengths, one operand lacking a fractional part, all-zero values, and very large inputs.
Quick Answer: This question evaluates a candidate's proficiency in string-based arbitrary-precision arithmetic, including decimal alignment, fractional carry propagation, normalization of numeric strings, and analysis of time and space complexity.
Given two non-empty strings representing decimal numbers (e.g. "123.456" and "6234.42432"), return their exact sum as a string WITHOUT using floating-point arithmetic or any big-number library, and without any precision loss.
Inputs may be very large (up to 1e5 total digits) and may contain leading zeros, trailing zeros, and a decimal point, but no scientific notation. An optional leading sign ('+' or '-') may be present.
Approach: align the fractional parts by right-padding the shorter one with zeros, align the integer parts by left-padding with zeros, then add (or subtract, when signs differ) digit-by-digit from least to most significant while propagating the carry/borrow straight across the decimal point. Finally normalize the output: strip unnecessary leading zeros in the integer part (keeping at least one), strip trailing zeros in the fractional part, drop a bare decimal point, and avoid producing '-0'.
Return the normalized sum string.
Examples:
solution("123.456", "6234.42432") -> "6357.88032"
solution("999.999", "0.001") -> "1000"
solution("0.000", "0.0") -> "0"
solution("-5.5", "3.25") -> "-2.25"
Constraints
- Both inputs are non-empty strings representing decimal numbers.
- Up to 1e5 total digits per input.
- May contain leading zeros, trailing zeros, and a single decimal point.
- An optional leading '+' or '-' sign may be present.
- No scientific notation.
- No floating-point arithmetic and no big-number libraries; the result must be exact.
Examples
Input: ("123.456", "6234.42432")
Expected Output: "6357.88032"
Explanation: Different fractional lengths (3 vs 5); the shorter fraction is right-padded with zeros before adding.
Input: ("0.1", "0.2")
Expected Output: "0.3"
Explanation: The classic case where binary floating point would give 0.30000000000000004; string addition is exact.
Hints
- Separate each number into sign, integer part, and fractional part by splitting on the '.' character.
- Right-pad the shorter fractional part with zeros and left-pad the shorter integer part with zeros so both operands have identically positioned digits, then add column-by-column from the right and let the carry flow straight across the (now-aligned) decimal point.
- When signs differ, compare magnitudes of the aligned digit strings and subtract the smaller from the larger, taking the sign of the larger.
- Normalize at the end: strip leading zeros from the integer part (keep at least one), strip trailing zeros from the fractional part, drop the decimal point if no fractional digits remain, and never emit '-0'.