Skip to content

Commit

Permalink
Revert "Normalize Temperature arithmetic (#550)"
Browse files Browse the repository at this point in the history
This reverts commit b0361ba.

Per discussion in:
#560 (comment)

We can't justify this change just yet, we need to know if the majority
of our userbase expects this new Temperature arithmetic or the old one.
  • Loading branch information
angularsen committed Nov 16, 2018
1 parent f28d009 commit 71bc0a8
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 132 deletions.
3 changes: 2 additions & 1 deletion Common/UnitDefinitions/Temperature.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"Name": "Temperature",
"BaseUnit": "Kelvin",
"XmlDoc": "A temperature is a numerical measure of hot or cold. Its measurement is by detection of heat radiation or particle velocity or kinetic energy, or by the bulk behavior of a thermometric material. It may be calibrated in any of various temperature scales, Celsius, Fahrenheit, Kelvin, etc. The fundamental physical definition of temperature is provided by thermodynamics.",
"GenerateArithmetic": false,
"BaseDimensions": {
"Θ": 1
},
Expand Down Expand Up @@ -103,4 +104,4 @@
]
}
]
}
}
31 changes: 5 additions & 26 deletions UnitsNet.Tests/CustomCode/TemperatureDeltaTests.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated (once) by \generate-code.bat, but will not be
// regenerated when it already exists. The purpose of creating this file is to make
// regenerated when it already exists. The purpose of creating this file is to make
// it easier to remember to implement all the unit conversion test cases.
//
//
// Whenever a new unit is added to this unit class and \generate-code.bat is run,
// the base test class will get a new abstract property and cause a compile error
// in this derived class, reminding the developer to implement the test case
Expand All @@ -19,17 +19,17 @@

// Copyright (c) 2013 Andreas Gullberg Larsen ([email protected]).
// https://github.com/angularsen/UnitsNet
//
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Expand All @@ -38,8 +38,6 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Globalization;
using UnitsNet.Units;
using Xunit;

namespace UnitsNet.Tests.CustomCode
Expand All @@ -61,24 +59,5 @@ public void TemperatureDeltaTimesSpecificEntropyEqualsSpecificEnergy()
SpecificEnergy specificEnergy = SpecificEntropy.FromJoulesPerKilogramKelvin(10) * TemperatureDelta.FromKelvins(6);
Assert.Equal(specificEnergy, SpecificEnergy.FromJoulesPerKilogram(60));
}

[Theory]
[InlineData(TemperatureUnit.DegreeCelsius, 30, 20, "10 ∆°C")]
[InlineData(TemperatureUnit.DegreeCelsius, 20, 30, "-10 ∆°C")]
[InlineData(TemperatureUnit.DegreeFahrenheit, 30, 20, "10 ∆°F")]
[InlineData(TemperatureUnit.DegreeFahrenheit, 20, 30, "-10 ∆°F")]
[InlineData(TemperatureUnit.Kelvin, 30, 20, "10 ∆K")]
[InlineData(TemperatureUnit.Kelvin, 20, 30, "-10 ∆K")]
public void FromTemperatures_ReturnsDeltaOfTheTwoTemperaturesInLeftUnit(TemperatureUnit unit, int value, int otherValue, string expected)
{
Temperature temperature = Temperature.From(value, unit);
Temperature otherTemperature = Temperature.From(otherValue, unit);

// Act
var delta = TemperatureDelta.FromTemperatures(temperature, otherTemperature);

// Assert
Assert.Equal(expected, delta.ToString(CultureInfo.InvariantCulture, "{0:0} {1}"));
}
}
}
65 changes: 43 additions & 22 deletions UnitsNet.Tests/CustomCode/TemperatureTests.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
// Copyright (c) 2013 Andreas Gullberg Larsen ([email protected]).
// https://github.com/angularsen/UnitsNet
//
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Expand Down Expand Up @@ -45,6 +45,46 @@ public class TemperatureTests : TemperatureTestsBase

protected override double KelvinsInOneKelvin => 1;

[SuppressMessage("ReSharper", "ImpureMethodCallOnReadonlyValueField",
Justification = "R# incorrectly identifies method as impure, due to internal method calls.")]
[Theory]
[InlineData(TemperatureUnit.DegreeCelsius, 10, 1, "10 °C")]
[InlineData(TemperatureUnit.DegreeCelsius, 10, 5, "2 °C")]
[InlineData(TemperatureUnit.DegreeCelsius, 10, -10, "-1 °C")]
[InlineData(TemperatureUnit.DegreeFahrenheit, 10, 1, "10 °F")]
[InlineData(TemperatureUnit.DegreeFahrenheit, 10, 5, "2 °F")]
[InlineData(TemperatureUnit.DegreeFahrenheit, 10, -10, "-1 °F")]
public void DividedByTemperatureDeltaEqualsTemperature(TemperatureUnit unit, int temperatureVal, int divisor, string expected)
{
Temperature temperature = Temperature.From(temperatureVal, unit);

// Act
Temperature resultTemp = temperature.Divide(divisor, unit);

string actual = resultTemp.ToUnit(unit).ToString(CultureInfo.InvariantCulture, "{0:0} {1}");
Assert.Equal(expected, actual);
}

[SuppressMessage("ReSharper", "ImpureMethodCallOnReadonlyValueField",
Justification = "R# incorrectly identifies method as impure, due to internal method calls.")]
[Theory]
[InlineData(TemperatureUnit.DegreeCelsius, 10, 0, "0 °C")]
[InlineData(TemperatureUnit.DegreeCelsius, 10, 5, "50 °C")]
[InlineData(TemperatureUnit.DegreeCelsius, 10, -5, "-50 °C")]
[InlineData(TemperatureUnit.DegreeFahrenheit, 10, 0, "0 °F")]
[InlineData(TemperatureUnit.DegreeFahrenheit, 10, 5, "50 °F")]
[InlineData(TemperatureUnit.DegreeFahrenheit, 10, -5, "-50 °F")]
public void MultiplyByTemperatureDeltaEqualsTemperature(TemperatureUnit unit, int temperatureVal, int factor, string expected)
{
Temperature temperature = Temperature.From(temperatureVal, unit);

// Act
Temperature resultTemp = temperature.Multiply(factor, unit);

string actual = resultTemp.ToUnit(unit).ToString(CultureInfo.InvariantCulture, "{0:0} {1}");
Assert.Equal(expected, actual);
}

[Theory]
[InlineData(TemperatureUnit.DegreeCelsius, -10, 0, "-10 °C")]
[InlineData(TemperatureUnit.DegreeCelsius, -10, 10, "0 °C")]
Expand Down Expand Up @@ -101,24 +141,5 @@ public void TemperaturePlusTemperatureDeltaEqualsTemperature(TemperatureUnit uni
string actual = resultTemp.ToUnit(unit).ToString(CultureInfo.InvariantCulture, "{0:0} {1}");
Assert.Equal(expected, actual);
}

[Theory]
[InlineData(TemperatureUnit.DegreeCelsius, 30, 20, "10 ∆°C")]
[InlineData(TemperatureUnit.DegreeCelsius, 20, 30, "-10 ∆°C")]
[InlineData(TemperatureUnit.DegreeFahrenheit, 30, 20, "10 ∆°F")]
[InlineData(TemperatureUnit.DegreeFahrenheit, 20, 30, "-10 ∆°F")]
[InlineData(TemperatureUnit.Kelvin, 30, 20, "10 ∆K")]
[InlineData(TemperatureUnit.Kelvin, 20, 30, "-10 ∆K")]
public void ToDelta_ReturnsDeltaOfTwoTemperaturesInSameUnit(TemperatureUnit unit, int value, int otherValue, string expected)
{
Temperature temperature = Temperature.From(value, unit);
Temperature otherTemperature = Temperature.From(otherValue, unit);

// Act
var delta = temperature.ToDelta(otherTemperature);

// Assert
Assert.Equal(expected, delta.ToString(CultureInfo.InvariantCulture, "{0:0} {1}"));
}
}
}
62 changes: 48 additions & 14 deletions UnitsNet/CustomCode/Quantities/Temperature.extra.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
// Copyright (c) 2013 Andreas Gullberg Larsen ([email protected]).
// https://github.com/angularsen/UnitsNet
//
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Expand All @@ -36,7 +36,7 @@ public partial struct Temperature
// Windows Runtime Component does not allow operator overloads: https://msdn.microsoft.com/en-us/library/br230301.aspx
#if !WINDOWS_UWP
/// <summary>
/// Add a <see cref="TemperatureDelta" /> to a <see cref="Temperature" />.
/// Add a <see cref="Temperature" /> and a <see cref="TemperatureDelta" />.
/// </summary>
/// <remarks>Due to temperature units having different scales, the arithmetic must be performed on the same scale.</remarks>
/// <returns>The new temperature.</returns>
Expand All @@ -46,7 +46,7 @@ public partial struct Temperature
}

/// <summary>
/// Add a <see cref="TemperatureDelta" /> to a <see cref="Temperature" />.
/// Add a <see cref="TemperatureDelta" /> and a <see cref="Temperature" />.
/// </summary>
/// <remarks>Due to temperature units having different scales, the arithmetic must be performed on the same scale.</remarks>
/// <returns>The new temperature.</returns>
Expand All @@ -56,7 +56,7 @@ public partial struct Temperature
}

/// <summary>
/// Subtract a <see cref="TemperatureDelta" /> from a <see cref="Temperature" />.
/// Subtract a <see cref="Temperature" /> by a <see cref="TemperatureDelta" />.
/// </summary>
/// <remarks>Due to temperature units having different scales, the arithmetic must be performed on the same scale.</remarks>
/// <returns>The new temperature.</returns>
Expand All @@ -66,15 +66,49 @@ public partial struct Temperature
}

/// <summary>
/// Subtract two temperatures to get a <see cref="TemperatureDelta"/> in this temperature's unit, which you can later convert to any temperature unit.
/// This is useful since Celsius, Fahrenheit and Kelvins don't share a common zero point on the scale and normal subtraction
/// would operate on Kelvins and likely give an unexpected result.
/// Example:
/// double deltaCelsius = celsius30.ToDelta(celsius20).DegreesCelsius; // 10 C
/// double wrongDeltaCelsius = (celsius30 - celsius20).DegreesCelsius; // 303.15 K - 293.15 K = 10 K = -263.15 degrees Celsius
/// Subtract a <see cref="Temperature" /> by a <see cref="TemperatureDelta" />.
/// </summary>
/// <returns>A temperature delta.</returns>
public TemperatureDelta ToDelta(Temperature other) => TemperatureDelta.FromTemperatures(this, other);
/// <remarks>Due to temperature units having different scales, the arithmetic must be performed on the same scale.</remarks>
/// <returns>The delta temperature (difference).</returns>
public static TemperatureDelta operator -(Temperature left, Temperature right)
{
return new TemperatureDelta(left.Kelvins - right.Kelvins, TemperatureDeltaUnit.Kelvin);
}
#endif

/// <summary>
/// Multiply temperature with a <paramref name="factor" /> in a given <paramref name="unit" />.
/// </summary>
/// <remarks>
/// Due to different temperature units having different zero points, we cannot simply
/// multiply or divide a temperature by a factor. We must first convert to the desired unit, then perform the
/// calculation.
/// </remarks>
/// <param name="factor">Factor to multiply by.</param>
/// <param name="unit">Unit to perform multiplication in.</param>
/// <returns>The resulting <see cref="Temperature" />.</returns>
public Temperature Multiply(double factor, TemperatureUnit unit)
{
double resultInUnit = As(unit) * factor;
return From(resultInUnit, unit);
}


/// <summary>
/// Divide temperature by a <paramref name="divisor" /> in a given <paramref name="unit" />.
/// </summary>
/// <remarks>
/// Due to different temperature units having different zero points, we cannot simply
/// multiply or divide a temperature by a factor. We must first convert to the desired unit, then perform the
/// calculation.
/// </remarks>
/// <param name="divisor">Factor to multiply by.</param>
/// <param name="unit">Unit to perform multiplication in.</param>
/// <returns>The resulting <see cref="Temperature" />.</returns>
public Temperature Divide(double divisor, TemperatureUnit unit)
{
double resultInUnit = As(unit) / divisor;
return From(resultInUnit, unit);
}
}
}
30 changes: 0 additions & 30 deletions UnitsNet/CustomCode/Quantities/TemperatureDelta.extra.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@
// THE SOFTWARE.

// ReSharper disable once CheckNamespace

using System;
using UnitsNet.Units;

namespace UnitsNet
{
// Windows Runtime Component has constraints on public types: https://msdn.microsoft.com/en-us/library/br230301.aspx#Declaring types in Windows Runtime Components
Expand Down Expand Up @@ -51,32 +47,6 @@ public partial struct TemperatureDelta
{
return specificEntropy * temperatureDelta;
}

/// <summary>
/// Subtract two temperatures to get a <see cref="TemperatureDelta"/> in <paramref name="left"/>'s unit, which you can later convert to any temperature unit.
/// This is useful since Celsius, Fahrenheit and Kelvins don't share a common zero point on the scale and normal subtraction
/// would operate on Kelvins and likely give an unexpected result.
/// Example:
/// double deltaCelsius = TemperatureDelta.FromTemperatures(celsius30, celsius20).DegreesCelsius; // 10 C
/// double wrongDeltaCelsius = (celsius30 - celsius20).DegreesCelsius; // 303.15 K - 293.15 K = 10 K = -263.15 degrees Celsius
/// </summary>
/// <returns>A temperature delta.</returns>
public static TemperatureDelta FromTemperatures(Temperature left, Temperature right)
{
TemperatureDeltaUnit deltaUnit = ToDeltaUnit(left.Unit);
return new TemperatureDelta(left.Value - right.As(left.Unit), deltaUnit);
}

/// <summary>
/// Converts a temperature unit to a temperature delta unit.
/// They share the exact same unit names, but are of different enum types and have slightly different semantic meaning.
/// </summary>
/// <param name="temperatureUnit">Temperature unit.</param>
/// <returns>Equivalent temperature delta unit.</returns>
public static TemperatureDeltaUnit ToDeltaUnit(TemperatureUnit temperatureUnit)
{
return (TemperatureDeltaUnit)Enum.Parse(typeof(TemperatureDeltaUnit), temperatureUnit.ToString());
}
#endif
}
}
39 changes: 0 additions & 39 deletions UnitsNet/GeneratedCode/Quantities/Temperature.NetFramework.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 71bc0a8

Please sign in to comment.