C# 将华氏温度转换为摄氏温度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18542357/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert from Fahrenheit to Celsius
提问by user2723261
I'm trying to convert a Fahrenheit temperature into Celsius.
doing the following I'm always getting zero:
我正在尝试将华氏温度转换为摄氏温度。
做以下我总是得到零:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Celcius_Farenheit_Converter
{
class Program
{
static double Celcius(double f)
{
double c = 5/9*(f - 32);
return c;
}
static void Main(string[] args)
{
string text = "enter a farenheit tempature";
double c = Celcius(GetTempature(text));
Console.WriteLine("the tempature in Celicus is {0}", c);
Console.ReadKey(true);
}
static double GetTempature(string text)
{
Console.WriteLine(text);
bool IsItTemp = false;
double x = 0;
do
{
IsItTemp = double.TryParse(Console.ReadLine(), out x);
} while (!IsItTemp);
return x;
}
}
}
can you help me fix it?
你能帮我修一下吗?
回答by p.s.w.g
5/9
performs an integer division—that is, it always discards the fractional part—so it will always return 0.
5/9
执行整数除法——也就是说,它总是丢弃小数部分——所以它总是返回 0。
5.0/9.0
performs floating-point division, and will return the expected 0.55555...
5.0/9.0
执行浮点除法,并将返回预期的 0.55555...
Try this instead:
试试这个:
static double Celcius(double f)
{
double c = 5.0/9.0 * (f - 32);
return c;
}
Further Reading
进一步阅读
回答by Soner G?nül
Change your integer divisionto floating point divisionlike;
将您的整数除法更改为浮点除法,例如;
double c = (5.0 / 9.0) * (f - 32);
From C# Specification $7.7.2 Division operator
;
来自C# Specification $7.7.2 Division operator
;
Integer division:
The division rounds the result towards zero, and the absolute value of the result is the largest possible integer that is less than the absolute value of the quotient of the two operands. The result is zero or positive when the two operands have the same sign and zero or negative when the two operands have opposite signs.
整数除法:
除法将结果向零舍入,结果的绝对值是小于两个操作数的商的绝对值的最大可能整数。当两个操作数的符号相同时,结果为零或正数,当两个操作数的符号相反时,结果为零或负数。
As Frederik said, only chaning one of your variables to floating point type is also enough for your calculation. (5 / 9f
or 5f / 9
gives the right solution)
正如 Frederik所说,仅将您的变量之一更改为浮点类型也足以进行计算。(5 / 9f
或5f / 9
给出正确的解决方案)
回答by JohnLBevan
Earlier in the comments I suggested the option of using a struct
to encapsulate your temperature conversion logic. I've knocked up a rough hash below (only partially tested) should it be of interest:
在前面的评论中,我建议选择使用 astruct
来封装您的温度转换逻辑。如果感兴趣,我已经在下面敲了一个粗略的散列(仅部分测试):
public struct Temperature: IComparable
{
#region fields
double value;
TemperatureUnit unit;
#endregion fields
#region constructors
public Temperature(double value, TemperatureUnit unit)
{
AssertUnitNotNull(unit);
AssertValueNotBelowAbsZero(value, unit);
this.value = value;
this.unit = unit;
}
public Temperature(Temperature temp, TemperatureUnit unit)
{
AssertUnitNotNull(unit);
this.value = ConvertUnit(temp.value, temp.unit, unit);
this.unit = unit;
}
#endregion constructors
#region properties
public double Value
{
get { return this.value; }
set
{
AssertValueNotBelowAbsZero(value, this.unit);
this.value = value;
}
}
public TemperatureUnit Unit
{
get { return this.unit; }
set
{
AssertUnitNotNull(value);
if (this.unit != value)
{
this.value = ConvertUnit(this.value, this.unit, value);
this.unit = value;
}
}
}
#endregion properties
#region methods
#region overridden methods
public override bool Equals(object obj)
{
return this.CompareTo(obj) == 0;
}
public override int GetHashCode()
{
return this.unit.ToKelvin(value).GetHashCode();
}
const string OutputFormat = "{0}{1}";
public override string ToString()
{
return string.Format(OutputFormat, this.value, this.unit.Symbol);
}
#endregion overridden methods
public int CompareTo(object obj)
{
Temperature? t = obj as Temperature?;
if (!t.HasValue) return -1;
return this.unit.ToKelvin(value).CompareTo(t.Value.unit.ToKelvin(t.Value.value));
}
#region operator overloads
public static Temperature operator +(Temperature a, double b)
{
return new Temperature(a.value + b, a.unit);
}
public static Temperature operator +(Temperature a, Temperature b)
{
return a + ConvertUnit(b.value, b.unit, a.unit);
}
public static Temperature operator +(Temperature a, TemperatureUnit b)
{
return new Temperature(a, b);
}
public static Temperature operator -(Temperature a, double b)
{
return new Temperature(a.value - b, a.unit);
}
public static Temperature operator -(Temperature a, Temperature b)
{
return a - ConvertUnit(b.value, b.unit, a.unit);
}
public static Temperature operator ++(Temperature a)
{
return new Temperature(a.value + 1.0, a.unit);
}
public static Temperature operator --(Temperature a)
{
return new Temperature(a.value - 1.0, a.unit);
}
public static Temperature operator /(Temperature a, double b)
{
return new Temperature(a.value / b, a.unit);
}
public static Temperature operator *(Temperature a, double b)
{
return new Temperature(a.value * b, a.unit);
}
#endregion operator overloads
#region helper methods
private static double ConvertUnit(double value, TemperatureUnit from, TemperatureUnit to)
{
return to.FromKelvin(from.ToKelvin(value));
}
#endregion helper methods
#endregion methods
#region static validation methods
private static void AssertUnitNotNull(TemperatureUnit unit)
{
if (unit == null) throw new ArgumentNullException();
}
private static void AssertValueNotBelowAbsZero(double value, TemperatureUnit unit)
{
if (unit.ToKelvin(value) < 0.0) throw new TemperatureIsBelowAbsoluteZeroException(value,unit);
}
#endregion static validation methods
}
public sealed class TemperatureUnit
{
#region delegate definitions
delegate double Conversion(double source);
#endregion delegate definitions
#region attributes
readonly string name;
readonly string symbol;
//base all functions around Kelvin since that allows us to restrict values to zero and above
readonly Conversion fromKelvin;
readonly Conversion toKelvin;
#endregion attributes
#region constructors
private TemperatureUnit(string name, string symbol, Conversion fromKelvin, Conversion toKelvin)
{
this.name = name;
this.symbol = symbol;
this.fromKelvin = fromKelvin;
this.toKelvin = toKelvin;
}
#endregion constructors
#region properties
public string Name { get { return this.name; } }
public string Symbol { get { return this.symbol; } }
#region defined units
public static TemperatureUnit Kelvin = new TemperatureUnit("Kelvin", "\u212A", delegate(double d) { return d; }, delegate(double d) { return d; });
public static TemperatureUnit Celcius = new TemperatureUnit("Celcius", "\u2103", KelvinToCelcius, CelciusToKelvin);
public static TemperatureUnit Farenheit = new TemperatureUnit("Farenheit", "\u2109", KelvinToFarenheit, FarenheitToKelvin);
public static TemperatureUnit Rankine = new TemperatureUnit("Rankine", "\u00B0Ra", KelvinToRankine, RankineToKelvin);
public static TemperatureUnit Romer = new TemperatureUnit("R\u03B8mer", "\u00B0R\u03B8", KelvinToRomer, RomerToKelvin);
public static TemperatureUnit Newton = new TemperatureUnit("Newton", "\u00B0N", KelvinToNewton, NewtonToKelvin);
public static TemperatureUnit Delisle = new TemperatureUnit("Delisle", "\u00B0D", KelvinToDelisle, DelisleToKelvin);
public static TemperatureUnit Reaumur = new TemperatureUnit("R\u00E9amur", "\u00B0R\u00E9", KelvinToReaumur, ReaumurToKelvin);
#endregion defined units
#endregion properties
#region functions
public double FromKelvin(double kelvin)
{
return this.fromKelvin(kelvin);
}
public double ToKelvin(double value)
{
return this.toKelvin(value);
}
#endregion functions
#region overridden methods
public override bool Equals(object obj)
{
TemperatureUnit tu = obj as TemperatureUnit;
if (tu == null) return false;
return this.name.Equals(tu.name);
}
public override int GetHashCode()
{
return this.name.GetHashCode();
}
public override string ToString()
{
return this.name.ToString();
}
#endregion overridden methods
#region static conversion functions
#region Celcius
const double KelvinToCelciusOffset = -273.15;
public static double CelciusToKelvin(double celcius)
{
return celcius - KelvinToCelciusOffset;
}
public static double KelvinToCelcius(double kelvin)
{
return kelvin + KelvinToCelciusOffset;
}
#endregion Celcius
#region Fahrenheit
//Fahrenheit [°F] = [K] × 9?5 ? 459.67 [K] = ([°F] + 459.67) × 5?9
const double KelvinToFarenheitMultiplier = 9.0 / 5.0;
const double KelvinToFarenheitOffset = -459.67;
public static double FarenheitToKelvin(double farenheit)
{
return (farenheit - KelvinToFarenheitOffset) / KelvinToFarenheitMultiplier;
}
public static double KelvinToFarenheit(double kelvin)
{
return kelvin * KelvinToFarenheitMultiplier + KelvinToFarenheitOffset;
}
#endregion Fahrenheit
#region Rankine
const double KelvinToRankineMultiplier = KelvinToFarenheitMultiplier;
public static double RankineToKelvin(double rankine)
{
return rankine / KelvinToRankineMultiplier;
}
public static double KelvinToRankine(double kelvin)
{
return kelvin * KelvinToRankineMultiplier;
}
#endregion Rankine
#region Romer
//[K] = ([°R?] ? 7.5) × 40?21 + 273.15 [°R?] = ([K] ? 273.15) × 21?40 + 7.5
const double KelvinToRomerMultiplier = 21.0 / 40.0;
const double KelvinToRomerOffset1 = KelvinToCelciusOffset;
const double KelvinToRomerOffset2 = 7.5;
public static double RomerToKelvin(double romer)
{
return (romer - KelvinToRomerOffset2) / KelvinToRomerMultiplier - KelvinToRomerOffset1;
}
public static double KelvinToRomer(double kelvin)
{
return (kelvin + KelvinToRomerOffset1) * KelvinToRomerMultiplier + KelvinToRomerOffset2;
}
#endregion Romer
#region Newton
//[K] = [°N] × 100?33 + 273.15 [°N] = ([K] ? 273.15) × 33?100
const double KelvinToNewtonMultiplier = 33.0 / 100.0;
const double KelvinToNewtonOffset = KelvinToCelciusOffset;
public static double NewtonToKelvin(double newton)
{
return (newton / KelvinToNewtonMultiplier) - KelvinToNewtonOffset;
}
public static double KelvinToNewton(double kelvin)
{
return (kelvin + KelvinToNewtonOffset) * KelvinToNewtonMultiplier;
}
#endregion Newton
#region Delisle
//[K] = 373.15 ? [°De] × 2?3 [°De] = (373.15 ? [K]) × 3?2
const double KelvinToDelisleMultiplier = 1.5;
const double KelvinToDelisleOffset = 373.15;
public static double DelisleToKelvin(double delisle)
{
return KelvinToDelisleOffset - delisle / KelvinToDelisleMultiplier;
}
public static double KelvinToDelisle(double kelvin)
{
return (KelvinToDelisleOffset - kelvin) * KelvinToDelisleMultiplier;
}
#endregion Delisle
#region Reaumur
//[K] = [°Ré] × 5?4 + 273.15 [°Ré] = ([K] ? 273.15) × 4?5
const double KelvinToReaumurMultiplier = 4.0 / 5.0;
const double KelvinToReaumurOffset = KelvinToCelciusOffset;
public static double ReaumurToKelvin(double reaumur)
{
return reaumur / KelvinToReaumurMultiplier - KelvinToReaumurOffset;
}
public static double KelvinToReaumur(double kelvin)
{
return (kelvin + KelvinToReaumurOffset) * KelvinToReaumurMultiplier;
}
#endregion Reaumur
#endregion static conversion functions
}
public class TemperatureIsBelowAbsoluteZeroException : Exception
{
public TemperatureIsBelowAbsoluteZeroException() : base() { }
public TemperatureIsBelowAbsoluteZeroException(string message) : base(message) { }
public TemperatureIsBelowAbsoluteZeroException(string message, Exception innerException) : base(message,innerException) { }
public TemperatureIsBelowAbsoluteZeroException(System.Runtime.Serialization.SerializationInfo info,System.Runtime.Serialization.StreamingContext context) : base(info,context) { }
const string ErrorMessageFormat = "Value '{0}{1}' is below absolute zero!";
public TemperatureIsBelowAbsoluteZeroException(double value, TemperatureUnit unit) : base(string.Format(ErrorMessageFormat, value, unit.Symbol)) { }
}
回答by Milodin
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class TempConvert
{
static void Main(string[] args)
{
//Variables declared to hold and test conversion
//floats used to avoid int calculation errors
float originalFarenheit;
float centigrade;
float returnFarenheit;
Console.Write("Enter Temperature (Farenheit): "); //take temp to be converted
originalFarenheit = float.Parse(Console.ReadLine()); //hold as float var
centigrade = ((originalFarenheit - 32) / 9) * 5; //Convert to centrigrade
returnFarenheit = ((centigrade / 5) * 9) + 32; //test conversion by reversing
Console.WriteLine("Centigrade = :" + centigrade); //Display result
Console.WriteLine("Return Farenheit = :" + returnFarenheit); //Test result
Console.ReadKey();
}
}
}
回答by Praveen M
This is a general method, which will perform all temperature unit conversions
这是一种通用方法,它将执行所有温度单位转换
public static double ConvertTemperatureUnits(TemperatureUnit toConvert, TemperatureUnit from, double value)
{
double convertedValue = 0.0;
if (toConvert == from)
return value;
switch (toConvert)
{
case TemperatureUnit.FAHRENHEIT:
{
switch (from)
{
case TemperatureUnit.CELSIUS:
convertedValue = (value * 9) / 5 + 32;
break;
case TemperatureUnit.KELVIN:
convertedValue = 1.8 * (value - 273.15) + 32;
break;
}
}
break;
case TemperatureUnit.KELVIN:
switch (from)
{
case TemperatureUnit.CELSIUS:
convertedValue = value + 273.15;
break;
case TemperatureUnit.FAHRENHEIT:
convertedValue = (value + 459.67) * 5 / 9;
break;
}
break;
case TemperatureUnit.CELSIUS:
switch (from)
{
case TemperatureUnit.KELVIN:
convertedValue = value - 273.15;
break;
case TemperatureUnit.FAHRENHEIT:
convertedValue = (value - 32) * 5 / 9;
break;
}
break;
}
return convertedValue;
}
create TemperatureUnit enum like this
像这样创建 TemperatureUnit 枚举
enum TemperatureUnit
{
FAHRENHEIT,
KELVIN,
CELSIUS
}