Temperature conversion: Difference between revisions
→{{header|REXX}}: added the REXX language. -- ~~~~ |
m →{{header|REXX}}: added an alternate word for Celcius. -- ~~~~ |
||
Line 239: | Line 239: | ||
This REXX version supports: |
This REXX version supports: |
||
* (alternate spellings with optional ''degrees''): |
* (alternate spellings with optional ''degrees''): |
||
** Centingrade, Celsius, Celcius |
** Centingrade, centesimal, Celsius, Celcius |
||
** Fahrenheit |
** Fahrenheit |
||
** Kelvin |
** Kelvin |
||
Line 271: | Line 271: | ||
select /*convert ───◄ common temperature*/ |
select /*convert ───◄ common temperature*/ |
||
when abbrev('CENTIGRADE', uU) |, |
when abbrev('CENTIGRADE', uU) |, |
||
abbrev('CENTESIMAL', uU) |, |
|||
abbrev('CELSIUS' , uU) |, |
abbrev('CELSIUS' , uU) |, |
||
abbrev('CELCIUS' , uU) then F = n * 1.8 + 32 |
abbrev('CELCIUS' , uU) then F = n * 1.8 + 32 |
Revision as of 23:39, 13 February 2013
There are quite a number of temperature scales. For this task we will concentrate on 4 of the perhaps best-known ones: Kelvin, Celcius, Fahrenheit and Rankine.
The Celcius and Kelvin scales have the same magnitude, but different null points.
0 degrees Celcius corresponds to 273.15 kelvin.
0 kelvin is absolute zero.
The Fahrenheit and Rankine scales also have the same magnitude, but different null points.
0 degrees Fahrenheit corresponds to 459.67 degrees Rankine.
0 degrees Rankine is absolute zero.
The Celcius/Kelvin and Fahrenheit/Rankine scales have a ratio of 5 : 9.
Write code that accepts a value of kelvin, converts it to values on the three other scales and prints the result. For instance:
K 21.00 C -252.15 F -421.87 R 37.80
D
<lang d>double kelvinToCelsius(in double k) pure nothrow @safe {
return k - 273.15;
}
double kelvinToFahrenheit(in double k) pure nothrow @safe {
return k * 1.8 - 459.67;
}
double kelvinToRankine(in double k) pure nothrow @safe {
return k * 1.8;
}
unittest {
import std.math: approxEqual; assert(approxEqual(kelvinToCelsius(21.0), -252.15)); assert(approxEqual(kelvinToFahrenheit(21.0), -421.87)); assert(approxEqual(kelvinToRankine(21.0), 37.8));
}
void main(string[] args) {
import std.stdio, std.conv, std.string;
if (args.length == 2 && isNumeric(args[1])) { immutable kelvin = to!double(args[1]); if (kelvin >= 0) { writefln("K %2.2f", kelvin); writefln("C %2.2f", kelvinToCelsius(kelvin)); writefln("F %2.2f", kelvinToFahrenheit(kelvin)); writefln("R %2.2f", kelvinToRankine(kelvin)); } else writefln("%2.2f K is below absolute zero", kelvin); }
}</lang>
- Output:
K 21.00 C -252.15 F -421.87 R 37.80
J
Solution:<lang j> NB. Temp conversions are all linear polynomials
K2K =: 0 1 NB. K = (1 *k) + 0 K2C =: _273 1 NB. C = (1 *k) - 273 K2F =: _459.67 1.8 NB. F = (1.8*k) - 459.67 K2R =: 0 1.8 NB. R = (1.8*k) + 0
NB. Do all conversions at once (eval NB. polynomials in parallel). This is the NB. numeric matrix J programs would manipulate NB. directly. k2KCFR =: (K2K , K2C , K2F ,: K2R) p./ ]</lang>
Example:<lang j> NB. Format matrix for printing
fmt =: '0.2' 8!:0 k2KCFR
NB. Tag each temp with scale, for human NB. legibility. kcfr =: 0 _1 |: 'KCFR' ,"0 1"_1 >@:fmt kcfr 21
K 21.00 C-252.00 F-421.87 R 37.80
kcfr 0 NB. Absolute zero
K 0.00 C-273.00 F-459.67 R 0.00
kcfr 21 100 300 NB. List of temps works fine
K 21.00 C-252.00 F-421.87 R 37.80
K 100.00 C-173.00 F-279.67 R 180.00
K 300.00 C 27.00 F 80.33 R 540.00
</lang>
Notes: The approach is founded on polynomials, one for each conversion (e.g. Fahrenheit = 1.8*x - 459.67 where x is measured in degrees Kelvin), and all polynomials are evaluated simultaneously using the built-in p.. Through some code decorations (specifically the / in p./ the "0 1"_1 and the 0 _1 |:), we permit our function to convert arrays of temperatures of arbitrarily high dimension (a single temp, lists of temps, tables of temps, cubes of temps, etc).
Java
<lang java>public class TemperatureConversion {
public static void main(String args[]) { if (args.length == 1) { try { double kelvin = Double.parseDouble(args[0]); if (kelvin >= 0) { System.out.printf("K %2.2f\n", kelvin); System.out.printf("C %2.2f\n", kelvinToCelcius(kelvin)); System.out.printf("F %2.2f\n", kelvinToFahrenheit(kelvin)); System.out.printf("R %2.2f\n", kelvinToRankine(kelvin)); } else { System.out.printf("%2.2f K is below absolute zero", kelvin); } } catch (NumberFormatException e) { System.out.println(e); } } }
public static double kelvinToCelcius(double k) { return k + 273.15; }
public static double kelvinToFahrenheit(double k) { return k * 1.8 - 459.67; }
public static double kelvinToRankine(double k) { return k * 1.8; }
}</lang>
K 21.00 C -252.15 F -421.87 R 37.80
PHP
<lang php>error_reporting(E_ALL & ~ ( E_NOTICE | E_WARNING ));
while (true) {
echo "\nEnter a value in kelvin (q to quit): "; if (($kelvin = trim(fgets(STDIN))) !== false) { if ($kelvin == 'q') { echo 'quitting'; break; } if (is_numeric($kelvin)) { $kelvin = floatVal($kelvin); if ($kelvin >= 0) { printf(" K %2.2f\n", $kelvin); printf(" C %2.2f\n", $kelvin - 273.15); printf(" F %2.2f\n", $kelvin * 1.8 - 459.67); printf(" R %2.2f\n", $kelvin * 1.8); } else printf(" %2.2f K is below absolute zero\n", $kelvin); } }
}</lang>
Enter a value in kelvin (q to quit): 21 K 21.00 C -252.15 F -421.87 R 37.80 Enter a value in kelvin (q to quit): q quitting
Python
<lang python>>>> while True: k = float(input('K ? ')) print("%g Kelvin = %g Celsius = %g Fahrenheit = %g Rankine degrees." % (k, k - 273.15, k * 1.8 - 459.67, k * 1.8))
K ? 21.0
21 Kelvin = -252.15 Celsius = -421.87 Fahrenheit = 37.8 Rankine degrees.
K ? 222.2
222.2 Kelvin = -50.95 Celsius = -59.71 Fahrenheit = 399.96 Rankine degrees.
K ? </lang>
Python: Universal conversion
This converts from any one of the units to all the others <lang python>>>> toK = {'C': (lambda c: c + 273.15),
'F': (lambda f: (f + 459.67) / 1.8), 'R': (lambda r: r / 1.8), 'K': (lambda k: k) }
>>> while True: magnitude, unit = input('<value> <K/R/F/C> ? ').split() k = toK[unit](float(magnitude)) print("%g Kelvin = %g Celsius = %g Fahrenheit = %g Rankine degrees." % (k, k - 273.15, k * 1.8 - 459.67, k * 1.8))
<value> <K/R/F/C> ? 222.2 K
222.2 Kelvin = -50.95 Celsius = -59.71 Fahrenheit = 399.96 Rankine degrees.
<value> <K/R/F/C> ? -50.95 C
222.2 Kelvin = -50.95 Celsius = -59.71 Fahrenheit = 399.96 Rankine degrees.
<value> <K/R/F/C> ? -59.71 F
222.2 Kelvin = -50.95 Celsius = -59.71 Fahrenheit = 399.96 Rankine degrees.
<value> <K/R/F/C> ? 399.96 R
222.2 Kelvin = -50.95 Celsius = -59.71 Fahrenheit = 399.96 Rankine degrees.
<value> <K/R/F/C> ? </lang>
REXX
This REXX version supports:
- (alternate spellings with optional degrees):
- Centingrade, centesimal, Celsius, Celcius
- Fahrenheit
- Kelvin
- Rankine
- Reaumur
- multiple temperatures in a list
- comments within the list
- aligned output (whole numbers and decimal fractions)
<lang rexx>/*REXX program converts units of temperature for: C, F, R, Re, K. */ parse arg tList /*get specified temperature lists*/
do until tList= /*process a list of temperatures.*/ parse var tList x ',' tList /*temps are separated by commas. */ x=space(x); parse var x z '(' /*handle any comments (if any). */ if z== then call serr 'no arguments were specified.' _ = verify(z, '+-.0123456789') /*all the legal number thingys. */
if _\==0 then do if _==1 then call serr 'illegal temperature:' # n= left(z,_-1) /*pick off the number (hopefully)*/ u= strip(substr(z,_)) /*pick off the temperature unit. */ end else u= 'k' /*assume Kelvin as per task req.*/
uU=u; upper uU /*uppercase version of temp unit.*/ if left(uU,7)=='DEGREES' then uU=substr(uU,8) /*reduntant "degrees"? */ if left(uU,5)=='DEGREE' then uU=substr(uU,7) /*reduntant "degree" ? */ uU=strip(uU) if \datatype(n,'N') then call serr 'illegal number:' n /*accept alternate spellings. */ select /*convert ───◄ common temperature*/ when abbrev('CENTIGRADE', uU) |, abbrev('CENTESIMAL', uU) |, abbrev('CELSIUS' , uU) |, abbrev('CELCIUS' , uU) then F = n * 1.8 + 32 when abbrev('FAHRENHEIT', uU) then F = n when abbrev('KELVIN' , uU) then F = n * 1.8 - 459.67 when abbrev('RANKINE' , uU) then F = n - 459.67 when abbrev('REAUMUR' , uU, 2) then F = n * 2.25 + 32 otherwise call serr 'illegal temperature scale:' u end /*select*/ say right(' ' x,55,"─") say Tform((F - 32) / 1.8 ) 'Celcius' say Tform( F ) 'Fahrenheit' say Tform((F + 459.67) * 1.8 ) 'Kelvin' say Tform( F + 459.67 ) 'Rankine' say Tform((F - 32 ) / 2.25 ) 'Reaumur' end /*until tlist=*/
exit /*stick a fork in it, we're done.*/ /*──────────────────────────────────TFORM subroutine────────────────────*/ Tform: procedure; showDig=3; _=format(arg(1),,showDig)/1; p=pos('.',_) if p==0 then _=_ || left(,showDig+1)
else _=_ || left(,showDig-length(_)+p); return right(_,20)
/*──────────────────────────────────SERR subroutine─────────────────────*/ serr: say; say '***error!***'; say; say arg(1); say; exit 13</lang> output when using the input of: -40C, 0 c (water freezes), 37C (body temp), 100 C (water boils), 21 degrees Kelvin, 0K (outer space?)
───────────────────────────────────────────────── -40C -40 Celcius -40 Fahrenheit 755.406 Kelvin 419.67 Rankine -32 Reaumur ────────────────────────────────── 0 c (water freezes) 0 Celcius 32 Fahrenheit 885.006 Kelvin 491.67 Rankine 0 Reaumur ────────────────────────────────────── 37C (body temp) 37 Celcius 98.6 Fahrenheit 1004.886 Kelvin 558.27 Rankine 29.6 Reaumur ────────────────────────────────── 100 C (water boils) 100 Celcius 212 Fahrenheit 1209.006 Kelvin 671.67 Rankine 80 Reaumur ──────────────────────────────────── 21 degrees Kelvin -252.15 Celcius -421.87 Fahrenheit 68.04 Kelvin 37.8 Rankine -201.72 Reaumur ──────────────────────────────────── 0K (outer space?) -273.15 Celcius -459.67 Fahrenheit 0 Kelvin 0 Rankine -218.52 Reaumur