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.

Task
Temperature conversion
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>

  1. 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.]