Temperature conversion
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.
You are encouraged to solve this task according to the task description, using any language you may know.
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
C
<lang c>#include <stdio.h>
- include <stdlib.h>
double kelvinToCelsius(double k){
return k - 273.15;
}
double kelvinToFahrenheit(double k){
return k * 1.8 - 459.67;
}
double kelvinToRankine(double k){
return k * 1.8;
} void convertKelvin(double kelvin) {
printf("K %.2f\n", kelvin); printf("C %.2f\n", kelvinToCelsius(kelvin)); printf("F %.2f\n", kelvinToFahrenheit(kelvin)); printf("R %.2f", kelvinToRankine(kelvin));
}
int main(int argc, const char * argv[]) {
if (argc > 1) { double kelvin = atof(argv[1]); convertKelvin(kelvin); } return 0;
}</lang>
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
МК-61/52
<lang>П7 0 , 8 * П8 ИП7 9 * 5 / 3 2 + П9 ИП7 2 7 3 , 1 5 + П4 С/П П8 1 , 8 / БП 00 П9 3 2 - 5 * 9 / БП 00 П4 2 7 3 , 1 5 - БП 00</lang>
Instruction:
tºC = РX В/О С/П;
tºRa = РX БП 25 С/П;
tºF = РX БП 32 С/П;
tK = РX БП 42 С/П;
Result:
РX = Р4 = tK;
Р7 = tºC;
Р8 = tºRa;
Р9 = tºF.
Perl 6
<lang perl6>while ne my $answer = prompt 'Temperature: ' {
my $k = do given $answer { when s/:i C $// { $_ + 273.15 } when s/:i F $// { ($_ + 459.67) / 1.8 } when s/:i R $// { $_ / 1.8 } when s/:i K $// { $_ } default { $_ } } say " { $k }K"; say " { $k - 273.15 }℃"; say " { $k * 1.8 - 459.67 }℉"; say " { $k * 1.8 }R";
}</lang>
- Output:
Temperature: 0 0K -273.15℃ -459.67℉ 0R Temperature: 0c 273.15K 0℃ 32℉ 491.67R Temperature: 212f 373.15K 100℃ 212℉ 671.67R Temperature: -40c 233.15K -40℃ -40℉ 419.67R
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
- Delisle
- Fahrenheit
- Kelvin
- Newton
- Rankine
- Reaumur, Réaumur
- Romer (Rømer), Roemer
- multiple temperatures in a list
- comments within the list
- aligned output (whole numbers and decimal fractions)
<lang rexx>/*REXX program converts temperature for: C, D, F, N, Ra, Re, Ro, and 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') /*a list of valid number thingys.*/ n=z if _\==0 then do if _==1 then call serr 'illegal temperature:' z 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=translate(u,'EE',"éÉ"); upper uU /*uppercase version of temp unit.*/ if left(uU,7)=='DEGREES' then uU=substr(uU,8) /*redundant "degrees"? */ if left(uU,5)=='DEGREE' then uU=substr(uU,7) /* " "degree" ? */ uU=strip(uU) if \datatype(n,'N') then call serr 'illegal number:' n /*accept alternate spellings. */ select /*convert ──► ºF temperatures. */ when abbrev('CENTIGRADE', uU) |, abbrev('CENTESIMAL', uU) |, abbrev('CELSIUS' , uU) |, abbrev('CELCIUS' , uU) then F=n * 9/5 + 32 when abbrev('DELISLE' , uU) then F=212 -(n * 6/5) when abbrev('FAHRENHEIT', uU) then F=n when abbrev('KELVIN' , uU) then F=n * 9/5 - 459.67 when abbrev('NEWTON' , uU) then F=n * 60/11 + 32 when abbrev('RANKINE' , uU) then F=n - 459.67 when abbrev('REAUMUR' , uU, 2) then F=n * 9/4 + 32 when abbrev('ROEMER' , uU, 2) |, abbrev('ROMER' , uU, 2) then F=(n-7.5) * 27/4 + 32 otherwise call serr 'illegal temperature scale:' u end /*select*/ say right(' ' x,55,"─") say Tform( ( F - 32 ) * 5/9 ) 'Celcius' say Tform( ( 212 - F ) * 5/6 ) 'Delisle' say Tform( F ) 'Fahrenheit' say Tform( ( F + 459.67 ) * 5/9 ) 'Kelvin' say Tform( ( F - 32 ) * 11/60 ) 'Newton' say Tform( F + 459.67 ) 'Rankine' say Tform( ( F - 32 ) * 4/9 ) 'Reaumur' say Tform( ( F - 32 ) * 7/24 + 7.5 ) 'Romer' end /*until tlist=*/
exit /*stick a fork in it, we're done.*/ /*──────────────────────────────────TFORM subroutine────────────────────*/ Tform: procedure; showDig=8; _=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 210 Delisle -40 Fahrenheit 233.15 Kelvin -13.2 Newton 419.67 Rankine -32 Reaumur -13.5 Romer ─────────────────────────────────────────────────── 0c 0 Celcius 150 Delisle 32 Fahrenheit 273.15 Kelvin 0 Newton 491.67 Rankine 0 Reaumur 7.5 Romer ────────────────────────────────────────────────── 37c 37 Celcius 94.5 Delisle 98.6 Fahrenheit 310.15 Kelvin 12.21 Newton 558.27 Rankine 29.6 Reaumur 26.925 Romer ───────────────────────────────────────────────── 100c 100 Celcius 0 Delisle 212 Fahrenheit 373.15 Kelvin 33 Newton 671.67 Rankine 80 Reaumur 60 Romer ────────────────────────────────────────────────── 21k -252.15 Celcius 528.225 Delisle -421.87 Fahrenheit 21 Kelvin -83.2095 Newton 37.8 Rankine -201.72 Reaumur -124.87875 Romer ─────────────────────────────────────────────────── 0k -273.15 Celcius 559.725 Delisle -459.67 Fahrenheit 0 Kelvin -90.1395 Newton 0 Rankine -218.52 Reaumur -135.90375 Romer
[Actually, water freezes at 0.000089º C, and boils at 99.974º C.]