Functional Weave
Code in TypeScript

math.rational@2.0.0

vectors.json

16,879 bytes · view raw

[
  {"fn": "calculateRational", "name": "a third plus a sixth is a half", "args": [{"numerator": 1, "denominator": 3}, "add", {"numerator": 1, "denominator": 6}], "expect": {"numerator": 1, "denominator": 2}},
  {"fn": "calculateRational", "name": "one tenth plus two tenths is exactly three tenths, unlike 0.1 + 0.2", "args": [{"numerator": 1, "denominator": 10}, "add", {"numerator": 2, "denominator": 10}], "expect": {"numerator": 3, "denominator": 10}},
  {"fn": "calculateRational", "name": "subtracting past zero gives a negative numerator", "args": [{"numerator": 3, "denominator": 4}, "subtract", {"numerator": 5, "denominator": 4}], "expect": {"numerator": -1, "denominator": 2}},
  {"fn": "calculateRational", "name": "equal values subtract to zero over one", "args": [{"numerator": 1, "denominator": 2}, "subtract", {"numerator": 2, "denominator": 4}], "expect": {"numerator": 0, "denominator": 1}},
  {"fn": "calculateRational", "name": "multiplying reduces the result", "args": [{"numerator": 2, "denominator": 3}, "multiply", {"numerator": 9, "denominator": 4}], "expect": {"numerator": 3, "denominator": 2}},
  {"fn": "calculateRational", "name": "dividing by a quarter doubles a half into a whole number", "args": [{"numerator": 1, "denominator": 2}, "divide", {"numerator": 1, "denominator": 4}], "expect": {"numerator": 2, "denominator": 1}},
  {"fn": "calculateRational", "name": "dividing by a negative puts the sign on the numerator", "args": [{"numerator": 1, "denominator": 3}, "divide", {"numerator": -2, "denominator": 3}], "expect": {"numerator": -1, "denominator": 2}},
  {"fn": "calculateRational", "name": "unreduced inputs with a negative denominator are normalised", "args": [{"numerator": 2, "denominator": -4}, "add", {"numerator": 0, "denominator": 5}], "expect": {"numerator": -1, "denominator": 2}},
  {"fn": "calculateRational", "name": "negative over negative is positive", "args": [{"numerator": -3, "denominator": -9}, "multiply", {"numerator": 1, "denominator": 1}], "expect": {"numerator": 1, "denominator": 3}},
  {"fn": "calculateRational", "name": "unreduced products past 2^53 still reduce exactly", "args": [{"numerator": 9007199254740991, "denominator": 2}, "multiply", {"numerator": 2, "denominator": 9007199254740991}], "expect": {"numerator": 1, "denominator": 1}},
  {"fn": "calculateRational", "name": "a common denominator past 2^53 before reducing", "args": [{"numerator": 1, "denominator": 4503599627370496}, "add", {"numerator": 1, "denominator": 4503599627370496}], "expect": {"numerator": 1, "denominator": 2251799813685248}},
  {"fn": "calculateRational", "name": "an exchange rate and its inverse multiply to exactly one", "args": [{"numerator": 11734, "denominator": 10000}, "multiply", {"numerator": 10000, "denominator": 11734}], "expect": {"numerator": 1, "denominator": 1}},
  {"fn": "calculateRational", "name": "a numerator past 2^53 - 1 is an overflow, not a rounded number", "args": [{"numerator": 9007199254740991, "denominator": 1}, "add", {"numerator": 1, "denominator": 1}], "expectError": "rational overflow"},
  {"fn": "calculateRational", "name": "a denominator past 2^53 - 1 is an overflow", "args": [{"numerator": 1, "denominator": 9007199254740991}, "multiply", {"numerator": 1, "denominator": 2}], "expectError": "rational overflow"},
  {"fn": "calculateRational", "name": "dividing by zero is an error", "args": [{"numerator": 1, "denominator": 2}, "divide", {"numerator": 0, "denominator": 5}], "expectError": "division by zero"},
  {"fn": "calculateRational", "name": "a zero denominator is an error", "args": [{"numerator": 1, "denominator": 0}, "add", {"numerator": 1, "denominator": 2}], "expectError": "denominator must not be zero"},
  {"fn": "calculateRational", "name": "an unknown operation is an error", "args": [{"numerator": 1, "denominator": 2}, "power", {"numerator": 1, "denominator": 2}], "expectError": "unknown operation"},
  {"fn": "rational", "name": "six eighths reduces to three quarters", "args": [6, 8], "expect": {"numerator": 3, "denominator": 4}},
  {"fn": "rational", "name": "already reduced is unchanged", "args": [3, 7], "expect": {"numerator": 3, "denominator": 7}},
  {"fn": "rational", "name": "a negative denominator moves the sign to the numerator", "args": [3, -9], "expect": {"numerator": -1, "denominator": 3}},
  {"fn": "rational", "name": "negative over negative is positive", "args": [-10, -4], "expect": {"numerator": 5, "denominator": 2}},
  {"fn": "rational", "name": "zero is zero over one, whatever the denominator", "args": [0, -17], "expect": {"numerator": 0, "denominator": 1}},
  {"fn": "rational", "name": "a whole number has denominator one", "args": [12, 4], "expect": {"numerator": 3, "denominator": 1}},
  {"fn": "rational", "name": "the largest safe parts reduce to one", "args": [9007199254740991, -9007199254740991], "expect": {"numerator": -1, "denominator": 1}},
  {"fn": "rational", "name": "the largest safe numerator over one", "args": [9007199254740991, 1], "expect": {"numerator": 9007199254740991, "denominator": 1}},
  {"fn": "rational", "name": "a zero denominator is an error", "args": [5, 0], "expectError": "denominator must not be zero"},
  {"fn": "rational", "name": "a numerator past 2^53 - 1 is an overflow", "args": [9007199254740992, 3], "expectError": "rational overflow"},
  {"fn": "rational", "name": "a fractional part is an error", "args": [1.5, 2], "expectError": "must be integers"},
  {"fn": "addRational", "name": "a half plus a third is five sixths", "args": [{"numerator": 1, "denominator": 2}, {"numerator": 1, "denominator": 3}], "expect": {"numerator": 5, "denominator": 6}},
  {"fn": "addRational", "name": "a tenth plus two tenths is exactly three tenths", "args": [{"numerator": 1, "denominator": 10}, {"numerator": 2, "denominator": 10}], "expect": {"numerator": 3, "denominator": 10}},
  {"fn": "addRational", "name": "opposites sum to zero over one", "args": [{"numerator": 3, "denominator": 4}, {"numerator": -3, "denominator": 4}], "expect": {"numerator": 0, "denominator": 1}},
  {"fn": "addRational", "name": "a negative plus a smaller positive stays negative", "args": [{"numerator": -5, "denominator": 6}, {"numerator": 1, "denominator": 3}], "expect": {"numerator": -1, "denominator": 2}},
  {"fn": "addRational", "name": "unreduced inputs with negative denominators", "args": [{"numerator": 4, "denominator": -8}, {"numerator": 6, "denominator": -9}], "expect": {"numerator": -7, "denominator": 6}},
  {"fn": "addRational", "name": "adding zero gives the other, reduced", "args": [{"numerator": 10, "denominator": 15}, {"numerator": 0, "denominator": 7}], "expect": {"numerator": 2, "denominator": 3}},
  {"fn": "addRational", "name": "a common denominator past 2^53 reduces back into range", "args": [{"numerator": 1, "denominator": 4503599627370496}, {"numerator": 1, "denominator": 4503599627370496}], "expect": {"numerator": 1, "denominator": 2251799813685248}},
  {"fn": "addRational", "name": "a sum past 2^53 - 1 is an overflow", "args": [{"numerator": 9007199254740991, "denominator": 1}, {"numerator": 1, "denominator": 1}], "expectError": "rational overflow"},
  {"fn": "addRational", "name": "a zero denominator is an error", "args": [{"numerator": 1, "denominator": 2}, {"numerator": 1, "denominator": 0}], "expectError": "denominator must not be zero"},
  {"fn": "subtractRational", "name": "three quarters less a quarter is a half", "args": [{"numerator": 3, "denominator": 4}, {"numerator": 1, "denominator": 4}], "expect": {"numerator": 1, "denominator": 2}},
  {"fn": "subtractRational", "name": "going below zero gives a negative numerator", "args": [{"numerator": 1, "denominator": 3}, {"numerator": 1, "denominator": 2}], "expect": {"numerator": -1, "denominator": 6}},
  {"fn": "subtractRational", "name": "equal values give zero over one", "args": [{"numerator": 2, "denominator": 6}, {"numerator": 1, "denominator": 3}], "expect": {"numerator": 0, "denominator": 1}},
  {"fn": "subtractRational", "name": "subtracting a negative adds", "args": [{"numerator": 1, "denominator": 4}, {"numerator": -1, "denominator": 4}], "expect": {"numerator": 1, "denominator": 2}},
  {"fn": "subtractRational", "name": "zero less a fraction is its negative", "args": [{"numerator": 0, "denominator": 1}, {"numerator": 5, "denominator": 8}], "expect": {"numerator": -5, "denominator": 8}},
  {"fn": "subtractRational", "name": "two nearly equal fractions differ by a millionth of a millionth", "args": [{"numerator": 999999, "denominator": 1000000}, {"numerator": 999998, "denominator": 999999}], "expect": {"numerator": 1, "denominator": 999999000000}},
  {"fn": "subtractRational", "name": "a difference whose reduced denominator is past 2^53 - 1 is an overflow", "args": [{"numerator": 9007199254740990, "denominator": 9007199254740991}, {"numerator": 9007199254740989, "denominator": 9007199254740990}], "expectError": "rational overflow"},
  {"fn": "subtractRational", "name": "a difference past -(2^53 - 1) is an overflow", "args": [{"numerator": -9007199254740991, "denominator": 1}, {"numerator": 1, "denominator": 1}], "expectError": "rational overflow"},
  {"fn": "subtractRational", "name": "a numerator past 2^53 - 1 in an operand is an overflow", "args": [{"numerator": 9007199254740992, "denominator": 1}, {"numerator": 0, "denominator": 1}], "expectError": "rational overflow"},
  {"fn": "multiplyRational", "name": "two thirds of three quarters is a half", "args": [{"numerator": 2, "denominator": 3}, {"numerator": 3, "denominator": 4}], "expect": {"numerator": 1, "denominator": 2}},
  {"fn": "multiplyRational", "name": "a rate and its inverse multiply to exactly one", "args": [{"numerator": 11734, "denominator": 10000}, {"numerator": 10000, "denominator": 11734}], "expect": {"numerator": 1, "denominator": 1}},
  {"fn": "multiplyRational", "name": "a negative times a negative is positive", "args": [{"numerator": -2, "denominator": 5}, {"numerator": -5, "denominator": 4}], "expect": {"numerator": 1, "denominator": 2}},
  {"fn": "multiplyRational", "name": "a negative times a positive is negative", "args": [{"numerator": 7, "denominator": 3}, {"numerator": -3, "denominator": 14}], "expect": {"numerator": -1, "denominator": 2}},
  {"fn": "multiplyRational", "name": "anything times zero is zero over one", "args": [{"numerator": 123, "denominator": 456}, {"numerator": 0, "denominator": -9}], "expect": {"numerator": 0, "denominator": 1}},
  {"fn": "multiplyRational", "name": "unreduced products past 2^53 still reduce exactly", "args": [{"numerator": 9007199254740991, "denominator": 2}, {"numerator": 2, "denominator": 9007199254740991}], "expect": {"numerator": 1, "denominator": 1}},
  {"fn": "multiplyRational", "name": "a denominator past 2^53 - 1 is an overflow", "args": [{"numerator": 1, "denominator": 9007199254740991}, {"numerator": 1, "denominator": 2}], "expectError": "rational overflow"},
  {"fn": "multiplyRational", "name": "a zero denominator is an error", "args": [{"numerator": 1, "denominator": 0}, {"numerator": 1, "denominator": 2}], "expectError": "denominator must not be zero"},
  {"fn": "divideRational", "name": "a half divided by a quarter is two", "args": [{"numerator": 1, "denominator": 2}, {"numerator": 1, "denominator": 4}], "expect": {"numerator": 2, "denominator": 1}},
  {"fn": "divideRational", "name": "dividing by a fraction multiplies by its inverse", "args": [{"numerator": 3, "denominator": 5}, {"numerator": 9, "denominator": 10}], "expect": {"numerator": 2, "denominator": 3}},
  {"fn": "divideRational", "name": "dividing by a negative puts the sign on the numerator", "args": [{"numerator": 1, "denominator": 3}, {"numerator": -2, "denominator": 3}], "expect": {"numerator": -1, "denominator": 2}},
  {"fn": "divideRational", "name": "a negative divided by a negative is positive", "args": [{"numerator": -4, "denominator": 7}, {"numerator": -8, "denominator": 21}], "expect": {"numerator": 3, "denominator": 2}},
  {"fn": "divideRational", "name": "zero divided by anything is zero", "args": [{"numerator": 0, "denominator": 3}, {"numerator": 5, "denominator": 2}], "expect": {"numerator": 0, "denominator": 1}},
  {"fn": "divideRational", "name": "a value divided by itself is one", "args": [{"numerator": 9007199254740991, "denominator": 9007199254740990}, {"numerator": 9007199254740991, "denominator": 9007199254740990}], "expect": {"numerator": 1, "denominator": 1}},
  {"fn": "divideRational", "name": "dividing by zero is an error, not infinity", "args": [{"numerator": 1, "denominator": 2}, {"numerator": 0, "denominator": 5}], "expectError": "division by zero"},
  {"fn": "divideRational", "name": "a quotient past 2^53 - 1 is an overflow", "args": [{"numerator": 9007199254740991, "denominator": 1}, {"numerator": 1, "denominator": 2}], "expectError": "rational overflow"},
  {"fn": "divideRational", "name": "a zero denominator in the divisor is an error", "args": [{"numerator": 1, "denominator": 2}, {"numerator": 3, "denominator": 0}], "expectError": "denominator must not be zero"},
  {"fn": "compareRational", "name": "a third is less than a half", "args": [{"numerator": 1, "denominator": 3}, {"numerator": 1, "denominator": 2}], "expect": -1},
  {"fn": "compareRational", "name": "a half is more than a third", "args": [{"numerator": 1, "denominator": 2}, {"numerator": 1, "denominator": 3}], "expect": 1},
  {"fn": "compareRational", "name": "equal values in different forms are equal", "args": [{"numerator": 2, "denominator": 4}, {"numerator": -3, "denominator": -6}], "expect": 0},
  {"fn": "compareRational", "name": "a negative is less than zero", "args": [{"numerator": -1, "denominator": 1000000}, {"numerator": 0, "denominator": 1}], "expect": -1},
  {"fn": "compareRational", "name": "the larger debt is less", "args": [{"numerator": -3, "denominator": 4}, {"numerator": -2, "denominator": 3}], "expect": -1},
  {"fn": "compareRational", "name": "fractions a float could not tell apart", "args": [{"numerator": 9007199254740990, "denominator": 9007199254740991}, {"numerator": 9007199254740989, "denominator": 9007199254740990}], "expect": 1},
  {"fn": "compareRational", "name": "the largest safe values at opposite signs", "args": [{"numerator": -9007199254740991, "denominator": 1}, {"numerator": 9007199254740991, "denominator": 1}], "expect": -1},
  {"fn": "compareRational", "name": "a zero denominator is an error", "args": [{"numerator": 1, "denominator": 0}, {"numerator": 1, "denominator": 2}], "expectError": "denominator must not be zero"},
  {"fn": "compareRational", "name": "a part past 2^53 - 1 is an overflow", "args": [{"numerator": 1, "denominator": 2}, {"numerator": 1, "denominator": 9007199254740992}], "expectError": "rational overflow"},
  {"fn": "rationalToInteger", "name": "seven halves rounds half up to 4", "args": [{"numerator": 7, "denominator": 2}, "half-up"], "expect": 4},
  {"fn": "rationalToInteger", "name": "five halves rounds half even to 2", "args": [{"numerator": 5, "denominator": 2}, "half-even"], "expect": 2},
  {"fn": "rationalToInteger", "name": "seven halves rounds half even to 4", "args": [{"numerator": 7, "denominator": 2}, "half-even"], "expect": 4},
  {"fn": "rationalToInteger", "name": "down rounds toward zero", "args": [{"numerator": 29, "denominator": 10}, "down"], "expect": 2},
  {"fn": "rationalToInteger", "name": "up rounds away from zero", "args": [{"numerator": 21, "denominator": 10}, "up"], "expect": 3},
  {"fn": "rationalToInteger", "name": "a negative half rounds half up away from zero", "args": [{"numerator": -5, "denominator": 2}, "half-up"], "expect": -3},
  {"fn": "rationalToInteger", "name": "a negative rounds down toward zero", "args": [{"numerator": -29, "denominator": 10}, "down"], "expect": -2},
  {"fn": "rationalToInteger", "name": "a negative rounds up away from zero", "args": [{"numerator": -21, "denominator": 10}, "up"], "expect": -3},
  {"fn": "rationalToInteger", "name": "a whole number is not rounded up", "args": [{"numerator": 12, "denominator": 4}, "up"], "expect": 3},
  {"fn": "rationalToInteger", "name": "zero is zero", "args": [{"numerator": 0, "denominator": 5}, "half-up"], "expect": 0},
  {"fn": "rationalToInteger", "name": "just under a half rounds down", "args": [{"numerator": 4999, "denominator": 10000}, "half-up"], "expect": 0},
  {"fn": "rationalToInteger", "name": "the largest safe numerator over two", "args": [{"numerator": 9007199254740991, "denominator": 2}, "half-even"], "expect": 4503599627370496},
  {"fn": "rationalToInteger", "name": "a zero denominator is an error", "args": [{"numerator": 1, "denominator": 0}, "half-up"], "expectError": "denominator must not be zero"},
  {"fn": "rationalToInteger", "name": "an unknown rounding mode is an error", "args": [{"numerator": 1, "denominator": 2}, "nearest"], "expectError": "unknown rounding mode"}
]