Temperature conversion: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|REXX}}: output needs updating... -- ~~~~)
(→‎{{header|REXX}}: added other temperature scales to the REXX program, added a nit at the bottom of the output. -- ~~~~)
Line 240: Line 240:
* (alternate spellings with optional   ''degrees''):
* (alternate spellings with optional   ''degrees''):
** Centingrade, centesimal, Celsius, Celcius
** Centingrade, centesimal, Celsius, Celcius
** Delisle
** Fahrenheit
** Fahrenheit
** Kelvin
** Kelvin
** Newton
** Rankine
** Rankine
** Reaumur
** Reaumur, Réaumur
** Romer   (Romer)
* multiple temperatures in a list
* multiple temperatures in a list
* comments within the list
* comments within the list
* aligned output (whole numbers and decimal fractions)
* aligned output (whole numbers and decimal fractions)
<lang rexx>/*REXX program converts units of temperature for: C, F, R, Re, K. */
<lang rexx>/*REXX program converts temperature for: C, D, F, N, Ra, Re, Ro, and K.*/
parse arg tList /*get specified temperature lists*/
parse arg tList /*get specified temperature lists*/


Line 264: Line 267:


uU=u; upper uU /*uppercase version of temp unit.*/
uU=u; upper uU /*uppercase version of temp unit.*/
if left(uU,7)=='DEGREES' then uU=substr(uU,8) /*reduntant "degrees"? */
if left(uU,7)=='DEGREES' then uU=substr(uU,8) /*redundant "degrees"? */
if left(uU,5)=='DEGREE' then uU=substr(uU,7) /*reduntant "degree" ? */
if left(uU,5)=='DEGREE' then uU=substr(uU,7) /* " " ? */
uU=strip(uU)
uU=strip(uU)
if \datatype(n,'N') then call serr 'illegal number:' n
if \datatype(n,'N') then call serr 'illegal number:' n
/*accept alternate spellings. */
/*accept alternate spellings. */
select /*convert ───◄ common temperature*/
select /*convert ──► ºF temperatures. */
when abbrev('CENTIGRADE', uU) |,
when abbrev('CENTIGRADE', uU) |,
abbrev('CENTESIMAL', 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 * 9/5 + 32
when abbrev('FAHRENHEIT', uU) then F = n
when abbrev('DELISLE' , uU) then F=212 -(n * 6/5)
when abbrev('KELVIN' , uU) then F = n * 1.8 - 459.67
when abbrev('FAHRENHEIT', uU) then F=n
when abbrev('RANKINE' , uU) then F = n - 459.67
when abbrev('KELVIN' , uU) then F=n * 9/5 - 459.67
when abbrev('REAUMUR' , uU, 2) then F = n * 2.25 + 32
when abbrev('NEWTON' , uU) then F=n * 60/11 + 32
otherwise call serr 'illegal temperature scale:' u
when abbrev('RANKINE' , uU) then F=n - 459.67
end /*select*/
when abbrev('REAUMUR' , uU, 2) then F=n * 9/4 + 32
when abbrev('RéAUMUR' , uU, 2) |,
abbrev('RÉAUMUR' , uU, 2) |,
abbrev('REAUMUR' , uU, 2) then F=n * 9/4 + 32
when 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 right(' ' x,55,"─")
say Tform((F - 32) / 1.8 ) 'Celcius'
say Tform((F - 32) * 5/9 ) 'Celcius'
say Tform( F ) 'Fahrenheit'
say Tform((212-F) * 5/6 ) 'Delisle'
say Tform((F + 459.67) * 1.8 ) 'Kelvin'
say Tform( F ) 'Fahrenheit'
say Tform( F + 459.67 ) 'Rankine'
say Tform((F + 459.67) * 5/9 ) 'Kelvin'
say Tform((F - 32 ) / 2.25 ) 'Reaumur'
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=''*/
end /*until tlist=''*/


Line 297: Line 309:
'''output''' when using the input of: <tt> -40C, 0 c (water freezes), 37C (body temp), 100 C (water boils), 21 degrees Kelvin, 0K (outer space?) </tt>
'''output''' when using the input of: <tt> -40C, 0 c (water freezes), 37C (body temp), 100 C (water boils), 21 degrees Kelvin, 0K (outer space?) </tt>
<pre style="overflow:scroll">
<pre style="overflow:scroll">
───────────────────────────────────────────────── -40C

-40 Celcius
210 Delisle
-40 Fahrenheit
233.15 Kelvin
-13.2 Newton
419.67 Rankine
-32 Reaumur
-13.5 Romer
─────────────────────────────────── 0c (water freezes)
0 Celcius
150 Delisle
32 Fahrenheit
273.15 Kelvin
0 Newton
491.67 Rankine
0 Reaumur
7.5 Romer
────────────────────────────────────── 37C (body temp)
37 Celcius
94.5 Delisle
98.6 Fahrenheit
310.15 Kelvin
12.21 Newton
558.27 Rankine
29.6 Reaumur
26.925 Romer
─────────────────────────────────── 100c (water boils)
100 Celcius
0 Delisle
212 Fahrenheit
373.15 Kelvin
33 Newton
671.67 Rankine
80 Reaumur
60 Romer
──────────────────────────────────── 21 degrees Kelvin
-252.15 Celcius
528.225 Delisle
-421.87 Fahrenheit
21 Kelvin
-83.21 Newton
37.8 Rankine
-201.72 Reaumur
-124.879 Romer
──────────────────────────────────── 0K (outer space?)
-273.15 Celcius
559.725 Delisle
-459.67 Fahrenheit
0 Kelvin
-90.14 Newton
0 Rankine
-218.52 Reaumur
-135.904 Romer
</pre>
</pre>
[Actually, water freezes at 0.000089 ºC, &nbsp; and boils at 99.974 ºC.]
<br><br>

Revision as of 00:46, 14 February 2013

Temperature conversion is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

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
    • Delisle
    • Fahrenheit
    • Kelvin
    • Newton
    • Rankine
    • Reaumur, Réaumur
    • Romer   (Romer)
  • 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')       /*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)  /*redundant "degrees"? */
 if left(uU,5)=='DEGREE'  then uU=substr(uU,7)  /*    "         "    ? */
 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('RéAUMUR'   , uU, 2) |,
          abbrev('RÉAUMUR'   , uU, 2) |,
          abbrev('REAUMUR'   , uU, 2)    then F=n       *  9/4   +  32
     when 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=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
             210     Delisle
             -40     Fahrenheit
             233.15  Kelvin
             -13.2   Newton
             419.67  Rankine
             -32     Reaumur
             -13.5   Romer
───────────────────────────────────  0c (water freezes)
               0     Celcius
             150     Delisle
              32     Fahrenheit
             273.15  Kelvin
               0     Newton
             491.67  Rankine
               0     Reaumur
               7.5   Romer
──────────────────────────────────────  37C (body temp)
              37     Celcius
              94.5   Delisle
              98.6   Fahrenheit
             310.15  Kelvin
              12.21  Newton
             558.27  Rankine
              29.6   Reaumur
              26.925 Romer
───────────────────────────────────  100c (water boils)
             100     Celcius
               0     Delisle
             212     Fahrenheit
             373.15  Kelvin
              33     Newton
             671.67  Rankine
              80     Reaumur
              60     Romer
────────────────────────────────────  21 degrees Kelvin
            -252.15  Celcius
             528.225 Delisle
            -421.87  Fahrenheit
              21     Kelvin
             -83.21  Newton
              37.8   Rankine
            -201.72  Reaumur
            -124.879 Romer
────────────────────────────────────  0K (outer space?)
            -273.15  Celcius
             559.725 Delisle
            -459.67  Fahrenheit
               0     Kelvin
             -90.14  Newton
               0     Rankine
            -218.52  Reaumur
            -135.904 Romer

[Actually, water freezes at 0.000089 ºC,   and boils at 99.974 ºC.]