关于Rational Number的编程练习。

## Preamble

A *rational number* is defined as the quotient of two integers `a`

and `b`

, called the *numerator* and *denominator*, respectively, where `b != 0`

.

- The absolute value
`|r|`

of the rational number`r = a/b`

is equal to`|a|/|b|`

. - The sum of two rational numbers
`r1 = a1/b1`

and`r2 = a2/b2`

is`r1 + r2 = a1/b1 + a2/b2 = (a1 * b2 + a2 * b1) / (b1 * b2)`

. - The difference of two rational numbers
`r1 = a1/b1`

and`r2 = a2/b2`

is`r1 - r2 = a1/b1 - a2/b2 = (a1 * b2 - a2 * b1) / (b1 * b2)`

. - The product (multiplication) of two rational numbers
`r1 = a1/b1`

and`r2 = a2/b2`

is`r1 * r2 = (a1 * a2) / (b1 * b2)`

. - Dividing a rational number
`r1 = a1/b1`

by another`r2 = a2/b2`

is`r1 / r2 = (a1 * b2) / (a2 * b1)`

if`a2 * b1`

is not zero. - Exponentiation of a rational number
`r = a/b`

to a non-negative integer power`n`

is`r^n = (a^n)/(b^n)`

. - Exponentiation of a rational number
`r = a/b`

to a negative integer power`n`

is`r^n = (b^m)/(a^m)`

, where`m = |n|`

. - Exponentiation of a rational number
`r = a/b`

to a real (floating-point) number`x`

is the quotient`(a^x)/(b^x)`

, which is a real number. - Exponentiation of a real number
`x`

to a rational number`r = a/b`

is`x^(a/b) = root(x^a, b)`

, where`root(p, q)`

is the`q`

th root of`p`

.

## Requirements

Implement the following operations on Rational Numbers:

- addition, subtraction, multiplication, and division of two rational numbers,
- absolute value of a given rational number,
- exponentiation of a given rational number to an integer power,
- exponentiation of a given rational number to a real (floating-point) power,
- exponentiation of a real number to a rational number, and
- display as
`n/d`

, where`n`

is the numerator and`d`

is the denominator.

Your implementation should meet the following conditions:

- All rational numbers should be
*immutable*; that is, there should be no external mechanism to change the components of the number after it has been created; most of your methods will simply return a new rational number. - The denominator
**may not**be zero. - The denominator should never be negative.

(You may provide a negative number for the denominator via the constructor when you create the rational, but a negative rational should be represented internally with a negative numerator and a positive denominator.) - Zero should be represented as
`0/1`

. - Always be reduced to
*lowest terms*.

For example,`4/4`

should reduce to`1/1`

,`30/60`

should reduce to`1/2`

,`12/8`

should reduce to`3/2`

, etc.

To reduce a rational number`r = a/b`

, divide`a`

and`b`

by the greatest common divisor (gcd) of`a`

and`b`

.

For example, the`gcd(12, 8) = 4`

, therefore`r = 12/8`

can be reduced to`(12/4)/(8/4) = 3/2`

. - Use (at least) one additional [extension method][extension].
- Utilise [operator overloading methods][overload] for the
`+`

,`-`

,`*`

, and`/`

operators.

Assume that the programming language you are using does not have an implementation of rational numbers.

## The code

- You are provided with some skeletal code for both for the
`Rational`

entity and its tests. - You are required to complete the code.
- You
**should not**assume the provided code is correct — check it thoroughly. - In particular you should remember to add initial tests as the provided tests are “minimal”.
- Your goal in writing the tests for the
`Rational`

class is too test for every possible condition, including that the correct exceptions are thrown (where appropriate).

## Testing

Initially, only the first test will be enabled; this is to encourage you to solve the exercise one step at a time.

Once you get the first test to pass remove the `Skip`

property from the next test, and continue to work on getting that test to pass (and the previous test(s)) - repeat until all the tests pass.

## Resources

Percentage | Criteria |
---|---|

40% | For functionality, including testing, using the facilities of the language if possible, and that your program works according to the specification! |

40% | For coding in the idiomatic style of the programming language (i.e., `C#` ). |

20% | For adequate comments, proper formatting, indentation, choosing proper names, following naming conventions, and for correct submission. |

## Important Information

- Need to write in C#
- Need to write clean code
- Premature Optimisation, as described by one of the current programming
*Gurus*— Martin Fowler (“Yet Another Optimisation Article“), is frowned upon. - Code needs to be well structured
- Need to write comments each line to explain what it does
- Need to have proper formatting, indentation, choosing proper names, and following naming conventions.
- Need to have clear identifier names and abbreviations
- Code don’t contain inappropriate hard-coded values
- Code need to be easily maintainable
- Need to write testing, using the facilities of C# language