Skip to content

Commit 71bc0a8

Browse files
committed
Revert "Normalize Temperature arithmetic (#550)"
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.
1 parent f28d009 commit 71bc0a8

File tree

6 files changed

+98
-132
lines changed

6 files changed

+98
-132
lines changed

Common/UnitDefinitions/Temperature.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"Name": "Temperature",
33
"BaseUnit": "Kelvin",
44
"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.",
5+
"GenerateArithmetic": false,
56
"BaseDimensions": {
67
"Θ": 1
78
},
@@ -103,4 +104,4 @@
103104
]
104105
}
105106
]
106-
}
107+
}
Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
//------------------------------------------------------------------------------
22
// <auto-generated>
33
// This code was generated (once) by \generate-code.bat, but will not be
4-
// regenerated when it already exists. The purpose of creating this file is to make
4+
// regenerated when it already exists. The purpose of creating this file is to make
55
// it easier to remember to implement all the unit conversion test cases.
6-
//
6+
//
77
// Whenever a new unit is added to this unit class and \generate-code.bat is run,
88
// the base test class will get a new abstract property and cause a compile error
99
// in this derived class, reminding the developer to implement the test case
@@ -19,17 +19,17 @@
1919

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

4543
namespace UnitsNet.Tests.CustomCode
@@ -61,24 +59,5 @@ public void TemperatureDeltaTimesSpecificEntropyEqualsSpecificEnergy()
6159
SpecificEnergy specificEnergy = SpecificEntropy.FromJoulesPerKilogramKelvin(10) * TemperatureDelta.FromKelvins(6);
6260
Assert.Equal(specificEnergy, SpecificEnergy.FromJoulesPerKilogram(60));
6361
}
64-
65-
[Theory]
66-
[InlineData(TemperatureUnit.DegreeCelsius, 30, 20, "10 ∆°C")]
67-
[InlineData(TemperatureUnit.DegreeCelsius, 20, 30, "-10 ∆°C")]
68-
[InlineData(TemperatureUnit.DegreeFahrenheit, 30, 20, "10 ∆°F")]
69-
[InlineData(TemperatureUnit.DegreeFahrenheit, 20, 30, "-10 ∆°F")]
70-
[InlineData(TemperatureUnit.Kelvin, 30, 20, "10 ∆K")]
71-
[InlineData(TemperatureUnit.Kelvin, 20, 30, "-10 ∆K")]
72-
public void FromTemperatures_ReturnsDeltaOfTheTwoTemperaturesInLeftUnit(TemperatureUnit unit, int value, int otherValue, string expected)
73-
{
74-
Temperature temperature = Temperature.From(value, unit);
75-
Temperature otherTemperature = Temperature.From(otherValue, unit);
76-
77-
// Act
78-
var delta = TemperatureDelta.FromTemperatures(temperature, otherTemperature);
79-
80-
// Assert
81-
Assert.Equal(expected, delta.ToString(CultureInfo.InvariantCulture, "{0:0} {1}"));
82-
}
8362
}
8463
}

UnitsNet.Tests/CustomCode/TemperatureTests.cs

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
// Copyright (c) 2013 Andreas Gullberg Larsen ([email protected]).
22
// https://github.com/angularsen/UnitsNet
3-
//
3+
//
44
// Permission is hereby granted, free of charge, to any person obtaining a copy
55
// of this software and associated documentation files (the "Software"), to deal
66
// in the Software without restriction, including without limitation the rights
77
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
88
// copies of the Software, and to permit persons to whom the Software is
99
// furnished to do so, subject to the following conditions:
10-
//
10+
//
1111
// The above copyright notice and this permission notice shall be included in
1212
// all copies or substantial portions of the Software.
13-
//
13+
//
1414
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1515
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1616
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -45,6 +45,46 @@ public class TemperatureTests : TemperatureTestsBase
4545

4646
protected override double KelvinsInOneKelvin => 1;
4747

48+
[SuppressMessage("ReSharper", "ImpureMethodCallOnReadonlyValueField",
49+
Justification = "R# incorrectly identifies method as impure, due to internal method calls.")]
50+
[Theory]
51+
[InlineData(TemperatureUnit.DegreeCelsius, 10, 1, "10 °C")]
52+
[InlineData(TemperatureUnit.DegreeCelsius, 10, 5, "2 °C")]
53+
[InlineData(TemperatureUnit.DegreeCelsius, 10, -10, "-1 °C")]
54+
[InlineData(TemperatureUnit.DegreeFahrenheit, 10, 1, "10 °F")]
55+
[InlineData(TemperatureUnit.DegreeFahrenheit, 10, 5, "2 °F")]
56+
[InlineData(TemperatureUnit.DegreeFahrenheit, 10, -10, "-1 °F")]
57+
public void DividedByTemperatureDeltaEqualsTemperature(TemperatureUnit unit, int temperatureVal, int divisor, string expected)
58+
{
59+
Temperature temperature = Temperature.From(temperatureVal, unit);
60+
61+
// Act
62+
Temperature resultTemp = temperature.Divide(divisor, unit);
63+
64+
string actual = resultTemp.ToUnit(unit).ToString(CultureInfo.InvariantCulture, "{0:0} {1}");
65+
Assert.Equal(expected, actual);
66+
}
67+
68+
[SuppressMessage("ReSharper", "ImpureMethodCallOnReadonlyValueField",
69+
Justification = "R# incorrectly identifies method as impure, due to internal method calls.")]
70+
[Theory]
71+
[InlineData(TemperatureUnit.DegreeCelsius, 10, 0, "0 °C")]
72+
[InlineData(TemperatureUnit.DegreeCelsius, 10, 5, "50 °C")]
73+
[InlineData(TemperatureUnit.DegreeCelsius, 10, -5, "-50 °C")]
74+
[InlineData(TemperatureUnit.DegreeFahrenheit, 10, 0, "0 °F")]
75+
[InlineData(TemperatureUnit.DegreeFahrenheit, 10, 5, "50 °F")]
76+
[InlineData(TemperatureUnit.DegreeFahrenheit, 10, -5, "-50 °F")]
77+
public void MultiplyByTemperatureDeltaEqualsTemperature(TemperatureUnit unit, int temperatureVal, int factor, string expected)
78+
{
79+
Temperature temperature = Temperature.From(temperatureVal, unit);
80+
81+
// Act
82+
Temperature resultTemp = temperature.Multiply(factor, unit);
83+
84+
string actual = resultTemp.ToUnit(unit).ToString(CultureInfo.InvariantCulture, "{0:0} {1}");
85+
Assert.Equal(expected, actual);
86+
}
87+
4888
[Theory]
4989
[InlineData(TemperatureUnit.DegreeCelsius, -10, 0, "-10 °C")]
5090
[InlineData(TemperatureUnit.DegreeCelsius, -10, 10, "0 °C")]
@@ -101,24 +141,5 @@ public void TemperaturePlusTemperatureDeltaEqualsTemperature(TemperatureUnit uni
101141
string actual = resultTemp.ToUnit(unit).ToString(CultureInfo.InvariantCulture, "{0:0} {1}");
102142
Assert.Equal(expected, actual);
103143
}
104-
105-
[Theory]
106-
[InlineData(TemperatureUnit.DegreeCelsius, 30, 20, "10 ∆°C")]
107-
[InlineData(TemperatureUnit.DegreeCelsius, 20, 30, "-10 ∆°C")]
108-
[InlineData(TemperatureUnit.DegreeFahrenheit, 30, 20, "10 ∆°F")]
109-
[InlineData(TemperatureUnit.DegreeFahrenheit, 20, 30, "-10 ∆°F")]
110-
[InlineData(TemperatureUnit.Kelvin, 30, 20, "10 ∆K")]
111-
[InlineData(TemperatureUnit.Kelvin, 20, 30, "-10 ∆K")]
112-
public void ToDelta_ReturnsDeltaOfTwoTemperaturesInSameUnit(TemperatureUnit unit, int value, int otherValue, string expected)
113-
{
114-
Temperature temperature = Temperature.From(value, unit);
115-
Temperature otherTemperature = Temperature.From(otherValue, unit);
116-
117-
// Act
118-
var delta = temperature.ToDelta(otherTemperature);
119-
120-
// Assert
121-
Assert.Equal(expected, delta.ToString(CultureInfo.InvariantCulture, "{0:0} {1}"));
122-
}
123144
}
124145
}

UnitsNet/CustomCode/Quantities/Temperature.extra.cs

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
// Copyright (c) 2013 Andreas Gullberg Larsen ([email protected]).
22
// https://github.com/angularsen/UnitsNet
3-
//
3+
//
44
// Permission is hereby granted, free of charge, to any person obtaining a copy
55
// of this software and associated documentation files (the "Software"), to deal
66
// in the Software without restriction, including without limitation the rights
77
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
88
// copies of the Software, and to permit persons to whom the Software is
99
// furnished to do so, subject to the following conditions:
10-
//
10+
//
1111
// The above copyright notice and this permission notice shall be included in
1212
// all copies or substantial portions of the Software.
13-
//
13+
//
1414
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1515
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1616
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -36,7 +36,7 @@ public partial struct Temperature
3636
// Windows Runtime Component does not allow operator overloads: https://msdn.microsoft.com/en-us/library/br230301.aspx
3737
#if !WINDOWS_UWP
3838
/// <summary>
39-
/// Add a <see cref="TemperatureDelta" /> to a <see cref="Temperature" />.
39+
/// Add a <see cref="Temperature" /> and a <see cref="TemperatureDelta" />.
4040
/// </summary>
4141
/// <remarks>Due to temperature units having different scales, the arithmetic must be performed on the same scale.</remarks>
4242
/// <returns>The new temperature.</returns>
@@ -46,7 +46,7 @@ public partial struct Temperature
4646
}
4747

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

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

6868
/// <summary>
69-
/// Subtract two temperatures to get a <see cref="TemperatureDelta"/> in this temperature's unit, which you can later convert to any temperature unit.
70-
/// This is useful since Celsius, Fahrenheit and Kelvins don't share a common zero point on the scale and normal subtraction
71-
/// would operate on Kelvins and likely give an unexpected result.
72-
/// Example:
73-
/// double deltaCelsius = celsius30.ToDelta(celsius20).DegreesCelsius; // 10 C
74-
/// double wrongDeltaCelsius = (celsius30 - celsius20).DegreesCelsius; // 303.15 K - 293.15 K = 10 K = -263.15 degrees Celsius
69+
/// Subtract a <see cref="Temperature" /> by a <see cref="TemperatureDelta" />.
7570
/// </summary>
76-
/// <returns>A temperature delta.</returns>
77-
public TemperatureDelta ToDelta(Temperature other) => TemperatureDelta.FromTemperatures(this, other);
71+
/// <remarks>Due to temperature units having different scales, the arithmetic must be performed on the same scale.</remarks>
72+
/// <returns>The delta temperature (difference).</returns>
73+
public static TemperatureDelta operator -(Temperature left, Temperature right)
74+
{
75+
return new TemperatureDelta(left.Kelvins - right.Kelvins, TemperatureDeltaUnit.Kelvin);
76+
}
7877
#endif
78+
79+
/// <summary>
80+
/// Multiply temperature with a <paramref name="factor" /> in a given <paramref name="unit" />.
81+
/// </summary>
82+
/// <remarks>
83+
/// Due to different temperature units having different zero points, we cannot simply
84+
/// multiply or divide a temperature by a factor. We must first convert to the desired unit, then perform the
85+
/// calculation.
86+
/// </remarks>
87+
/// <param name="factor">Factor to multiply by.</param>
88+
/// <param name="unit">Unit to perform multiplication in.</param>
89+
/// <returns>The resulting <see cref="Temperature" />.</returns>
90+
public Temperature Multiply(double factor, TemperatureUnit unit)
91+
{
92+
double resultInUnit = As(unit) * factor;
93+
return From(resultInUnit, unit);
94+
}
95+
96+
97+
/// <summary>
98+
/// Divide temperature by a <paramref name="divisor" /> in a given <paramref name="unit" />.
99+
/// </summary>
100+
/// <remarks>
101+
/// Due to different temperature units having different zero points, we cannot simply
102+
/// multiply or divide a temperature by a factor. We must first convert to the desired unit, then perform the
103+
/// calculation.
104+
/// </remarks>
105+
/// <param name="divisor">Factor to multiply by.</param>
106+
/// <param name="unit">Unit to perform multiplication in.</param>
107+
/// <returns>The resulting <see cref="Temperature" />.</returns>
108+
public Temperature Divide(double divisor, TemperatureUnit unit)
109+
{
110+
double resultInUnit = As(unit) / divisor;
111+
return From(resultInUnit, unit);
112+
}
79113
}
80114
}

UnitsNet/CustomCode/Quantities/TemperatureDelta.extra.cs

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,6 @@
2020
// THE SOFTWARE.
2121

2222
// ReSharper disable once CheckNamespace
23-
24-
using System;
25-
using UnitsNet.Units;
26-
2723
namespace UnitsNet
2824
{
2925
// Windows Runtime Component has constraints on public types: https://msdn.microsoft.com/en-us/library/br230301.aspx#Declaring types in Windows Runtime Components
@@ -51,32 +47,6 @@ public partial struct TemperatureDelta
5147
{
5248
return specificEntropy * temperatureDelta;
5349
}
54-
55-
/// <summary>
56-
/// Subtract two temperatures to get a <see cref="TemperatureDelta"/> in <paramref name="left"/>'s unit, which you can later convert to any temperature unit.
57-
/// This is useful since Celsius, Fahrenheit and Kelvins don't share a common zero point on the scale and normal subtraction
58-
/// would operate on Kelvins and likely give an unexpected result.
59-
/// Example:
60-
/// double deltaCelsius = TemperatureDelta.FromTemperatures(celsius30, celsius20).DegreesCelsius; // 10 C
61-
/// double wrongDeltaCelsius = (celsius30 - celsius20).DegreesCelsius; // 303.15 K - 293.15 K = 10 K = -263.15 degrees Celsius
62-
/// </summary>
63-
/// <returns>A temperature delta.</returns>
64-
public static TemperatureDelta FromTemperatures(Temperature left, Temperature right)
65-
{
66-
TemperatureDeltaUnit deltaUnit = ToDeltaUnit(left.Unit);
67-
return new TemperatureDelta(left.Value - right.As(left.Unit), deltaUnit);
68-
}
69-
70-
/// <summary>
71-
/// Converts a temperature unit to a temperature delta unit.
72-
/// They share the exact same unit names, but are of different enum types and have slightly different semantic meaning.
73-
/// </summary>
74-
/// <param name="temperatureUnit">Temperature unit.</param>
75-
/// <returns>Equivalent temperature delta unit.</returns>
76-
public static TemperatureDeltaUnit ToDeltaUnit(TemperatureUnit temperatureUnit)
77-
{
78-
return (TemperatureDeltaUnit)Enum.Parse(typeof(TemperatureDeltaUnit), temperatureUnit.ToString());
79-
}
8050
#endif
8151
}
8252
}

UnitsNet/GeneratedCode/Quantities/Temperature.NetFramework.g.cs

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

0 commit comments

Comments
 (0)