Browse Source

[SL.Core] Drop unneeded types plus added Size operators.

af/octree-no-pixelmap
Scott Williams 9 years ago
parent
commit
e040a5e6f4
  1. 209
      src/SixLabors.Primitives/ApproximateFloatComparer.cs
  2. 180
      src/SixLabors.Primitives/Ellipse.cs
  3. 352
      src/SixLabors.Primitives/LongRational.cs
  4. 189
      src/SixLabors.Primitives/Rational.cs
  5. 189
      src/SixLabors.Primitives/SignedRational.cs
  6. 67
      src/SixLabors.Primitives/Size.cs
  7. 34
      src/SixLabors.Primitives/SizeF.cs
  8. 115
      tests/SixLabors.Primitives.Tests/RationalTests.cs
  9. 122
      tests/SixLabors.Primitives.Tests/SignedRationalTests.cs
  10. 81
      tests/SixLabors.Primitives.Tests/SizeFTests.cs
  11. 180
      tests/SixLabors.Primitives.Tests/SizeTests.cs

209
src/SixLabors.Primitives/ApproximateFloatComparer.cs

@ -1,209 +0,0 @@
// <copyright file="Ellipse.cs" company="Six Labors">
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
using System;
using System.Collections.Generic;
using System.Numerics;
namespace SixLabors.Primitives
{
internal struct ApproximateFloatComparer
: IEqualityComparer<float>,
IEqualityComparer<Vector4>,
IEqualityComparer<Vector2>,
IEqualityComparer<Vector3>,
IEqualityComparer<System.Numerics.Matrix3x2>,
IEqualityComparer<Matrix4x4>,
IEqualityComparer<PointF>
{
private readonly float tolerance;
const float defaultTolerance = 1e-5f;
public ApproximateFloatComparer(float tolerance = defaultTolerance)
{
this.tolerance = tolerance;
}
public static bool Equal(float x, float y, float tolerance)
{
float d = x - y;
return d > -tolerance && d < tolerance;
}
public static bool Equal(float x, float y)
{
return Equal(x, y, defaultTolerance);
}
public bool Equals(float x, float y)
{
return Equal(x, y, this.tolerance);
}
public int GetHashCode(float obj)
{
var diff = obj % this.tolerance;// how different from tollerance are we?
return (obj - diff).GetHashCode();
}
public bool Equals(Vector4 a, Vector4 b)
{
return this.Equals(a.X, b.X) && this.Equals(a.Y, b.Y) && this.Equals(a.Z, b.Z) && this.Equals(a.W, b.W);
}
public int GetHashCode(Vector4 obj)
{
int hash = GetHashCode(obj.X);
hash = HashHelpers.Combine(hash, GetHashCode(obj.Y));
hash = HashHelpers.Combine(hash, GetHashCode(obj.Z));
hash = HashHelpers.Combine(hash, GetHashCode(obj.W));
return hash;
}
public bool Equals(Vector2 a, Vector2 b)
{
return this.Equals(a.X, b.X) && this.Equals(a.Y, b.Y);
}
public int GetHashCode(Vector2 obj)
{
int hash = GetHashCode(obj.X);
hash = HashHelpers.Combine(hash, GetHashCode(obj.Y));
return hash;
}
public bool Equals(Vector3 a, Vector3 b)
{
return this.Equals(a.X, b.X) && this.Equals(a.Y, b.Y) && this.Equals(a.Z, b.Z);
}
public int GetHashCode(Vector3 obj)
{
int hash = GetHashCode(obj.X);
hash = HashHelpers.Combine(hash, GetHashCode(obj.Y));
hash = HashHelpers.Combine(hash, GetHashCode(obj.Z));
return hash;
}
public static bool Equal(System.Numerics.Matrix3x2 a, System.Numerics.Matrix3x2 b, float tolerance)
{
return Equal(a.M11, b.M11, tolerance) &&
Equal(a.M12, b.M12, tolerance) &&
Equal(a.M21, b.M21, tolerance) &&
Equal(a.M22, b.M22, tolerance) &&
Equal(a.M31, b.M31, tolerance) &&
Equal(a.M32, b.M32, tolerance);
}
public static bool Equal(System.Numerics.Matrix3x2 a, System.Numerics.Matrix3x2 b)
{
return Equal(a, b, defaultTolerance);
}
public bool Equals(System.Numerics.Matrix3x2 a, System.Numerics.Matrix3x2 b)
{
return Equal(a, b, this.tolerance);
}
public int GetHashCode(System.Numerics.Matrix3x2 obj)
{
int hash = GetHashCode(obj.M11);
hash = HashHelpers.Combine(hash, GetHashCode(obj.M11));
hash = HashHelpers.Combine(hash, GetHashCode(obj.M12));
hash = HashHelpers.Combine(hash, GetHashCode(obj.M21));
hash = HashHelpers.Combine(hash, GetHashCode(obj.M22));
hash = HashHelpers.Combine(hash, GetHashCode(obj.M31));
hash = HashHelpers.Combine(hash, GetHashCode(obj.M32));
return hash;
}
public static bool Equal(Matrix4x4 a, Matrix4x4 b, float tolerance)
{
return
Equal(a.M11, b.M11, tolerance) &&
Equal(a.M12, b.M12, tolerance) &&
Equal(a.M13, b.M13, tolerance) &&
Equal(a.M14, b.M14, tolerance) &&
Equal(a.M21, b.M21, tolerance) &&
Equal(a.M22, b.M22, tolerance) &&
Equal(a.M23, b.M23, tolerance) &&
Equal(a.M24, b.M24, tolerance) &&
Equal(a.M31, b.M31, tolerance) &&
Equal(a.M32, b.M32, tolerance) &&
Equal(a.M33, b.M33, tolerance) &&
Equal(a.M34, b.M34, tolerance) &&
Equal(a.M41, b.M41, tolerance) &&
Equal(a.M42, b.M42, tolerance) &&
Equal(a.M43, b.M43, tolerance) &&
Equal(a.M44, b.M44, tolerance);
}
public static bool Equal(Matrix4x4 a, Matrix4x4 b)
{
return Equal(a, b, defaultTolerance);
}
public bool Equals(Matrix4x4 a, Matrix4x4 b)
{
return Equal(a, b, this.tolerance);
}
public int GetHashCode(Matrix4x4 obj)
{
int hash = GetHashCode(obj.M11);
hash = HashHelpers.Combine(hash, GetHashCode(obj.M12));
hash = HashHelpers.Combine(hash, GetHashCode(obj.M13));
hash = HashHelpers.Combine(hash, GetHashCode(obj.M14));
hash = HashHelpers.Combine(hash, GetHashCode(obj.M21));
hash = HashHelpers.Combine(hash, GetHashCode(obj.M22));
hash = HashHelpers.Combine(hash, GetHashCode(obj.M23));
hash = HashHelpers.Combine(hash, GetHashCode(obj.M24));
hash = HashHelpers.Combine(hash, GetHashCode(obj.M31));
hash = HashHelpers.Combine(hash, GetHashCode(obj.M32));
hash = HashHelpers.Combine(hash, GetHashCode(obj.M33));
hash = HashHelpers.Combine(hash, GetHashCode(obj.M34));
hash = HashHelpers.Combine(hash, GetHashCode(obj.M41));
hash = HashHelpers.Combine(hash, GetHashCode(obj.M42));
hash = HashHelpers.Combine(hash, GetHashCode(obj.M43));
hash = HashHelpers.Combine(hash, GetHashCode(obj.M44));
return hash;
}
public static bool Equal(PointF a, PointF b, float tolerance)
{
return
Equal(a.X, b.X, tolerance) &&
Equal(a.Y, b.Y, tolerance);
}
public static bool Equal(PointF a, PointF b)
{
return Equal(a, b, defaultTolerance);
}
public bool Equals(PointF a, PointF b)
{
return Equal(a, b, this.tolerance);
}
public int GetHashCode(PointF obj)
{
int hash = GetHashCode(obj.X);
hash = HashHelpers.Combine(hash, GetHashCode(obj.Y));
return hash;
}
}
}

180
src/SixLabors.Primitives/Ellipse.cs

@ -1,180 +0,0 @@
// <copyright file="Ellipse.cs" company="Six Labors">
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace SixLabors.Primitives
{
using System;
using System.ComponentModel;
using System.Numerics;
/// <summary>
/// Represents an ellipse.
/// </summary>
public struct Ellipse : IEquatable<Ellipse>
{
/// <summary>
/// Represents a <see cref="Ellipse"/> that has X and Y values set to zero.
/// </summary>
public static readonly Ellipse Empty = default(Ellipse);
/// <summary>
/// The center point.
/// </summary>
private Point center;
/// <summary>
/// Initializes a new instance of the <see cref="Ellipse"/> struct.
/// </summary>
/// <param name="center">The center point.</param>
/// <param name="radiusX">The x-radius.</param>
/// <param name="radiusY">The y-radius.</param>
public Ellipse(Point center, float radiusX, float radiusY)
{
this.center = center;
this.RadiusX = radiusX;
this.RadiusY = radiusY;
}
/// <summary>
/// Gets the x-radius of this <see cref="Ellipse"/>.
/// </summary>
public float RadiusX { get; }
/// <summary>
/// Gets the y-radius of this <see cref="Ellipse"/>.
/// </summary>
public float RadiusY { get; }
/// <summary>
/// Gets a value indicating whether this <see cref="Ellipse"/> is empty.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public bool IsEmpty => this.Equals(Empty);
/// <summary>
/// Compares two <see cref="Ellipse"/> objects for equality.
/// </summary>
/// <param name="left">
/// The <see cref="Ellipse"/> on the left side of the operand.
/// </param>
/// <param name="right">
/// The <see cref="Ellipse"/> on the right side of the operand.
/// </param>
/// <returns>
/// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
public static bool operator ==(Ellipse left, Ellipse right)
{
return left.Equals(right);
}
/// <summary>
/// Compares two <see cref="Ellipse"/> objects for inequality.
/// </summary>
/// <param name="left">
/// The <see cref="Ellipse"/> on the left side of the operand.
/// </param>
/// <param name="right">
/// The <see cref="Ellipse"/> on the right side of the operand.
/// </param>
/// <returns>
/// True if the current left is unequal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
public static bool operator !=(Ellipse left, Ellipse right)
{
return !left.Equals(right);
}
/// <summary>
/// Returns the center point of the given <see cref="Ellipse"/>
/// </summary>
/// <param name="ellipse">The ellipse</param>
/// <returns><see cref="Vector2"/></returns>
public static Vector2 Center(Ellipse ellipse)
{
return new Vector2(ellipse.center.X, ellipse.center.Y);
}
/// <summary>
/// Determines if the specfied point is contained within the rectangular region defined by
/// this <see cref="Ellipse"/>.
/// </summary>
/// <param name="x">The x-coordinate of the given point.</param>
/// <param name="y">The y-coordinate of the given point.</param>
/// <returns>The <see cref="bool"/></returns>
public bool Contains(int x, int y)
{
if (this.RadiusX <= 0 || this.RadiusY <= 0)
{
return false;
}
// TODO: SIMD?
// This is a more general form of the circle equation
// X^2/a^2 + Y^2/b^2 <= 1
Point normalized = new Point(x - this.center.X, y - this.center.Y);
int nX = normalized.X;
int nY = normalized.Y;
return ((double)(nX * nX) / (this.RadiusX * this.RadiusX))
+ ((double)(nY * nY) / (this.RadiusY * this.RadiusY))
<= 1.0;
}
/// <inheritdoc/>
public override int GetHashCode()
{
return this.GetHashCode(this);
}
/// <inheritdoc/>
public override string ToString()
{
if (this.IsEmpty)
{
return "Ellipse [ Empty ]";
}
return
$"Ellipse [ RadiusX={this.RadiusX}, RadiusY={this.RadiusX}, Centre={this.center.X},{this.center.Y} ]";
}
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj is Ellipse)
{
return this.Equals((Ellipse)obj);
}
return false;
}
/// <inheritdoc/>
public bool Equals(Ellipse other)
{
return this.center.Equals(other.center)
&& this.RadiusX.Equals(other.RadiusX)
&& this.RadiusY.Equals(other.RadiusY);
}
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
/// <param name="ellipse">
/// The instance of <see cref="Point"/> to return the hash code for.
/// </param>
/// <returns>
/// A 32-bit signed integer that is the hash code for this instance.
/// </returns>
private int GetHashCode(Ellipse ellipse)
{
int hashCode = ellipse.center.GetHashCode();
hashCode = HashHelpers.Combine(hashCode, ellipse.RadiusX.GetHashCode());
hashCode = HashHelpers.Combine(hashCode, ellipse.RadiusY.GetHashCode());
return hashCode;
}
}
}

352
src/SixLabors.Primitives/LongRational.cs

@ -1,352 +0,0 @@
// <copyright file="LongRational.cs" company="Six Labors">
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace SixLabors.Primitives
{
using System;
using System.Globalization;
using System.Text;
/// <summary>
/// Represents a number that can be expressed as a fraction
/// </summary>
/// <remarks>
/// This is a very simplified implementation of a rational number designed for use with metadata only.
/// </remarks>
internal struct LongRational : IEquatable<LongRational>
{
/// <summary>
/// Initializes a new instance of the <see cref="LongRational"/> struct.
/// </summary>
/// <param name="numerator">
/// The number above the line in a vulgar fraction showing how many of the parts
/// indicated by the denominator are taken.
/// </param>
/// <param name="denominator">
/// The number below the line in a vulgar fraction; a divisor.
/// </param>
public LongRational(long numerator, long denominator)
: this(numerator, denominator, false)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="LongRational"/> struct.
/// </summary>
/// <param name="numerator">
/// The number above the line in a vulgar fraction showing how many of the parts
/// indicated by the denominator are taken.
/// </param>
/// <param name="denominator">
/// The number below the line in a vulgar fraction; a divisor.
/// </param>
/// <param name="simplify">
/// Whether to attempt to simplify the fractional parts.
/// </param>
public LongRational(long numerator, long denominator, bool simplify)
: this()
{
this.Numerator = numerator;
this.Denominator = denominator;
if (simplify)
{
this.Simplify();
}
}
/// <summary>
/// Initializes a new instance of the <see cref="LongRational"/> struct.
/// </summary>
/// <param name="value">The <see cref="double"/> to create the instance from.</param>
/// <param name="bestPrecision">Whether to use the best possible precision when parsing the value.</param>
public LongRational(double value, bool bestPrecision)
: this()
{
if (double.IsNaN(value))
{
this.Numerator = this.Denominator = 0;
return;
}
if (double.IsPositiveInfinity(value))
{
this.Numerator = 1;
this.Denominator = 0;
return;
}
if (double.IsNegativeInfinity(value))
{
this.Numerator = -1;
this.Denominator = 0;
return;
}
this.Numerator = 1;
this.Denominator = 1;
double val = Math.Abs(value);
double df = this.Numerator / (double)this.Denominator;
double epsilon = bestPrecision ? double.Epsilon : .000001;
while (Math.Abs(df - val) > epsilon)
{
if (df < val)
{
this.Numerator++;
}
else
{
this.Denominator++;
this.Numerator = (int)(val * this.Denominator);
}
df = this.Numerator / (double)this.Denominator;
}
if (value < 0.0)
{
this.Numerator *= -1;
}
this.Simplify();
}
/// <summary>
/// Gets the numerator of a number.
/// </summary>
public long Numerator
{
get;
private set;
}
/// <summary>
/// Gets the denominator of a number.
/// </summary>
public long Denominator
{
get;
private set;
}
/// <summary>
/// Gets a value indicating whether this instance is indeterminate.
/// </summary>
public bool IsIndeterminate
{
get
{
if (this.Denominator != 0)
{
return false;
}
return this.Numerator == 0;
}
}
/// <summary>
/// Gets a value indicating whether this instance is an integer (n, 1)
/// </summary>
public bool IsInteger => this.Denominator == 1;
/// <summary>
/// Gets a value indicating whether this instance is equal to negative infinity (-1, 0)
/// </summary>
public bool IsNegativeInfinity
{
get
{
if (this.Denominator != 0)
{
return false;
}
return this.Numerator == -1;
}
}
/// <summary>
/// Gets a value indicating whether this instance is equal to positive infinity (1, 0)
/// </summary>
public bool IsPositiveInfinity
{
get
{
if (this.Denominator != 0)
{
return false;
}
return this.Numerator == 1;
}
}
/// <summary>
/// Gets a value indicating whether this instance is equal to 0 (0, 1)
/// </summary>
public bool IsZero
{
get
{
if (this.Denominator != 1)
{
return false;
}
return this.Numerator == 0;
}
}
/// <inheritdoc/>
public bool Equals(LongRational other)
{
if (this.Denominator == other.Denominator)
{
return this.Numerator == other.Numerator;
}
if (this.Numerator == 0 && this.Denominator == 0)
{
return other.Numerator == 0 && other.Denominator == 0;
}
if (other.Numerator == 0 && other.Denominator == 0)
{
return this.Numerator == 0 && this.Denominator == 0;
}
return (this.Numerator * other.Denominator) == (this.Denominator * other.Numerator);
}
/// <inheritdoc/>
public override int GetHashCode()
{
return this.GetHashCode(this);
}
/// <inheritdoc/>
public override string ToString()
{
return this.ToString(CultureInfo.InvariantCulture);
}
/// <summary>
/// Converts the numeric value of this instance to its equivalent string representation using
/// the specified culture-specific format information.
/// </summary>
/// <param name="provider">
/// An object that supplies culture-specific formatting information.
/// </param>
/// <returns>The <see cref="string"/></returns>
public string ToString(IFormatProvider provider)
{
if (this.IsIndeterminate)
{
return "[ Indeterminate ]";
}
if (this.IsPositiveInfinity)
{
return "[ PositiveInfinity ]";
}
if (this.IsNegativeInfinity)
{
return "[ NegativeInfinity ]";
}
if (this.IsZero)
{
return "0";
}
if (this.IsInteger)
{
return this.Numerator.ToString(provider);
}
StringBuilder sb = new StringBuilder();
sb.Append(this.Numerator.ToString(provider));
sb.Append("/");
sb.Append(this.Denominator.ToString(provider));
return sb.ToString();
}
/// <summary>
/// Finds the greatest common divisor of two <see cref="long"/> values.
/// </summary>
/// <param name="left">The first value</param>
/// <param name="right">The second value</param>
/// <returns>The <see cref="long"/></returns>
private static long GreatestCommonDivisor(long left, long right)
{
return right == 0 ? left : GreatestCommonDivisor(right, left % right);
}
/// <summary>
/// Simplifies the <see cref="LongRational"/>
/// </summary>
private void Simplify()
{
if (this.IsIndeterminate)
{
return;
}
if (this.IsNegativeInfinity)
{
return;
}
if (this.IsPositiveInfinity)
{
return;
}
if (this.IsInteger)
{
return;
}
if (this.IsZero)
{
return;
}
if (this.Numerator == 0)
{
this.Denominator = 0;
return;
}
if (this.Numerator == this.Denominator)
{
this.Numerator = 1;
this.Denominator = 1;
}
long gcd = GreatestCommonDivisor(Math.Abs(this.Numerator), Math.Abs(this.Denominator));
if (gcd > 1)
{
this.Numerator = this.Numerator / gcd;
this.Denominator = this.Denominator / gcd;
}
}
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
/// <param name="rational">
/// The instance of <see cref="LongRational"/> to return the hash code for.
/// </param>
/// <returns>
/// A 32-bit signed integer that is the hash code for this instance.
/// </returns>
private int GetHashCode(LongRational rational) => HashHelpers.Combine(rational.Numerator.GetHashCode(), rational.Denominator.GetHashCode());
}
}

189
src/SixLabors.Primitives/Rational.cs

@ -1,189 +0,0 @@
// <copyright file="Rational.cs" company="Six Labors">
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace SixLabors.Primitives
{
using System;
using System.Globalization;
/// <summary>
/// Represents a number that can be expressed as a fraction.
/// </summary>
/// <remarks>
/// This is a very simplified implementation of a rational number designed for use with metadata only.
/// </remarks>
public struct Rational : IEquatable<Rational>
{
/// <summary>
/// Initializes a new instance of the <see cref="Rational"/> struct.
/// </summary>
/// <param name="value">The <see cref="uint"/> to create the rational from.</param>
public Rational(uint value)
: this(value, 1)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Rational"/> struct.
/// </summary>
/// <param name="numerator">The number above the line in a vulgar fraction showing how many of the parts indicated by the denominator are taken.</param>
/// <param name="denominator">The number below the line in a vulgar fraction; a divisor.</param>
public Rational(uint numerator, uint denominator)
: this(numerator, denominator, true)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Rational"/> struct.
/// </summary>
/// <param name="numerator">The number above the line in a vulgar fraction showing how many of the parts indicated by the denominator are taken.</param>
/// <param name="denominator">The number below the line in a vulgar fraction; a divisor.</param>
/// <param name="simplify">Specified if the rational should be simplified.</param>
public Rational(uint numerator, uint denominator, bool simplify)
{
LongRational rational = new LongRational(numerator, denominator, simplify);
this.Numerator = (uint)rational.Numerator;
this.Denominator = (uint)rational.Denominator;
}
/// <summary>
/// Initializes a new instance of the <see cref="Rational"/> struct.
/// </summary>
/// <param name="value">The <see cref="double"/> to create the instance from.</param>
public Rational(double value)
: this(value, false)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Rational"/> struct.
/// </summary>
/// <param name="value">The <see cref="double"/> to create the instance from.</param>
/// <param name="bestPrecision">Whether to use the best possible precision when parsing the value.</param>
public Rational(double value, bool bestPrecision)
{
LongRational rational = new LongRational(Math.Abs(value), bestPrecision);
this.Numerator = (uint)rational.Numerator;
this.Denominator = (uint)rational.Denominator;
}
/// <summary>
/// Gets the numerator of a number.
/// </summary>
public uint Numerator { get; }
/// <summary>
/// Gets the denominator of a number.
/// </summary>
public uint Denominator { get; }
/// <summary>
/// Determines whether the specified <see cref="Rational"/> instances are considered equal.
/// </summary>
/// <param name="left">The first <see cref="Rational"/> to compare.</param>
/// <param name="right"> The second <see cref="Rational"/> to compare.</param>
/// <returns>The <see cref="bool"/></returns>
public static bool operator ==(Rational left, Rational right)
{
return Rational.Equals(left, right);
}
/// <summary>
/// Determines whether the specified <see cref="Rational"/> instances are not considered equal.
/// </summary>
/// <param name="left">The first <see cref="Rational"/> to compare.</param>
/// <param name="right"> The second <see cref="Rational"/> to compare.</param>
/// <returns>The <see cref="bool"/></returns>
public static bool operator !=(Rational left, Rational right)
{
return !Rational.Equals(left, right);
}
/// <summary>
/// Converts the specified <see cref="double"/> to an instance of this type.
/// </summary>
/// <param name="value">The <see cref="double"/> to convert to an instance of this type.</param>
/// <returns>
/// The <see cref="Rational"/>.
/// </returns>
public static Rational FromDouble(double value)
{
return new Rational(value, false);
}
/// <summary>
/// Converts the specified <see cref="double"/> to an instance of this type.
/// </summary>
/// <param name="value">The <see cref="double"/> to convert to an instance of this type.</param>
/// <param name="bestPrecision">Whether to use the best possible precision when parsing the value.</param>
/// <returns>
/// The <see cref="Rational"/>.
/// </returns>
public static Rational FromDouble(double value, bool bestPrecision)
{
return new Rational(value, bestPrecision);
}
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj is Rational)
{
return this.Equals((Rational)obj);
}
return false;
}
/// <inheritdoc/>
public bool Equals(Rational other)
{
LongRational left = new LongRational(this.Numerator, this.Denominator);
LongRational right = new LongRational(other.Numerator, other.Denominator);
return left.Equals(right);
}
/// <inheritdoc/>
public override int GetHashCode()
{
LongRational self = new LongRational(this.Numerator, this.Denominator);
return self.GetHashCode();
}
/// <summary>
/// Converts a rational number to the nearest <see cref="double"/>.
/// </summary>
/// <returns>
/// The <see cref="double"/>.
/// </returns>
public double ToDouble()
{
return this.Numerator / (double)this.Denominator;
}
/// <inheritdoc/>
public override string ToString()
{
return this.ToString(CultureInfo.InvariantCulture);
}
/// <summary>
/// Converts the numeric value of this instance to its equivalent string representation using
/// the specified culture-specific format information.
/// </summary>
/// <param name="provider">
/// An object that supplies culture-specific formatting information.
/// </param>
/// <returns>The <see cref="string"/></returns>
public string ToString(IFormatProvider provider)
{
LongRational rational = new LongRational(this.Numerator, this.Denominator);
return rational.ToString(provider);
}
}
}

189
src/SixLabors.Primitives/SignedRational.cs

@ -1,189 +0,0 @@
// <copyright file="SignedRational.cs" company="Six Labors">
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace SixLabors.Primitives
{
using System;
using System.Globalization;
/// <summary>
/// Represents a number that can be expressed as a fraction.
/// </summary>
/// <remarks>
/// This is a very simplified implementation of a rational number designed for use with metadata only.
/// </remarks>
public struct SignedRational : IEquatable<SignedRational>
{
/// <summary>
/// Initializes a new instance of the <see cref="SignedRational"/> struct.
/// </summary>
/// <param name="value">The <see cref="int"/> to create the rational from.</param>
public SignedRational(int value)
: this(value, 1)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="SignedRational"/> struct.
/// </summary>
/// <param name="numerator">The number above the line in a vulgar fraction showing how many of the parts indicated by the denominator are taken.</param>
/// <param name="denominator">The number below the line in a vulgar fraction; a divisor.</param>
public SignedRational(int numerator, int denominator)
: this(numerator, denominator, true)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="SignedRational"/> struct.
/// </summary>
/// <param name="numerator">The number above the line in a vulgar fraction showing how many of the parts indicated by the denominator are taken.</param>
/// <param name="denominator">The number below the line in a vulgar fraction; a divisor.</param>
/// <param name="simplify">Specified if the rational should be simplified.</param>
public SignedRational(int numerator, int denominator, bool simplify)
{
LongRational rational = new LongRational(numerator, denominator, simplify);
this.Numerator = (int)rational.Numerator;
this.Denominator = (int)rational.Denominator;
}
/// <summary>
/// Initializes a new instance of the <see cref="SignedRational"/> struct.
/// </summary>
/// <param name="value">The <see cref="double"/> to create the instance from.</param>
public SignedRational(double value)
: this(value, false)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="SignedRational"/> struct.
/// </summary>
/// <param name="value">The <see cref="double"/> to create the instance from.</param>
/// <param name="bestPrecision">Whether to use the best possible precision when parsing the value.</param>
public SignedRational(double value, bool bestPrecision)
{
LongRational rational = new LongRational(value, bestPrecision);
this.Numerator = (int)rational.Numerator;
this.Denominator = (int)rational.Denominator;
}
/// <summary>
/// Gets the numerator of a number.
/// </summary>
public int Numerator { get; }
/// <summary>
/// Gets the denominator of a number.
/// </summary>
public int Denominator { get; }
/// <summary>
/// Determines whether the specified <see cref="SignedRational"/> instances are considered equal.
/// </summary>
/// <param name="left">The first <see cref="SignedRational"/> to compare.</param>
/// <param name="right"> The second <see cref="SignedRational"/> to compare.</param>
/// <returns>The <see cref="bool"/></returns>
public static bool operator ==(SignedRational left, SignedRational right)
{
return SignedRational.Equals(left, right);
}
/// <summary>
/// Determines whether the specified <see cref="SignedRational"/> instances are not considered equal.
/// </summary>
/// <param name="left">The first <see cref="SignedRational"/> to compare.</param>
/// <param name="right"> The second <see cref="SignedRational"/> to compare.</param>
/// <returns>The <see cref="bool"/></returns>
public static bool operator !=(SignedRational left, SignedRational right)
{
return !SignedRational.Equals(left, right);
}
/// <summary>
/// Converts the specified <see cref="double"/> to an instance of this type.
/// </summary>
/// <param name="value">The <see cref="double"/> to convert to an instance of this type.</param>
/// <returns>
/// The <see cref="SignedRational"/>.
/// </returns>
public static SignedRational FromDouble(double value)
{
return new SignedRational(value, false);
}
/// <summary>
/// Converts the specified <see cref="double"/> to an instance of this type.
/// </summary>
/// <param name="value">The <see cref="double"/> to convert to an instance of this type.</param>
/// <param name="bestPrecision">Whether to use the best possible precision when parsing the value.</param>
/// <returns>
/// The <see cref="SignedRational"/>.
/// </returns>
public static SignedRational FromDouble(double value, bool bestPrecision)
{
return new SignedRational(value, bestPrecision);
}
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj is SignedRational)
{
return this.Equals((SignedRational)obj);
}
return false;
}
/// <inheritdoc/>
public bool Equals(SignedRational other)
{
LongRational left = new LongRational(this.Numerator, this.Denominator);
LongRational right = new LongRational(other.Numerator, other.Denominator);
return left.Equals(right);
}
/// <inheritdoc/>
public override int GetHashCode()
{
LongRational self = new LongRational(this.Numerator, this.Denominator);
return self.GetHashCode();
}
/// <summary>
/// Converts a rational number to the nearest <see cref="double"/>.
/// </summary>
/// <returns>
/// The <see cref="double"/>.
/// </returns>
public double ToDouble()
{
return this.Numerator / (double)this.Denominator;
}
/// <inheritdoc/>
public override string ToString()
{
return this.ToString(CultureInfo.InvariantCulture);
}
/// <summary>
/// Converts the numeric value of this instance to its equivalent string representation using
/// the specified culture-specific format information.
/// </summary>
/// <param name="provider">
/// An object that supplies culture-specific formatting information.
/// </param>
/// <returns>The <see cref="string"/></returns>
public string ToString(IFormatProvider provider)
{
LongRational rational = new LongRational(this.Numerator, this.Denominator);
return rational.ToString(provider);
}
}
}

67
src/SixLabors.Primitives/Size.cs

@ -124,6 +124,55 @@ namespace SixLabors.Primitives
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Size operator -(Size left, Size right) => Subtract(left, right);
/// <summary>
/// Multiplies a <see cref="Size"/> by an <see cref="int"/> producing <see cref="Size"/>.
/// </summary>
/// <param name="left">Multiplier of type <see cref="int"/>.</param>
/// <param name="right">Multiplicand of type <see cref="Size"/>.</param>
/// <returns>Product of type <see cref="Size"/>.</returns>
public static Size operator *(int left, Size right) => Multiply(right, left);
/// <summary>
/// Multiplies <see cref="Size"/> by an <see cref="int"/> producing <see cref="Size"/>.
/// </summary>
/// <param name="left">Multiplicand of type <see cref="Size"/>.</param>
/// <param name="right">Multiplier of type <see cref="int"/>.</param>
/// <returns>Product of type <see cref="Size"/>.</returns>
public static Size operator *(Size left, int right) => Multiply(left, right);
/// <summary>
/// Divides <see cref="Size"/> by an <see cref="int"/> producing <see cref="Size"/>.
/// </summary>
/// <param name="left">Dividend of type <see cref="Size"/>.</param>
/// <param name="right">Divisor of type <see cref="int"/>.</param>
/// <returns>Result of type <see cref="Size"/>.</returns>
public static Size operator /(Size left, int right) => new Size(unchecked(left.Width / right), unchecked(left.Height / right));
/// <summary>
/// Multiplies <see cref="Size"/> by a <see cref="float"/> producing <see cref="SizeF"/>.
/// </summary>
/// <param name="left">Multiplier of type <see cref="float"/>.</param>
/// <param name="right">Multiplicand of type <see cref="Size"/>.</param>
/// <returns>Product of type <see cref="SizeF"/>.</returns>
public static SizeF operator *(float left, Size right) => Multiply(right, left);
/// <summary>
/// Multiplies <see cref="Size"/> by a <see cref="float"/> producing <see cref="SizeF"/>.
/// </summary>
/// <param name="left">Multiplicand of type <see cref="Size"/>.</param>
/// <param name="right">Multiplier of type <see cref="float"/>.</param>
/// <returns>Product of type <see cref="SizeF"/>.</returns>
public static SizeF operator *(Size left, float right) => Multiply(left, right);
/// <summary>
/// Divides <see cref="Size"/> by a <see cref="float"/> producing <see cref="SizeF"/>.
/// </summary>
/// <param name="left">Dividend of type <see cref="Size"/>.</param>
/// <param name="right">Divisor of type <see cref="int"/>.</param>
/// <returns>Result of type <see cref="SizeF"/>.</returns>
public static SizeF operator /(Size left, float right)
=> new SizeF(left.Width / right, left.Height / right);
/// <summary>
/// Compares two <see cref="Size"/> objects for equality.
/// </summary>
@ -172,6 +221,24 @@ namespace SixLabors.Primitives
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Size Subtract(Size left, Size right) => new Size(unchecked(left.Width - right.Width), unchecked(left.Height - right.Height));
/// <summary>
/// Multiplies <see cref="Size"/> by an <see cref="int"/> producing <see cref="Size"/>.
/// </summary>
/// <param name="size">Multiplicand of type <see cref="Size"/>.</param>
/// <param name="multiplier">Multiplier of type <see cref='int'>.</param>
/// <returns>Product of type <see cref="Size"/>.</returns>
private static Size Multiply(Size size, int multiplier) =>
new Size(unchecked(size.Width * multiplier), unchecked(size.Height * multiplier));
/// <summary>
/// Multiplies <see cref="Size"/> by a <see cref="float"/> producing <see cref="SizeF"/>.
/// </summary>
/// <param name="size">Multiplicand of type <see cref="Size"/>.</param>
/// <param name="multiplier">Multiplier of type <see cref="float"/>.</param>
/// <returns>Product of type SizeF.</returns>
private static SizeF Multiply(Size size, float multiplier) =>
new SizeF(size.Width * multiplier, size.Height * multiplier);
/// <summary>
/// Converts a <see cref="SizeF"/> to a <see cref="Size"/> by performing a ceiling operation on all the dimensions.
/// </summary>

34
src/SixLabors.Primitives/SizeF.cs

@ -116,6 +116,31 @@ namespace SixLabors.Primitives
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static SizeF operator -(SizeF left, SizeF right) => Subtract(left, right);
/// <summary>
/// Multiplies <see cref="SizeF"/> by a <see cref="float"/> producing <see cref="SizeF"/>.
/// </summary>
/// <param name="left">Multiplier of type <see cref="float"/>.</param>
/// <param name="right">Multiplicand of type <see cref="SizeF"/>.</param>
/// <returns>Product of type <see cref="SizeF"/>.</returns>
public static SizeF operator *(float left, SizeF right) => Multiply(right, left);
/// <summary>
/// Multiplies <see cref="SizeF"/> by a <see cref="float"/> producing <see cref="SizeF"/>.
/// </summary>
/// <param name="left">Multiplicand of type <see cref="SizeF"/>.</param>
/// <param name="right">Multiplier of type <see cref="float"/>.</param>
/// <returns>Product of type <see cref="SizeF"/>.</returns>
public static SizeF operator *(SizeF left, float right) => Multiply(left, right);
/// <summary>
/// Divides <see cref="SizeF"/> by a <see cref="float"/> producing <see cref="SizeF"/>.
/// </summary>
/// <param name="left">Dividend of type <see cref="SizeF"/>.</param>
/// <param name="right">Divisor of type <see cref="int"/>.</param>
/// <returns>Result of type <see cref="SizeF"/>.</returns>
public static SizeF operator /(SizeF left, float right)
=> new SizeF(left.Width / right, left.Height / right);
/// <summary>
/// Compares two <see cref="SizeF"/> objects for equality.
/// </summary>
@ -156,6 +181,15 @@ namespace SixLabors.Primitives
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static SizeF Subtract(SizeF left, SizeF right) => new SizeF(left.Width - right.Width, left.Height - right.Height);
/// <summary>
/// Multiplies <see cref="SizeF"/> by a <see cref="float"/> producing <see cref="SizeF"/>.
/// </summary>
/// <param name="size">Multiplicand of type <see cref="SizeF"/>.</param>
/// <param name="multiplier">Multiplier of type <see cref="float"/>.</param>
/// <returns>Product of type SizeF.</returns>
private static SizeF Multiply(SizeF size, float multiplier) =>
new SizeF(size.Width * multiplier, size.Height * multiplier);
/// <inheritdoc/>
public override int GetHashCode()
{

115
tests/SixLabors.Primitives.Tests/RationalTests.cs

@ -1,115 +0,0 @@
// <copyright file="RationalTests.cs" company="Six Labors">
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace SixLabors.Primitives.Tests
{
using Xunit;
/// <summary>
/// Tests the <see cref="Rational"/> struct.
/// </summary>
public class RationalTests
{
/// <summary>
/// Tests the equality operators for equality.
/// </summary>
[Fact]
public void AreEqual()
{
Rational r1 = new Rational(3, 2);
Rational r2 = new Rational(3, 2);
Assert.Equal(r1, r2);
Assert.True(r1 == r2);
Rational r3 = new Rational(7.55);
Rational r4 = new Rational(755, 100);
Rational r5 = new Rational(151, 20);
Assert.Equal(r3, r4);
Assert.Equal(r4, r5);
}
/// <summary>
/// Tests the equality operators for inequality.
/// </summary>
[Fact]
public void AreNotEqual()
{
Rational first = new Rational(0, 100);
Rational second = new Rational(100, 100);
Assert.NotEqual(first, second);
Assert.True(first != second);
}
/// <summary>
/// Tests whether the Rational constructor correctly assign properties.
/// </summary>
[Fact]
public void ConstructorAssignsProperties()
{
Rational rational = new Rational(7, 55);
Assert.Equal(7U, rational.Numerator);
Assert.Equal(55U, rational.Denominator);
rational = new Rational(755, 100);
Assert.Equal(151U, rational.Numerator);
Assert.Equal(20U, rational.Denominator);
rational = new Rational(755, 100, false);
Assert.Equal(755U, rational.Numerator);
Assert.Equal(100U, rational.Denominator);
rational = new Rational(-7.55);
Assert.Equal(151U, rational.Numerator);
Assert.Equal(20U, rational.Denominator);
rational = new Rational(7);
Assert.Equal(7U, rational.Numerator);
Assert.Equal(1U, rational.Denominator);
}
[Fact]
public void Fraction()
{
Rational first = new Rational(1.0 / 1600);
Rational second = new Rational(1.0 / 1600, true);
Assert.False(first.Equals(second));
}
[Fact]
public void ToDouble()
{
Rational rational = new Rational(0, 0);
Assert.Equal(double.NaN, rational.ToDouble());
rational = new Rational(2, 0);
Assert.Equal(double.PositiveInfinity, rational.ToDouble());
}
[Fact]
public void ToStringRepresention()
{
Rational rational = new Rational(0, 0);
Assert.Equal("[ Indeterminate ]", rational.ToString());
rational = new Rational(double.PositiveInfinity);
Assert.Equal("[ PositiveInfinity ]", rational.ToString());
rational = new Rational(double.NegativeInfinity);
Assert.Equal("[ PositiveInfinity ]", rational.ToString());
rational = new Rational(0, 1);
Assert.Equal("0", rational.ToString());
rational = new Rational(2, 1);
Assert.Equal("2", rational.ToString());
rational = new Rational(1, 2);
Assert.Equal("1/2", rational.ToString());
}
}
}

122
tests/SixLabors.Primitives.Tests/SignedRationalTests.cs

@ -1,122 +0,0 @@
// <copyright file="RationalTests.cs" company="Six Labors">
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace SixLabors.Primitives.Tests
{
using Xunit;
/// <summary>
/// Tests the <see cref="SignedRational"/> struct.
/// </summary>
public class SignedRationalTests
{
/// <summary>
/// Tests the equality operators for equality.
/// </summary>
[Fact]
public void AreEqual()
{
SignedRational r1 = new SignedRational(3, 2);
SignedRational r2 = new SignedRational(3, 2);
Assert.Equal(r1, r2);
Assert.True(r1 == r2);
SignedRational r3 = new SignedRational(7.55);
SignedRational r4 = new SignedRational(755, 100);
SignedRational r5 = new SignedRational(151, 20);
Assert.Equal(r3, r4);
Assert.Equal(r4, r5);
}
/// <summary>
/// Tests the equality operators for inequality.
/// </summary>
[Fact]
public void AreNotEqual()
{
SignedRational first = new SignedRational(0, 100);
SignedRational second = new SignedRational(100, 100);
Assert.NotEqual(first, second);
Assert.True(first != second);
}
/// <summary>
/// Tests whether the Rational constructor correctly assign properties.
/// </summary>
[Fact]
public void ConstructorAssignsProperties()
{
SignedRational rational = new SignedRational(7, -55);
Assert.Equal(7, rational.Numerator);
Assert.Equal(-55, rational.Denominator);
rational = new SignedRational(-755, 100);
Assert.Equal(-151, rational.Numerator);
Assert.Equal(20, rational.Denominator);
rational = new SignedRational(-755, -100, false);
Assert.Equal(-755, rational.Numerator);
Assert.Equal(-100, rational.Denominator);
rational = new SignedRational(-151, -20);
Assert.Equal(-151, rational.Numerator);
Assert.Equal(-20, rational.Denominator);
rational = new SignedRational(-7.55);
Assert.Equal(-151, rational.Numerator);
Assert.Equal(20, rational.Denominator);
rational = new SignedRational(7);
Assert.Equal(7, rational.Numerator);
Assert.Equal(1, rational.Denominator);
}
[Fact]
public void Fraction()
{
SignedRational first = new SignedRational(1.0 / 1600);
SignedRational second = new SignedRational(1.0 / 1600, true);
Assert.False(first.Equals(second));
}
[Fact]
public void ToDouble()
{
SignedRational rational = new SignedRational(0, 0);
Assert.Equal(double.NaN, rational.ToDouble());
rational = new SignedRational(2, 0);
Assert.Equal(double.PositiveInfinity, rational.ToDouble());
rational = new SignedRational(-2, 0);
Assert.Equal(double.NegativeInfinity, rational.ToDouble());
}
[Fact]
public void ToStringRepresention()
{
SignedRational rational = new SignedRational(0, 0);
Assert.Equal("[ Indeterminate ]", rational.ToString());
rational = new SignedRational(double.PositiveInfinity);
Assert.Equal("[ PositiveInfinity ]", rational.ToString());
rational = new SignedRational(double.NegativeInfinity);
Assert.Equal("[ NegativeInfinity ]", rational.ToString());
rational = new SignedRational(0, 1);
Assert.Equal("0", rational.ToString());
rational = new SignedRational(2, 1);
Assert.Equal("2", rational.ToString());
rational = new SignedRational(1, 2);
Assert.Equal("1/2", rational.ToString());
}
}
}

81
tests/SixLabors.Primitives.Tests/SizeFTests.cs

@ -159,5 +159,86 @@ namespace SixLabors.Primitives.Tests
var sz = new SizeF(0, 0);
Assert.Equal("SizeF [ Empty ]", sz.ToString());
}
[Theory]
[InlineData(1000.234f, 0.0f)]
[InlineData(1000.234f, 1.0f)]
[InlineData(1000.234f, 2400.933f)]
[InlineData(1000.234f, float.MaxValue)]
[InlineData(1000.234f, -1.0f)]
[InlineData(1000.234f, -2400.933f)]
[InlineData(1000.234f, float.MinValue)]
[InlineData(float.MaxValue, 0.0f)]
[InlineData(float.MaxValue, 1.0f)]
[InlineData(float.MaxValue, 2400.933f)]
[InlineData(float.MaxValue, float.MaxValue)]
[InlineData(float.MaxValue, -1.0f)]
[InlineData(float.MaxValue, -2400.933f)]
[InlineData(float.MaxValue, float.MinValue)]
[InlineData(float.MinValue, 0.0f)]
[InlineData(float.MinValue, 1.0f)]
[InlineData(float.MinValue, 2400.933f)]
[InlineData(float.MinValue, float.MaxValue)]
[InlineData(float.MinValue, -1.0f)]
[InlineData(float.MinValue, -2400.933f)]
[InlineData(float.MinValue, float.MinValue)]
public void MultiplicationTest(float dimension, float multiplier)
{
SizeF sz1 = new SizeF(dimension, dimension);
SizeF mulExpected;
mulExpected = new SizeF(dimension * multiplier, dimension * multiplier);
Assert.Equal(mulExpected, sz1 * multiplier);
Assert.Equal(mulExpected, multiplier * sz1);
}
[Theory]
[InlineData(1111.1111f, 2222.2222f, 3333.3333f)]
public void MultiplicationTestWidthHeightMultiplier(float width, float height, float multiplier)
{
SizeF sz1 = new SizeF(width, height);
SizeF mulExpected;
mulExpected = new SizeF(width * multiplier, height * multiplier);
Assert.Equal(mulExpected, sz1 * multiplier);
Assert.Equal(mulExpected, multiplier * sz1);
}
[Theory]
[InlineData(0.0f, 1.0f)]
[InlineData(1.0f, 1.0f)]
[InlineData(-1.0f, 1.0f)]
[InlineData(1.0f, -1.0f)]
[InlineData(-1.0f, -1.0f)]
[InlineData(float.MaxValue, float.MaxValue)]
[InlineData(float.MaxValue, float.MinValue)]
[InlineData(float.MinValue, float.MaxValue)]
[InlineData(float.MinValue, float.MinValue)]
[InlineData(float.MaxValue, 1.0f)]
[InlineData(float.MinValue, 1.0f)]
[InlineData(float.MaxValue, -1.0f)]
[InlineData(float.MinValue, -1.0f)]
[InlineData(float.MinValue, 0.0f)]
[InlineData(1.0f, float.MinValue)]
[InlineData(1.0f, float.MinValue)]
[InlineData(-1.0f, float.MinValue)]
[InlineData(-1.0f, float.MinValue)]
public void DivideTestSizeFloat(float dimension, float divisor)
{
SizeF size = new SizeF(dimension, dimension);
SizeF expected = new SizeF(dimension / divisor, dimension / divisor);
Assert.Equal(expected, size / divisor);
}
[Theory]
[InlineData(-111.111f, 222.222f, 333.333f)]
public void DivideTestSizeFloatWidthHeightDivisor(float width, float height, float divisor)
{
SizeF size = new SizeF(width, height);
SizeF expected = new SizeF(width / divisor, height / divisor);
Assert.Equal(expected, size / divisor);
}
}
}

180
tests/SixLabors.Primitives.Tests/SizeTests.cs

@ -5,6 +5,7 @@
namespace SixLabors.Primitives.Tests
{
using System;
using System.Globalization;
using Xunit;
@ -191,5 +192,184 @@ namespace SixLabors.Primitives.Tests
var sz = new Size(0, 0);
Assert.Equal("Size [ Empty ]", sz.ToString());
}
[Theory]
[InlineData(1000, 0)]
[InlineData(1000, 1)]
[InlineData(1000, 2400)]
[InlineData(1000, int.MaxValue)]
[InlineData(1000, -1)]
[InlineData(1000, -2400)]
[InlineData(1000, int.MinValue)]
[InlineData(int.MaxValue, 0)]
[InlineData(int.MaxValue, 1)]
[InlineData(int.MaxValue, 2400)]
[InlineData(int.MaxValue, int.MaxValue)]
[InlineData(int.MaxValue, -1)]
[InlineData(int.MaxValue, -2400)]
[InlineData(int.MaxValue, int.MinValue)]
[InlineData(int.MinValue, 0)]
[InlineData(int.MinValue, 1)]
[InlineData(int.MinValue, 2400)]
[InlineData(int.MinValue, int.MaxValue)]
[InlineData(int.MinValue, -1)]
[InlineData(int.MinValue, -2400)]
[InlineData(int.MinValue, int.MinValue)]
public void MultiplicationTestSizeInt(int dimension, int multiplier)
{
Size sz1 = new Size(dimension, dimension);
Size mulExpected;
unchecked
{
mulExpected = new Size(dimension * multiplier, dimension * multiplier);
}
Assert.Equal(mulExpected, sz1 * multiplier);
Assert.Equal(mulExpected, multiplier * sz1);
}
[Theory]
[InlineData(1000, 2000, 3000)]
public void MultiplicationTestSizeIntWidthHeightMultiplier(int width, int height, int multiplier)
{
Size sz1 = new Size(width, height);
Size mulExpected;
unchecked
{
mulExpected = new Size(width * multiplier, height * multiplier);
}
Assert.Equal(mulExpected, sz1 * multiplier);
Assert.Equal(mulExpected, multiplier * sz1);
}
[Theory]
[InlineData(1000, 0.0f)]
[InlineData(1000, 1.0f)]
[InlineData(1000, 2400.933f)]
[InlineData(1000, float.MaxValue)]
[InlineData(1000, -1.0f)]
[InlineData(1000, -2400.933f)]
[InlineData(1000, float.MinValue)]
[InlineData(int.MaxValue, 0.0f)]
[InlineData(int.MaxValue, 1.0f)]
[InlineData(int.MaxValue, 2400.933f)]
[InlineData(int.MaxValue, float.MaxValue)]
[InlineData(int.MaxValue, -1.0f)]
[InlineData(int.MaxValue, -2400.933f)]
[InlineData(int.MaxValue, float.MinValue)]
[InlineData(int.MinValue, 0.0f)]
[InlineData(int.MinValue, 1.0f)]
[InlineData(int.MinValue, 2400.933f)]
[InlineData(int.MinValue, float.MaxValue)]
[InlineData(int.MinValue, -1.0f)]
[InlineData(int.MinValue, -2400.933f)]
[InlineData(int.MinValue, float.MinValue)]
public void MultiplicationTestSizeFloat(int dimension, float multiplier)
{
Size sz1 = new Size(dimension, dimension);
SizeF mulExpected;
mulExpected = new SizeF(dimension * multiplier, dimension * multiplier);
Assert.Equal(mulExpected, sz1 * multiplier);
Assert.Equal(mulExpected, multiplier * sz1);
}
[Theory]
[InlineData(1000, 2000, 30.33f)]
public void MultiplicationTestSizeFloatWidthHeightMultiplier(int width, int height, float multiplier)
{
Size sz1 = new Size(width, height);
SizeF mulExpected;
mulExpected = new SizeF(width * multiplier, height * multiplier);
Assert.Equal(mulExpected, sz1 * multiplier);
Assert.Equal(mulExpected, multiplier * sz1);
}
[Fact]
public void DivideByZeroChecks()
{
Size size = new Size(100, 100);
Assert.Throws<DivideByZeroException>(() => size / 0);
SizeF expectedSizeF = new SizeF(float.PositiveInfinity, float.PositiveInfinity);
Assert.Equal(expectedSizeF, size / 0.0f);
}
[Theory]
[InlineData(0, 1)]
[InlineData(1, 1)]
[InlineData(-1, 1)]
[InlineData(1, -1)]
[InlineData(-1, -1)]
[InlineData(int.MaxValue, int.MaxValue)]
[InlineData(int.MaxValue, int.MinValue)]
[InlineData(int.MinValue, int.MaxValue)]
[InlineData(int.MinValue, int.MinValue)]
[InlineData(int.MaxValue, 1)]
[InlineData(int.MinValue, 1)]
[InlineData(int.MaxValue, -1)]
public void DivideTestSizeInt(int dimension, int divisor)
{
Size size = new Size(dimension, dimension);
Size expected;
expected = new Size(dimension / divisor, dimension / divisor);
Assert.Equal(expected, size / divisor);
}
[Theory]
[InlineData(1111, 2222, 3333)]
public void DivideTestSizeIntWidthHeightDivisor(int width, int height, int divisor)
{
Size size = new Size(width, height);
Size expected;
expected = new Size(width / divisor, height / divisor);
Assert.Equal(expected, size / divisor);
}
[Theory]
[InlineData(0, 1.0f)]
[InlineData(1, 1.0f)]
[InlineData(-1, 1.0f)]
[InlineData(1, -1.0f)]
[InlineData(-1, -1.0f)]
[InlineData(int.MaxValue, float.MaxValue)]
[InlineData(int.MaxValue, float.MinValue)]
[InlineData(int.MinValue, float.MaxValue)]
[InlineData(int.MinValue, float.MinValue)]
[InlineData(int.MaxValue, 1.0f)]
[InlineData(int.MinValue, 1.0f)]
[InlineData(int.MaxValue, -1.0f)]
[InlineData(int.MinValue, -1.0f)]
public void DivideTestSizeFloat(int dimension, float divisor)
{
SizeF size = new SizeF(dimension, dimension);
SizeF expected;
expected = new SizeF(dimension / divisor, dimension / divisor);
Assert.Equal(expected, size / divisor);
}
[Theory]
[InlineData(1111, 2222, -333.33f)]
public void DivideTestSizeFloatWidthHeightDivisor(int width, int height, float divisor)
{
SizeF size = new SizeF(width, height);
SizeF expected;
expected = new SizeF(width / divisor, height / divisor);
Assert.Equal(expected, size / divisor);
}
}
}
Loading…
Cancel
Save