# Heat_Index calculation in my C program; question about formula

Discussion in 'C Programming' started by Barry L. Bond, Oct 25, 2008.

1. ### Barry L. BondGuest

Greetings!

I just got a new Peet Brothers Ultimeter 2100 Weather Station. This
new one has a way to display the heat index, if you press the "dew point"
key twice.

Being aware of all the controversy surrounding the exact calculation
of the heat index, I would like my own software (which I programmed in the
1990's, when I got their Ultimeter 2000 weather station, but that one
didn't show heat index) to display it. Living in Florida, when it's hot,
in particular, I wouldn't mind knowing what it is, even if I'm not close
to the actual weather station mounted in my office to press the "d.p." key
twice. (My software shows all the current and daily record weather
conditions, updated twice a minute.)

Here is the heat index formula:

<<>>
-42.379 + 2.04901523T + 10.14333127R - 0.22475541TR - 6.83783x10-3T2 - 5.481717x10-2R2 + 1.22874x10-3T2R + 8.5282x10-4TR2 - 1.99x10-6T2R2
<<>>

And, here is the line in my C program:

<<>>
Heat_Index = (-42.379) + (2.04901523 * Temperature) +
(10.14333127 * Humidity) -
(0.22475541 * Temperature * Humidity) -
(6.83783 * powf (10.0, -3) * powf (Temperature, 2)) -
(5.481717 * powf (10.0, -2) * powf (Humidity, 2)) +
(1.22874 * powf (10.0, -3) * powf (Temperature, 2) *
Humidity) + (8.5282 * powf (10.0, -4) * Temperature *
powf (Humidity, 2)) - (1.99 * powf (10.0, -6) *
powf (Temperature, 2) * powf (Humidity, 2));
<<>>

Don't laugh! :-D

Temperature and Humidity are correct, as I've viewed it in gdb. It's
probably not surprising that I'm NOT getting what the weather station is
getting for the heat index.

I'm not mathematically educated, so I'll bet there is something that
I'm not properly capturing from the above formula in my C code.

Especially where it says things like "1.99x10-6T2R2".

I am thinking the "times Temperature squared and times humidity
squared" is probably okay, but that "x10-6" part, I'm not sure that's
right. Since there is no variable there, why wouldn't they just modify
the number before the "x"?

Anyway, if anyone doesn't mind talking with extreme patience to
someone who truly doesn't know whether what I have is right (but I know
it's not getting the correct amount), what should I do?

You don't have to rewrite the whole statement. If you could just tell
me how I handle things like the "1.99x10-6T2R2", I expect I would be able
to do the other "x" portions appropriate!

Thank you!

Barry
--
Barry L. Bond | http://home.cfl.rr.com/os9barry/
Software Engineer, ITT Corporation | (My personal home web page, last
bbondATcfl.rr.com | updated February 17, 2005)

Barry L. Bond, Oct 25, 2008

2. ### PaulGuest

Barry L. Bond wrote:
> Greetings!
>
> I just got a new Peet Brothers Ultimeter 2100 Weather Station. This
> new one has a way to display the heat index, if you press the "dew point"
> key twice.
>
> Being aware of all the controversy surrounding the exact calculation
> of the heat index, I would like my own software (which I programmed in the
> 1990's, when I got their Ultimeter 2000 weather station, but that one
> didn't show heat index) to display it. Living in Florida, when it's hot,
> in particular, I wouldn't mind knowing what it is, even if I'm not close
> to the actual weather station mounted in my office to press the "d.p." key
> twice. (My software shows all the current and daily record weather
> conditions, updated twice a minute.)
>
> Here is the heat index formula:
>
> <<>>
> -42.379 + 2.04901523T + 10.14333127R - 0.22475541TR - 6.83783x10-3T2 - 5.481717x10-2R2 + 1.22874x10-3T2R + 8.5282x10-4TR2 - 1.99x10-6T2R2
> <<>>
>
> And, here is the line in my C program:
>
> <<>>
> Heat_Index = (-42.379) + (2.04901523 * Temperature) +
> (10.14333127 * Humidity) -
> (0.22475541 * Temperature * Humidity) -
> (6.83783 * powf (10.0, -3) * powf (Temperature, 2)) -
> (5.481717 * powf (10.0, -2) * powf (Humidity, 2)) +
> (1.22874 * powf (10.0, -3) * powf (Temperature, 2) *
> Humidity) + (8.5282 * powf (10.0, -4) * Temperature *
> powf (Humidity, 2)) - (1.99 * powf (10.0, -6) *
> powf (Temperature, 2) * powf (Humidity, 2));
> <<>>
>
> Don't laugh! :-D
>
> Temperature and Humidity are correct, as I've viewed it in gdb. It's
> probably not surprising that I'm NOT getting what the weather station is
> getting for the heat index.
>
> I'm not mathematically educated, so I'll bet there is something that
> I'm not properly capturing from the above formula in my C code.
>
> Especially where it says things like "1.99x10-6T2R2".
>
> I am thinking the "times Temperature squared and times humidity
> squared" is probably okay, but that "x10-6" part, I'm not sure that's
> right. Since there is no variable there, why wouldn't they just modify
> the number before the "x"?
>
> Anyway, if anyone doesn't mind talking with extreme patience to
> someone who truly doesn't know whether what I have is right (but I know
> it's not getting the correct amount), what should I do?
>
> You don't have to rewrite the whole statement. If you could just tell
> me how I handle things like the "1.99x10-6T2R2", I expect I would be able
> to do the other "x" portions appropriate!
>
> Thank you!
>
> Barry

Page 41 has the equation. Checked second doc for units for TEMP and HUMIDITY.

http://gis.esri.com/library/userconf/health07/docs/use_of_gis-based.pdf
http://www.srh.noaa.gov/ffc/html/studies/ta_htindx.PDF

Assuming no transcription errors, I read the equation this way.

-42.40 +
(2.04901523 * TEMP) +
(10.14333127 * HUMIDITY) -
(0.22475541 * TEMP * HUMIDITY) -
(0.00683783 * TEMP * TEMP) -
(0.05481717 * HUMIDITY * HUMIDITY) +
(0.00122874 * TEMP * TEMP * HUMIDITY) +
(0.00085282 * TEMP * HUMIDITY * HUMIDITY) -
(0.00000199 * TEMP * TEMP * HUMIDITY * HUMIDITY)

TEMP = ambient dry bulb temperature in degrees Farenheit
HUMIDITY = relative humidity as integer percentage 0..100

If it still doesn't work for you, include a sample (TEMP, HUMIDITY, HI)
result so there is something to debug with.

HTH,
Paul

Paul, Oct 25, 2008

3. ### Barry L. BondGuest

Hi Richard!

>Although my system doesn't have a powf function, I presume it's a float
>equivalent of pow. So I wrote my own float equivalent of pow, and compared
>float calcs against double calcs, for temperatures in the range 0 to 30
>(varying by 0.1) and humidities in the range 0-100 (varying by 1.0). Most
>of the time, there was remarkably little difference between the two -
>quite a few zeros after the point - but occasionally there were what I
>would term minor discrepancies - e.g. T=5.2 H=83 gives a difference of
>0.000030517578125 between a float calc and a double calc of the above
>equation.

Yes. I found a man page for powf, that's what it is.

>You might want to give some example data, and tell us what results the
>weather station gets for those data and what results your program gets for
>the same data.

Ah! Okay.

Running it just now, with 74.5999985 F as the temp and 88.5% as the
humidity, the Heat_Index is 73.6352844. The Weather Station currently shows
79 F.

(Actually, I just noticed I'm making a one decimal point placement
error in the displaying of it, so it actually isn't as far off as I
thought earlier! But, it is still different from what the weather
station reports for Heat Index.)

>Is the equation generally accepted? Is your version an approximation? Is
>theirs? Are the constants considered canonical, or are they merely
>suggestions?

Yes. In fact, I was given three URLs from Peet Brothers, and one of
the URLs is the exact same page as the second link in Paul's reply to my
article. I printed that one side/both sides of paper, and I'm looking at
exactly that same text.

They said they used exactly the same calculation to calculate the
heat index in their Ultimeter 2100 as that very URL.

Merely suggestions, I'd say. But, I was rather wanting to see it,
again, especially when it was 95+ and high humidity, as we have a lot in
our summer months in Florida.

>No, that's fine - it's just a way of expressing numbers in a consistent
>format. The idea is that any (real) number that can be expressed in a
>finite number of decimals can also be expressed in this way:

>optional sign
>value in the range [1.0, 10.0)... the notation here means that 10.0 itself
>isn't part of the range
>multiplication sign
>optional sign
>exponent

>This is so well-established that the C language has a notation for it.
>Instead of writing (6.83783 * powf (10.0, -3)), for example, you can just
>write (6.83783E-3), where - in this context - E stands for "times ten to
>the power of".

Ah! That makes sense! Thank you for your kind and patient help!

Barry
--
Barry L. Bond | http://home.cfl.rr.com/os9barry/
Software Engineer, ITT Corporation | (My personal home web page, last
bbondATcfl.rr.com | updated February 17, 2005)

Barry L. Bond, Oct 25, 2008
4. ### Barry L. BondGuest

Hi Paul!

>Page 41 has the equation. Checked second doc for units for TEMP and HUMIDITY.

The second URL is exactly the same PDF file that Peet Brothers
emailed me, and they said they used the exact same calculation to get
their heat index.

>Assuming no transcription errors, I read the equation this way.

>-42.40 +
>(2.04901523 * TEMP) +
>(10.14333127 * HUMIDITY) -
>(0.22475541 * TEMP * HUMIDITY) -
>(0.00683783 * TEMP * TEMP) -
>(0.05481717 * HUMIDITY * HUMIDITY) +
>(0.00122874 * TEMP * TEMP * HUMIDITY) +
>(0.00085282 * TEMP * HUMIDITY * HUMIDITY) -
>(0.00000199 * TEMP * TEMP * HUMIDITY * HUMIDITY)

>TEMP = ambient dry bulb temperature in degrees Farenheit
>HUMIDITY = relative humidity as integer percentage 0..100

Yes, that's how I'm reading it, thanks to what Richard posted!

>If it still doesn't work for you, include a sample (TEMP, HUMIDITY, HI)
>result so there is something to debug with.

Something I just gave Richard, Temperature 74.5999985 and Humidity
88.5% gives 73.6352844. The weather station gives 79. (It rounds to the
nearest degree in what it displays. But, for things that it gives to my
software, most things are one decimal point.)

Barry
--
Barry L. Bond | http://home.cfl.rr.com/os9barry/
Software Engineer, ITT Corporation | (My personal home web page, last
bbondATcfl.rr.com | updated February 17, 2005)

Barry L. Bond, Oct 25, 2008
5. ### GeorgeGuest

On Sat, 25 Oct 2008 08:31:41 +0000, Richard Heathfield wrote:

> Barry L. Bond said:
>
> <snip>
>
>> Running it just now, with 74.5999985 F as the temp and 88.5% as the
>> humidity, the Heat_Index is 73.6352844. The Weather Station currently
>> shows 79 F.

>
> Using double, I get 73.63526917-. Using float, I get 73.63528442+, which
> matches your result. The difference is 0.000015258789062.
>
> Without knowing what the proper result should be, I don't see what other
> help I can give.

I'd be curious to see your source. I have a similar project.
--
George

The action we take and the decisions we make in this decade will have
consequences far into this century. If America shows weakness and
uncertainty, the world will drift toward tragedy. That will not happen on
my watch.
George W. Bush

George, Oct 25, 2008
6. ### Keith ThompsonGuest

(Barry L. Bond) writes:
[...]
> Here is the heat index formula:
>
> <<>>
> -42.379 + 2.04901523T + 10.14333127R - 0.22475541TR - 6.83783x10-3T2 - 5.481717x10-2R2 + 1.22874x10-3T2R + 8.5282x10-4TR2 - 1.99x10-6T2R2
> <<>>
>
> And, here is the line in my C program:
>
> <<>>
> Heat_Index = (-42.379) + (2.04901523 * Temperature) +
> (10.14333127 * Humidity) -
> (0.22475541 * Temperature * Humidity) -
> (6.83783 * powf (10.0, -3) * powf (Temperature, 2)) -
> (5.481717 * powf (10.0, -2) * powf (Humidity, 2)) +
> (1.22874 * powf (10.0, -3) * powf (Temperature, 2) *
> Humidity) + (8.5282 * powf (10.0, -4) * Temperature *
> powf (Humidity, 2)) - (1.99 * powf (10.0, -6) *
> powf (Temperature, 2) * powf (Humidity, 2));
> <<>>

[...]

None of your calls to powf() are necessary. In 5 places, you use it
where a floating-point constant would be clearer:

6.83783 * powf (10.0, -3) should be 6.83783e-3
5.481717 * powf (10.0, -2) should be 5.481717e-2
and so forth

The other calls all use an exponent of 2, i.e., you're just computing
the square of a number. IMHO it would be clearer to write
"Humidity*Humidity" rather than powf (Humidity, 2). And since both
Humidity*Humidity and Temperature*Temperature are used several times,
I'd probably compute them separately:

const double Humidity_Squared = Humidity * Humidity;
const double Temperature_Squared = Temperature * Temperature;

Make sure Heat_Index, Humidity, and Temperature are all declared as
type double.

Here's my version of the formula. (Note that it matches the formula

Heat_Index = -42.379
+ 2.04901523 * Temperature
+ 10.14333127 * Humidity
- 0.22475541 * Temperature * Humidity
- 6.83783e-3 * Temperature_Squared
- 5.481717e-2 * Humidity_Squared
+ 1.22874e-3 * Temperature_Squared * Humidity
+ 8.5282e-4 * Temperature * Humidity_Squared
- 1.99e-6 * Temperature_Squared * Humidity_Squared;

Note that arranged the expression so that each term is on a line by
itself. I've also dropped all the parentheses, taking advantage of
the fact that "*" binds more tightly than "+" and "-". Adding
parentheses to complicated expressions in C often adds clarity, but in
this case the precedence is sufficiently well known that parentheses

Here's another version of the same formula, which more closely follows
the mathematical form as given on the Wikipedia page; I find it
clearer than the above:

/* T is temperature in degrees Fahrenheit,
* R is relative humidity in percent
*/
double Heat_Index(double T, double R)
{
const double C1 = -42.379;
const double C2 = 2.04901523;
const double C3 = 10.14333127;
const double C4 = -0.22475541;
const double C5 = -6.83783e-3;
const double C6 = -5.481717e-2;
const double C7 = 1.22874e-3;
const double C8 = 8.5282e-4;
const double C9 = -1.99e-6;
return C1 + C2*T + C3*R + C4*T*R + C5*T*T + C6*R*R +
C7*T*T*R + C8*T*R*R + C9*T*T*R*R;
}

--
Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Keith Thompson, Oct 25, 2008
7. ### Tim PrinceGuest

Keith Thompson wrote:

> return C1 + C2*T + C3*R + C4*T*R + C5*T*T + C6*R*R +
> C7*T*T*R + C8*T*R*R + C9*T*T*R*R;

more efficient would be a grouping of terms such as
C1 + T*(C2 + T*(C5 + R*(C7 + C9*R)) + R*(C4 + C8*R)) + R*(C3 + C6*R)

The lack of an exponentiation operator in C, the existence of Horner's
rule, and the explicit allowance for such regrouping in the standards
for certain other programming languages, all should point in this direction.

Tim Prince, Oct 25, 2008
8. ### Keith ThompsonGuest

Tim Prince <> writes:
> Keith Thompson wrote:
>
>> return C1 + C2*T + C3*R + C4*T*R + C5*T*T + C6*R*R +
>> C7*T*T*R + C8*T*R*R + C9*T*T*R*R;

> more efficient would be a grouping of terms such as
> C1 + T*(C2 + T*(C5 + R*(C7 + C9*R)) + R*(C4 + C8*R)) + R*(C3 + C6*R)
>
> The lack of an exponentiation operator in C, the existence of Horner's
> rule, and the explicit allowance for such regrouping in the standards
> for certain other programming languages, all should point in this
> direction.

The greater complexity and obscurity of your version, the fact that
compilers are likely to perform common subexpression optimizations
(e.g., computing T*T and R*R only once) should point away from your
version and in the direction of greater clarity. Unless the
computation is time-critical, and this change improves performance
measurably.

--
Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Keith Thompson, Oct 25, 2008
9. ### Barry L. BondGuest

Hi again, Richard!

>> Running it just now, with 74.5999985 F as the temp and 88.5% as the
>> humidity, the Heat_Index is 73.6352844. The Weather Station currently
>> shows 79 F.

>Using double, I get 73.63526917-. Using float, I get 73.63528442+, which
>matches your result. The difference is 0.000015258789062.

Thank you. I will be changing it, to use the E- notation,
etc. However it is good to know that you're getting the same thing, or
close enough!

>Without knowing what the proper result should be, I don't see what other
>help I can give.

Oh, I'm sorry.

Peet Brothers emailed me 3 URLs, and the second URL is the 2-page PDF
file (that perfectly matches Paul's second URL he posted). They said that
they used that exact calculation for the Ultimeter 2100. So, they (said
that they) use the exact same calculation.

I'm not sure what to think now... but at least my Heat_Index appears
to be "working", though I now know a couple of improvements!

Barry
--
Barry L. Bond | http://home.cfl.rr.com/os9barry/
Software Engineer, ITT Corporation | (My personal home web page, last
bbondATcfl.rr.com | updated February 17, 2005)

Barry L. Bond, Oct 26, 2008
10. ### Barry L. BondGuest

Hi George!

>I'd be curious to see your source. I have a similar project.

Oh boy. While I have many things I wouldn't mind other people
seeing the source code, this one isn't one of them! :-D

Still, though, it DOES work. (I was going to add some things and
improve it from writing it in the 1990's, but I just haven't gotten to
it.) :-O It DOES work, and I actually run it frequently, and especially
when there is any sort of "weather emergency" or situation that is like to
have some weather item different.

If you can give me an email address that would work for you, I'll
email it to you. I have no reason not to share it, since you explicitly

You can do whatever you want to "mess up" the email (so it can't be
grabbed by software scanning USENET posts) but still be usable to me, such
as the way I do my email address at the end.

Barry
--
Barry L. Bond | http://home.cfl.rr.com/os9barry/
Software Engineer, ITT Corporation | (My personal home web page, last
bbondATcfl.rr.com | updated February 17, 2005)

Barry L. Bond, Oct 26, 2008
11. ### Barry L. BondGuest

Hi Gordon!

>There's also a heat index calculator on the web page which you can
>use to check against your formula. I took your formula and put it
>on an OpenOffice spreadsheet, and the two seem to match.

Ah! Great idea! Thank you! Yes, I'll do that!

>1. I hope Temperature and Humidity are declared float or double.

They are declared float.

>2. I would have calculated everything in doubles. Unless proved
> by benchmarking, there isn't that much difference on modern
> hardware.

I actually agree and am more doing things that way, now. I am now
making the minor modification to this source code in styles and ways that
are NOT the way I do new source code now, but it was the way I did it a

> The second argument of powf() is a float, not an integer, yet you
> pass it an integer. If you don't have a declaration of powf() in
> scope (and didn't include <math.h>), you could get complete garbage.
> If you do have a correct declaration of powf() in scope, you should
> be OK.

Thank you! I hadn't realized that!

I am including <math.h> and I'm not getting garbage, but thank you
for bringing that to my attention.

(But, when I recode it, I'll no longer be using the powf function at
all.)

>4. At a quick glance, your translation of the formula into C matches
> the one on the web page.

Thank you. I'm getting other comments that agree.

I failed to mention this in my original posting, but have mentioned
it in a few replies by now, but Peet Brothers emailed me that they were
using the exact same calculation in their calculation of heat index which
their Ultimeter 2100 does. So, when I say I'm not getting what they are
getting, that's among my reasons for wondering whether I was doing
something wrong.

>5. I would have manually calculated some of the powers of 10 in my
> head and avoided calls to powf(). Also, Temperature*Temperature
> is probably clearer than powf(Temperature,2).

And, now that I know how (thanks to several postings already), I'll
be doing that, too!

>Give us some test data.

Here's one I gave from my gdb debugging early this morning:

Running it just now, with 74.5999985 F as the temp and 88.5% as the
humidity, the Heat_Index is 73.6352844. The Weather Station currently
shows 79 F.

getting pretty well what I am getting.

>When you're copying numbers like .000000000000000005551212 around,
>it's easy to mis-count the zeroes, so they use exponential notation.

Thank you! I am seeing a couple of advantages to that notation,
now!

Thank you for your time and help!

Barry
--
Barry L. Bond | http://home.cfl.rr.com/os9barry/
Software Engineer, ITT Corporation | (My personal home web page, last
bbondATcfl.rr.com | updated February 17, 2005)

Barry L. Bond, Oct 26, 2008
12. ### Barry L. BondGuest

Hi Keith!

Thank you VERY much for your time and clear help!

>None of your calls to powf() are necessary. In 5 places, you use it
>where a floating-point constant would be clearer:

> 6.83783 * powf (10.0, -3) should be 6.83783e-3
> 5.481717 * powf (10.0, -2) should be 5.481717e-2
> and so forth

I agree with what you've posted, and when I make my next
modification, I'll be doing exactly what you indicate, above and what I am
not quoting in this reply! (Now that I know what they are! Other
wonderful postings as well as yours have shown me what that is!)

Thank you again!

Barry
--
Barry L. Bond | http://home.cfl.rr.com/os9barry/
Software Engineer, ITT Corporation | (My personal home web page, last
bbondATcfl.rr.com | updated February 17, 2005)

Barry L. Bond, Oct 26, 2008
13. ### Peter NilssonGuest

(Barry L. Bond) wrote:
>      Running it just now, with 74.5999985 F as the
> temp and 88.5% as the humidity, the Heat_Index is
> 73.6352844.  The Weather Station currently shows
> 79 F.

Probably because it's using the 'better' formula.
[cf <http://en.wikipedia.org/wiki/Heat_index>]

#include <stdio.h>

int main(void)
{
double t = 74.599985;
double r = 88.5;
double hi1 =
- 4.2379E1
+ 2.04901523 * t
+ 1.014333127E1 * r
- 0.22475541 * t * r
- 6.83783E-3 * t * t
- 5.481717E-2 * r * r
+ 1.22874E-3 * t * t * r
+ 8.5282E-4 * t * r * r
- 1.99E-6 * t * t * r * r;
double hi2 = 0;
double tv[4];
double m[4][4] =
{
{ 1.6923E1, 5.37941, 7.28898E-3, 2.91583E-5 },
{ 1.85212E-1, -1.00254E-1, -8.14971E-4, 1.97483E-7 },
{ 9.41695E-3, 3.45372E-4, 1.02102E-5, 8.43296E-10 },
{ -3.8646E-5, 1.42721E-6, -2.18429E-8, -4.81975E-11 }
};
double x[4];
double rv[4] = { 0 };
int c, i;

tv[0] = 1;
tv[1] = t;
tv[2] = t * t;
tv[3] = t * t * t;

rv[0] = 1;
rv[1] = r;
rv[2] = r * r;
rv[3] = r * r * r;

for (i = 0; i < 4; i++)
for (c = 0; c < 4; c++)
x += tv[c] * m[c];

for (i = 0; i < 4; i++)
hi2 += x * rv;

printf("%f\n", hi1);
printf("%f\n", hi2);

return 0;
}

--
Peter

Peter Nilsson, Oct 26, 2008
14. ### Peter NilssonGuest

[Apologies if I post twice on this. I can't see my
first attempt at posting which, from Google, is
normally immediate.]

(Barry L. Bond) wrote:
>      Running it just now, with 74.5999985 F as the
> temp and 88.5% as the humidity, the Heat_Index is
> 73.6352844.  The Weather Station currently shows
> 79 F.

The 'more accurate forumla' from...

http://en.wikipedia.org/wiki/Heat_index

....yields 78.5, which may explain the Weather Station
calculation.

--
Peter

Peter Nilsson, Oct 27, 2008
15. ### GeorgeGuest

On Sat, 25 Oct 2008 11:12:26 -0700, Keith Thompson wrote:

> Tim Prince <> writes:
>> Keith Thompson wrote:
>>
>>> return C1 + C2*T + C3*R + C4*T*R + C5*T*T + C6*R*R +
>>> C7*T*T*R + C8*T*R*R + C9*T*T*R*R;

>> more efficient would be a grouping of terms such as
>> C1 + T*(C2 + T*(C5 + R*(C7 + C9*R)) + R*(C4 + C8*R)) + R*(C3 + C6*R)
>>
>> The lack of an exponentiation operator in C, the existence of Horner's
>> rule, and the explicit allowance for such regrouping in the standards
>> for certain other programming languages, all should point in this
>> direction.

>
> The greater complexity and obscurity of your version, the fact that
> compilers are likely to perform common subexpression optimizations
> (e.g., computing T*T and R*R only once) should point away from your
> version and in the direction of greater clarity. Unless the
> computation is time-critical, and this change improves performance
> measurably.

OP seems to be happy, but I am not with your aspersions to Tim.

#include <stdio.h>

int main(void)
{
double t = 74.599985;
double r = 88.5;
double hi1 =
- 4.2379E1
+ 2.04901523 * t
+ 1.014333127E1 * r
- 0.22475541 * t * r
- 6.83783E-3 * t * t
- 5.481717E-2 * r * r
+ 1.22874E-3 * t * t * r
+ 8.5282E-4 * t * r * r
- 1.99E-6 * t * t * r * r;
double hi2 = 0;
double tv[4];
double m[4][4] =
{
{ 1.6923E1, 5.37941, 7.28898E-3, 2.91583E-5 },
{ 1.85212E-1, -1.00254E-1, -8.14971E-4, 1.97483E-7 },
{ 9.41695E-3, 3.45372E-4, 1.02102E-5, 8.43296E-10 },
{ -3.8646E-5, 1.42721E-6, -2.18429E-8, -4.81975E-11 }
};
double x[4];
double rv[4] = { 0 };
int c, i;

tv[0] = 1;
tv[1] = t;
tv[2] = t * t;
tv[3] = t * t * t;

rv[0] = 1;
rv[1] = r;
rv[2] = r * r;
rv[3] = r * r * r;

for (i = 0; i < 4; i++)
for (c = 0; c < 4; c++)
x += tv[c] * m[c];

for (i = 0; i < 4; i++)
hi2 += x * rv;

printf("%f\n", hi1);
printf("%f\n", hi2);

return 0;
}

I'll have to get a C compiler to know my own ass from a warm spot.
--
George

Faith crosses every border and touches every heart in every nation.
George W. Bush

George, Oct 27, 2008
16. ### user923005Guest

On Oct 25, 11:12 am, Keith Thompson <> wrote:
> Tim Prince <> writes:
> > Keith Thompson wrote:

>
> >>     return C1 + C2*T + C3*R + C4*T*R + C5*T*T + C6*R*R +
> >>            C7*T*T*R + C8*T*R*R + C9*T*T*R*R;

> > more efficient would be a grouping of terms such as
> > C1 + T*(C2 + T*(C5 + R*(C7 + C9*R)) + R*(C4 + C8*R)) + R*(C3 + C6*R)

>
> > The lack of an exponentiation operator in C, the existence of Horner's
> > rule, and the explicit allowance for such regrouping in the standards
> > for certain other programming languages, all should point in this
> > direction.

>
> The greater complexity and obscurity of your version, the fact that
> compilers are likely to perform common subexpression optimizations
> (e.g., computing T*T and R*R only once) should point away from your
> version and in the direction of greater clarity.  Unless the
> computation is time-critical, and this change improves performance
> measurably.

Horner's rule is so well known, I would argue that neither version is
more obscure than the other.
I would definitely have programmed the Horner's rule version myself,
unless there were some powerful reason given not to do that.

user923005, Oct 27, 2008
17. ### Peter NilssonGuest

Keith Thompson <> wrote:
> (Barry L. Bond) writes:
> [...]
> >      Here is the heat index formula:

> ...
> Here's my version of the formula.  (Note that it matches

Note that the weather station in question appears to be
using the 'more accurate formula'.

--
Peter

Peter Nilsson, Oct 27, 2008
18. ### user923005Guest

On Oct 25, 11:12 am, Keith Thompson <> wrote:
> Tim Prince <> writes:
> > Keith Thompson wrote:

>
> >>     return C1 + C2*T + C3*R + C4*T*R + C5*T*T + C6*R*R +
> >>            C7*T*T*R + C8*T*R*R + C9*T*T*R*R;

> > more efficient would be a grouping of terms such as
> > C1 + T*(C2 + T*(C5 + R*(C7 + C9*R)) + R*(C4 + C8*R)) + R*(C3 + C6*R)

>
> > The lack of an exponentiation operator in C, the existence of Horner's
> > rule, and the explicit allowance for such regrouping in the standards
> > for certain other programming languages, all should point in this
> > direction.

>
> The greater complexity and obscurity of your version, the fact that
> compilers are likely to perform common subexpression optimizations
> (e.g., computing T*T and R*R only once) should point away from your
> version and in the direction of greater clarity.  Unless the
> computation is time-critical, and this change improves performance
> measurably.

Turns out you are right about the brains of modern compilers:

/* T is temperature in degrees Fahrenheit,
* R is relative humidity in percent
*/
double Heat_Index(double T, double R)
{
static const double C1 = -42.379;
static const double C2 = 2.04901523;
static const double C3 = 10.14333127;
static const double C4 = -0.22475541;
static const double C5 = -6.83783e-3;
static const double C6 = -5.481717e-2;
static const double C7 = 1.22874e-3;
static const double C8 = 8.5282e-4;
static const double C9 = -1.99e-6;
return C1 + C2 * T + C3 * R + C4 * T * R + C5 * T * T + C6 * R * R
+
C7 * T * T * R + C8 * T * R * R + C9 * T * T * R * R;
}
/* T is temperature in degrees Fahrenheit,
* R is relative humidity in percent
*/
double Heat_Index_Horner(double T, double R)
{
static const double C1 = -42.379;
static const double C2 = 2.04901523;
static const double C3 = 10.14333127;
static const double C4 = -0.22475541;
static const double C5 = -6.83783e-3;
static const double C6 = -5.481717e-2;
static const double C7 = 1.22874e-3;
static const double C8 = 8.5282e-4;
static const double C9 = -1.99e-6;
return C1 + T * (C2 + T * (C5 + R * (C7 + C9 * R)) + R * (C4 + C8
* R)) + R * (C3 + C6 * R);
}

#ifdef UNIT_TEST

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
static const double clock_inv = 1.0 / CLOCKS_PER_SEC;
int main(void)
{
double temperature;
double humidity;
double sum;
clock_t start,
end;

sum = 0;
start = clock();
for (temperature = 32.0; temperature <= 120.0; temperature +=
0.01)
for (humidity = 0; humidity <= 100.0; humidity += 0.01)
sum += Heat_Index(temperature, humidity);
end = clock();
printf("Sum for expanded evaluation is %g which took %g seconds
\n", sum, (end - start) * clock_inv);

sum = 0;
start = clock();
for (temperature = 32.0; temperature <= 120.0; temperature +=
0.01)
for (humidity = 0; humidity <= 100.0; humidity += 0.01)
sum += Heat_Index_Horner(temperature, humidity);
end = clock();
printf("Sum for Horner's evaluation is %g which took %g seconds
\n", sum, (end - start) * clock_inv);
return 0;
}
/*
Sum for expanded evaluation is 9.4831e+009 which took 0.327 seconds
Sum for Horner's evaluation is 9.4831e+009 which took 0.437 seconds
*/
#endif /* UNIT_TEST */

user923005, Oct 27, 2008
19. ### user923005Guest

On Oct 24, 10:12 pm, (Barry L. Bond) wrote:
> Greetings!
>
>      I just got a new Peet Brothers Ultimeter 2100 Weather Station.  This
> new one has a way to display the heat index, if you press the "dew point"
> key twice.
>
>      Being aware of all the controversy surrounding the exact calculation
> of the heat index, I would like my own software (which I programmed in the
> 1990's, when I got their Ultimeter 2000 weather station, but that one
> didn't show heat index) to display it.  Living in Florida, when it's hot,
> in particular, I wouldn't mind knowing what it is, even if I'm not close
> to the actual weather station mounted in my office to press the "d.p." key
> twice.  (My software shows all the current and daily record weather
> conditions, updated twice a minute.)
>
>      Here is the heat index formula:
>
> <<>>
> -42.379 + 2.04901523T + 10.14333127R - 0.22475541TR - 6.83783x10-3T2 - 5.481717x10-2R2 + 1.22874x10-3T2R + 8.5282x10-4TR2 - 1.99x10-6T2R2
> <<>>
>
>      And, here is the line in my C program:
>
> <<>>
>    Heat_Index = (-42.379) + (2.04901523 * Temperature) +
>                 (10.14333127 * Humidity) -
>                 (0.22475541 * Temperature * Humidity) -
>                 (6.83783 * powf (10.0, -3) * powf (Temperature, 2)) -
>                 (5.481717 * powf (10.0, -2) * powf (Humidity, 2)) +
>                 (1.22874 * powf (10.0, -3) * powf (Temperature, 2) *
>                 Humidity) + (8.5282 * powf (10.0, -4) * Temperature *
>                 powf (Humidity, 2)) - (1.99 * powf (10.0, -6) *
>                 powf (Temperature, 2) * powf (Humidity, 2));
> <<>>
>
>      Don't laugh!  :-D
>
>      Temperature and Humidity are correct, as I've viewed it in gdb..  It's
> probably not surprising that I'm NOT getting what the weather station is
> getting for the heat index.
>
>      I'm not mathematically educated, so I'll bet there is something that
> I'm not properly capturing from the above formula in my C code.
>
>      Especially where it says things like "1.99x10-6T2R2".
>
>      I am thinking the "times Temperature squared and times humidity
> squared" is probably okay, but that "x10-6" part, I'm not sure that's
> right.  Since there is no variable there, why wouldn't they just modify
> the number before the "x"?
>
>      Anyway, if anyone doesn't mind talking with extreme patience to
> someone who truly doesn't know whether what I have is right (but I know
> it's not getting the correct amount), what should I do?
>
>      You don't have to rewrite the whole statement.  If you could just tell
> me how I handle things like the "1.99x10-6T2R2", I expect I would be able
> to do the other "x" portions appropriate!

I found this calculation that defines adjustments in two categories:
http://www.hpc.ncep.noaa.gov/heat_index/hi_equation.html

user923005, Oct 27, 2008
20. ### user923005Guest

On Oct 24, 10:12 pm, (Barry L. Bond) wrote:
> Greetings!
>
>      I just got a new Peet Brothers Ultimeter 2100 Weather Station.  This
> new one has a way to display the heat index, if you press the "dew point"
> key twice.
>
>      Being aware of all the controversy surrounding the exact calculation
> of the heat index, I would like my own software (which I programmed in the
> 1990's, when I got their Ultimeter 2000 weather station, but that one
> didn't show heat index) to display it.  Living in Florida, when it's hot,
> in particular, I wouldn't mind knowing what it is, even if I'm not close
> to the actual weather station mounted in my office to press the "d.p." key
> twice.  (My software shows all the current and daily record weather
> conditions, updated twice a minute.)
>
>      Here is the heat index formula:
>
> <<>>
> -42.379 + 2.04901523T + 10.14333127R - 0.22475541TR - 6.83783x10-3T2 - 5.481717x10-2R2 + 1.22874x10-3T2R + 8.5282x10-4TR2 - 1.99x10-6T2R2
> <<>>
>
>      And, here is the line in my C program:
>
> <<>>
>    Heat_Index = (-42.379) + (2.04901523 * Temperature) +
>                 (10.14333127 * Humidity) -
>                 (0.22475541 * Temperature * Humidity) -
>                 (6.83783 * powf (10.0, -3) * powf (Temperature, 2)) -
>                 (5.481717 * powf (10.0, -2) * powf (Humidity, 2)) +
>                 (1.22874 * powf (10.0, -3) * powf (Temperature, 2) *
>                 Humidity) + (8.5282 * powf (10.0, -4) * Temperature *
>                 powf (Humidity, 2)) - (1.99 * powf (10.0, -6) *
>                 powf (Temperature, 2) * powf (Humidity, 2));
> <<>>
>
>      Don't laugh!  :-D
>
>      Temperature and Humidity are correct, as I've viewed it in gdb..  It's
> probably not surprising that I'm NOT getting what the weather station is
> getting for the heat index.
>
>      I'm not mathematically educated, so I'll bet there is something that
> I'm not properly capturing from the above formula in my C code.
>
>      Especially where it says things like "1.99x10-6T2R2".
>
>      I am thinking the "times Temperature squared and times humidity
> squared" is probably okay, but that "x10-6" part, I'm not sure that's
> right.  Since there is no variable there, why wouldn't they just modify
> the number before the "x"?
>
>      Anyway, if anyone doesn't mind talking with extreme patience to
> someone who truly doesn't know whether what I have is right (but I know
> it's not getting the correct amount), what should I do?
>
>      You don't have to rewrite the whole statement.  If you could just tell
> me how I handle things like the "1.99x10-6T2R2", I expect I would be able
> to do the other "x" portions appropriate!

#include <math.h>
/*
From:
http://www.hpc.ncep.noaa.gov/heat_index/hi_equation.html
*/
double Heat_Index(double RH, double T)
{
/*
Heat Index Calculation:

The computation used for the heat index is a refinement of a result
obtained by multiple regression
analysis carried out by Lans P. Rothfusz and described in a 1990
National Weather Service (NWS)
Technical Attachment (SR 90-23).
The regression equation of Rothfusz is:
*/
double HI = -42.379 + 2.04901523 * T
+ 10.14333127 * RH
- 0.22475541 * T * RH
- 0.00683783 * T * T
- 0.05481717 * RH * RH
+ 0.00122874 * T * T * RH
+ 0.00085282 * T * RH * RH
- 0.00000199 * T * T * RH * RH;
/*
where T is temperature in degrees F and RH is relative humidity in
percent.
HI is the heat index expressed as an apparent temperature in
degrees F.
If the RH is less than 13% and the temperature is between 80 and
112 degrees F,
{note, original text says subtracted, but I reversed the sign --
DRC}
*/

if (RH < 13.0 && T >= 80.0 && T <= 112.0)
adjustment = -((13 - RH) / 4) * sqrt((17.0 - fabs(T - 95.)) /
17.0);
/*
where fabs and sqrt are the fabsolute value and square root
functions, respectively.
On the other hand, if the RH is greater than 85 % and the
temperature is between
80 and 87 degrees F, then the following adjustment is added to HI:
*/

if (RH > 85.0 && T >= 80.0 && T <= 87.0)
adjustment = ((RH - 85) / 10) * ((87 - T) / 5);
/*
The equation for HI above with the appropriate adjustment is used
to compute a maximum heat index
using the forecast maximum temperature and an estimated 00 UTC dew
point temperature at each forecast
point location for each forecast projection day. Similarly, a
minimum heat index is computed using
the forecast minimum temperature along with an estimated 12 UTC dew
point temperature.
The forecast daily mean heat index for the projection day is the
average of these two values,
the maximum heat index and the minimum heat index.
Estimated forecast dew point temperatures are obtained using the
method described in the documentation
of the HPC 5-km resolution grid data products.
*/