Skip to content

Commit 7b0ed94

Browse files
committed
Type conversions to integers or decimal types without support for _NaN_ or _Infinity_ now throw an OverflowException instead of a DivideByZeroException.
1 parent 4747013 commit 7b0ed94

9 files changed

Lines changed: 129 additions & 109 deletions

File tree

BreakingChanges.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ This file contains a summary of the most important breaking changes, sorted by v
99
### 9.0.0
1010

1111
- When using the .NET8 assembly, the data type implements the two interfaces `INumber<Fraction>` and `ISignedNumber<Fraction>` with the corresponding support but also possible side effects when using the generic [math functions](https://learn.microsoft.com/en-us/dotnet/standard/generics/math). For more information, see this [Microsoft blog article](https://devblogs.microsoft.com/dotnet/dotnet-7-generic-math/).
12+
- Type conversions to integers or decimal types without support for _NaN_ or _Infinity_ now throw an `OverflowException` instead of a `DivideByZeroException`.
1213

1314
### 8.0.0
1415

Changelog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
- PR [Implemented the INumber<Fraction> interface](https://github.com/Fractions-DotNet/Fractions/pull/96) by [lipchev](https://github.com/lipchev)
66
- PR [More DecimalQuantityFormatter performance optimizations](https://github.com/Fractions-DotNet/Fractions/pull/115) by [lipchev](https://github.com/lipchev)
77
- Replaced [FluentAssertions](https://xceed.com/products/unit-testing/fluent-assertions/) with [AwesomeAssertions](https://awesomeassertions.org/)
8+
- Type conversions to integers or decimal types without support for _NaN_ or _Infinity_ now throw an `OverflowException` instead of a `DivideByZeroException`.
89

910
### Breaking changes
1011

1112
- When using the .NET8 assembly, the data type implements the two interfaces `INumber<Fraction>` and `ISignedNumber<Fraction>` with the corresponding support but also possible side effects when using the generic [math functions](https://learn.microsoft.com/en-us/dotnet/standard/generics/math). For more information, see this [Microsoft blog article](https://devblogs.microsoft.com/dotnet/dotnet-7-generic-math/).
13+
- Type conversions to integers or decimal types without support for _NaN_ or _Infinity_ now throw an `OverflowException` instead of a `DivideByZeroException`.
1214

1315
## 8.3.2
1416
- PR [Optimizing the PowerOfTen function for exponents in the range 18-54](https://github.com/danm-de/Fractions/pull/110) by [lipchev](https://github.com/lipchev)

src/Fractions/Fraction.ConvertTo.cs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Numerics;
3+
using Fractions.Properties;
34

45
namespace Fractions;
56

@@ -13,9 +14,8 @@ public readonly partial struct Fraction {
1314
/// Converts the fraction to a 32-bit signed integer.
1415
/// </summary>
1516
/// <returns>The result of the integer division of the numerator by the denominator.</returns>
16-
/// <exception cref="DivideByZeroException">Thrown when the denominator is zero - i.e. the value is NaN or Infinity.</exception>
1717
/// <exception cref="OverflowException">
18-
/// Thrown when the result of the division is outside the range of a 32-bit signed integer.
18+
/// Thrown when the result of the division is outside the range of a 32-bit signed integer or when the denominator is zero, meaning the value is NaN or infinity.
1919
/// </exception>
2020
public int ToInt32() {
2121
return (int)ToBigInteger();
@@ -25,9 +25,8 @@ public int ToInt32() {
2525
/// Converts the fraction to a 64-bit signed integer.
2626
/// </summary>
2727
/// <returns>The result of the integer division of the numerator by the denominator.</returns>
28-
/// <exception cref="DivideByZeroException">Thrown when the denominator is zero - i.e. the value is NaN or Infinity.</exception>
2928
/// <exception cref="OverflowException">
30-
/// Thrown when the result of the division is outside the range of a 64-bit signed integer.
29+
/// Thrown when the result of the division is outside the range of a 64-bit signed integer or when the denominator is zero, meaning the value is NaN or infinity.
3130
/// </exception>
3231
public long ToInt64() {
3332
return (long)ToBigInteger();
@@ -37,9 +36,8 @@ public long ToInt64() {
3736
/// Converts the fraction to a 32-bit unsigned integer.
3837
/// </summary>
3938
/// <returns>The result of the integer division of the numerator by the denominator.</returns>
40-
/// <exception cref="DivideByZeroException">Thrown when the denominator is zero - i.e. the value is NaN or Infinity.</exception>
4139
/// <exception cref="OverflowException">
42-
/// Thrown when the result of the division is outside the range of a 32-bit unsigned integer.
40+
/// Thrown when the result of the division is outside the range of a 32-bit unsigned integer or when the denominator is zero, meaning the value is NaN or infinity.
4341
/// </exception>
4442
[CLSCompliant(false)]
4543
public uint ToUInt32() {
@@ -50,9 +48,8 @@ public uint ToUInt32() {
5048
/// Converts the fraction to a 64-bit unsigned integer.
5149
/// </summary>
5250
/// <returns>The result of the integer division of the numerator by the denominator.</returns>
53-
/// <exception cref="DivideByZeroException">Thrown when the denominator is zero - i.e. the value is NaN or Infinity.</exception>
5451
/// <exception cref="OverflowException">
55-
/// Thrown when the result of the division is outside the range of a 64-bit unsigned integer.
52+
/// Thrown when the result of the division is outside the range of a 64-bit unsigned integer or when the denominator is zero, meaning the value is NaN or infinity.
5653
/// </exception>
5754
[CLSCompliant(false)]
5855
public ulong ToUInt64() {
@@ -63,9 +60,14 @@ public ulong ToUInt64() {
6360
/// Converts the fraction to a BigInteger.
6461
/// </summary>
6562
/// <returns>The result of the integer division of the numerator by the denominator.</returns>
66-
/// <exception cref="DivideByZeroException">Thrown when the denominator is zero - i.e. the value is NaN or Infinity.</exception>
63+
/// <exception cref="OverflowException">Thrown when the denominator is zero - i.e. the value is NaN or Infinity.</exception>
6764
public BigInteger ToBigInteger() {
6865
var denominator = Denominator;
66+
67+
if (denominator.IsZero) {
68+
throw new OverflowException(Resources.ValueMustNotNanOrInfinity);
69+
}
70+
6971
return denominator.IsOne ? Numerator : Numerator / denominator;
7072
}
7173

@@ -76,17 +78,16 @@ public BigInteger ToBigInteger() {
7678
/// The fraction represented as a decimal. If the number exceeds decimal precision, the extra decimals are lost
7779
/// due to rounding.
7880
/// </returns>
79-
/// <exception cref="DivideByZeroException">Thrown when the denominator is zero - i.e. the value is NaN or Infinity.</exception>
8081
/// <exception cref="OverflowException">
81-
/// Thrown when the number represented by this fraction is outside the decimal range.
82+
/// Thrown when the number represented by this fraction is outside the decimal range or when the denominator is zero, meaning the value is NaN or infinity.
8283
/// </exception>
8384
public decimal ToDecimal() {
8485
var numerator = Numerator;
8586
var denominator = Denominator;
8687
switch (denominator.Sign) {
8788
case 0: {
88-
throw new DivideByZeroException();
89-
}
89+
throw new OverflowException(Resources.ValueMustNotNanOrInfinity);
90+
}
9091
case -1: {
9192
numerator = -numerator;
9293
denominator = -denominator;

src/Fractions/Fraction.Round.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Numerics;
3+
using Fractions.Properties;
34

45
namespace Fractions;
56

@@ -99,9 +100,12 @@ public static BigInteger RoundToBigInteger(Fraction fraction, MidpointRounding m
99100
/// <param name="denominator">The denominator of the fraction to be rounded.</param>
100101
/// <param name="mode">Specifies the strategy that mathematical rounding methods should use to round a number.</param>
101102
/// <returns>The number rounded to using the <paramref name="mode" /> rounding strategy.</returns>
103+
/// <exception cref="OverflowException">
104+
/// Thrown when the denominator is zero, meaning the value is NaN or infinity.
105+
/// </exception>
102106
private static BigInteger RoundToBigInteger(BigInteger numerator, BigInteger denominator, MidpointRounding mode) {
103107
if (denominator.IsZero) {
104-
throw new DivideByZeroException();
108+
throw new OverflowException(Resources.ValueMustNotNanOrInfinity);
105109
}
106110

107111
if (numerator.IsZero || denominator.IsOne) {

src/Fractions/Properties/Resources.Designer.cs

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Fractions/Properties/Resources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,7 @@
141141
<data name="InvalidTokenType" xml:space="preserve">
142142
<value>Invalid token type {0} (expected {1}).</value>
143143
</data>
144+
<data name="ValueMustNotNanOrInfinity" xml:space="preserve">
145+
<value>The value must not be NaN or +/-infinity.</value>
146+
</data>
144147
</root>

tests/Fractions.Tests/FractionSpecs/Round/Method_Round.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,9 @@ from midpointRounding in RoundingModes
222222

223223
[Test]
224224
[TestCaseSource(nameof(RoundNaNToBigIntegerTestCases))]
225-
public void The_result_of_rounding_NaN_to_BigInteger_should_be_a_DivideByZeroException(Fraction fraction,
225+
public void The_result_of_rounding_NaN_to_BigInteger_should_be_a_OverflowException(Fraction fraction,
226226
MidpointRounding roundingMode) {
227-
Invoking(() => Fraction.RoundToBigInteger(fraction, roundingMode)).Should().Throw<DivideByZeroException>();
227+
Invoking(() => Fraction.RoundToBigInteger(fraction, roundingMode)).Should().Throw<OverflowException>();
228228
}
229229

230230
private static IEnumerable RoundPositiveInfinityToBigIntegerTestCases =>
@@ -233,9 +233,9 @@ from midpointRounding in RoundingModes
233233

234234
[Test]
235235
[TestCaseSource(nameof(RoundPositiveInfinityToBigIntegerTestCases))]
236-
public void The_result_of_rounding_PositiveInfinity_to_BigInteger_should_throw_a_DivideByZeroException(
236+
public void The_result_of_rounding_PositiveInfinity_to_BigInteger_should_throw_a_OverflowException(
237237
Fraction fraction, MidpointRounding roundingMode) {
238-
Invoking(() => Fraction.RoundToBigInteger(fraction, roundingMode)).Should().Throw<DivideByZeroException>();
238+
Invoking(() => Fraction.RoundToBigInteger(fraction, roundingMode)).Should().Throw<OverflowException>();
239239
}
240240

241241
private static IEnumerable RoundNegativeInfinityToBigIntegerTestCases =>
@@ -244,9 +244,9 @@ from midpointRounding in RoundingModes
244244

245245
[Test]
246246
[TestCaseSource(nameof(RoundNegativeInfinityToBigIntegerTestCases))]
247-
public void The_result_of_rounding_NegativeInfinity_to_BigInteger_should_throw_a_DivideByZeroException(
247+
public void The_result_of_rounding_NegativeInfinity_to_BigInteger_should_throw_a_OverflowException(
248248
Fraction fraction, MidpointRounding roundingMode) {
249-
Invoking(() => Fraction.RoundToBigInteger(fraction, roundingMode)).Should().Throw<DivideByZeroException>();
249+
Invoking(() => Fraction.RoundToBigInteger(fraction, roundingMode)).Should().Throw<OverflowException>();
250250
}
251251

252252
[Test]

0 commit comments

Comments
 (0)