Mega Search
23.2 Million


Sign Up

Make a donation  
Calls to Function not returning any values.  
News Group: embarcadero.public.delphi.language.delphi.general

Hello and Help:

     I have a table lookup function that is called 3 times by a procedure, and only the last call results in a return of a value.  I have tried everything I could think of to remedy the error, but I believe that I have made a basic coding error that I do not recognize and I cannot figure it out.

The function is declared at the end of the Type area, just before the Private declaration.  It is as follows: “    Function GammaLookup(GN : Double) : Double;   ”.

The actual function is a lengthy table, only the first and last parts are shown below:

Function TFormMainFormBetaDist01072015.GammaLookup(GN : Double) : Double;

begin
   if GN < 0.10 then
        begin
           if MessageDlg('Data ERROR -- a or b is too small -- less than 0.1, application will be terminated', mtConfirmation, [mbYes, mbNo], 0, mbYes) = mrYes then close;
        end
   else if GN = 0.1 then GammaLookup := 9.51351
   else if GN = 0.2 then GammaLookup := 4.59084
   else if GN = 0.3 then GammaLookup := 2.99157
   else if GN = 0.4 then GammaLookup := 2.21816
   else if GN = 0.5 then GammaLookup := 1.77245
   else if GN = 0.6 then GammaLookup := 1.48919
   else if GN = 0.7 then GammaLookup := 1.29806
   else if GN = 0.8 then GammaLookup := 1.16423
   else if GN = 0.9 then GammaLookup := 1.06863
   else if GN = 1.0 then GammaLookup := 1.00000
   else if GN = 1.1 then GammaLookup := 0.951351
                              |
                              |
                             ∇
   else if GN = 9.4 then GammaLookup := 95809.5
   else if GN = 9.5 then GammaLookup := 119292.0
   else if GN = 9.6 then GammaLookup := 148696.0
   else if GN = 9.7 then GammaLookup := 185551.0
   else if GN = 9.8 then GammaLookup := 231792.0
   else if GN = 9.9 then GammaLookup := 289868.0
   else if GN = 10.0 then GammaLookup := 362880.0
   else if GN > 10.0 then
        begin
          if MessageDlg('Data ERROR -- a or b is greater than 10.0, Exit now?', mtConfirmation, [mbYes, mbNo], 0, mbYes) = mrYes then close;
        end ;
end;


The Function is called from a Procedure called Calculate as follows:

procedure TFormMainFormBetaDist01072015.CalculateBTNClick(Sender: TObject);
    //
var
   //
begin
    //
              GammaAlpha       := FloatEdit5.value;
              Label26.caption  := FloatToSTRF(GammaAlpha, ffNumber, 5, 2);
              gammaA1          := GammaLookup(GammaAlpha);
              Label21.Caption  := FloatToStrF(GammaA1, ffNumber, 10, 9);
              //
              GammaBeta        := FloatEdit6.value;
              Label28.caption  := FloatToSTRF(GammaBeta, ffNumber, 5, 2);
              gammaB1          := GammaLookup(GammaBeta);
              Label23.Caption  := FloatToStrF(GammaB1, ffNumber, 10, 9);
              //
              GammaAlphaBeta   := GammaAlpha + GammaBeta;
              Label30.Caption  := FloatToStrF(GammaAlphaBeta, ffNumber, 10, 2);
              gammaAplusB1     := GammaLookup(GammaAlphaBeta);
              Label25.caption  := FloatToSTRF(GammaAplusB1, ffNumber, 10, 9);
              //
              //
                              |
                              |
                             ∇
 Other code that will utilize the values GammaA1, GammaB1, and GammaAplusB1.

End;

there is a data holding unit as follows:

 “unit UnitDataHoldingBeta010172015;

interface

var
//
        Many, many variable definitions 
                              |
                              |
                             ∇
    GammaAlpha, GAmmaBeta, GammaAlphaBeta, BetaFunction : double;
    GammaA1, GammaB1, GammaAplusB1 : double; 
    //
    //
   //
implementation

end.


GammaAlpha, GAmmaBeta, GammaAlphaBeta are input from float edit boxes and all displayed on labels on the main form of the application, and the return values from the function of GammaA1, GammaB1 are displayed as 0.0000000 for both, but the return value for GammaAplusB1 is displayed with the proper value.

I have tried changing the number of calls to the function by // out the call lines for each and combinations of 2.  If I // out the calls for GammaB1 and GammaAplusB1, the proper value for GammaA1 is displayed, however, if I // out the calls for GammaA1 and GammaAplusB1, there is not any display (other than 0.000000) for GammaB1.  As mentioned above, the proper value for the sum of the two , GammaAplusB1 will display properly.

I have also tried substituting “result” for “GammaLookup” on the right side of the “then” in the else If statements.  That did not have any effect.

What am I doing wrong?  Any suggestions will be greatly appreciated.
John Shyer

Vote for best question.
Score: 0  # Vote:  0
Date Posted: 22-Jan-2015, at 1:20 PM EST
From: John Shyer
 
Re: Calls to Function not returning any values.  
News Group: embarcadero.public.delphi.language.delphi.general
"John Shyer" wrote in message news:710969@forums.embarcadero.com...
>
>   if GN < 0.10 then
>        begin
>           if MessageDlg('Data ERROR -- a or b is too small -- less than 
> 0.1, application will be terminated', mtConfirmation, [mbYes, mbNo], 0, 
> mbYes) = mrYes then close;
>        end
>   else if GN = 0.1 then GammaLookup := 9.51351
>   else if GN = 0.2 then GammaLookup := 4.59084
[...]
>   else if GN = 10.0 then GammaLookup := 362880.0
>   else if GN > 10.0 then
>        begin
>          if MessageDlg('Data ERROR -- a or b is greater than 10.0, Exit 
> now?', mtConfirmation, [mbYes, mbNo], 0, mbYes) = mrYes then close;
>        end ;
> end;

Your biggest problem is trying to compare floating point values with 
constant values. Floating point values are not exact. For each of your 
comparisons you need to use the CompareValue function (it is in the Math 
unit).

   else if CompareValue(GN, 0.1, 0.01) = 0 then GammaLookup := 9.51351
   else if CompareValue(GN, 0.2, 0.01) then GammaLookup := 4.59084

The 3rd parameter to CompareValue is the epsilon - or the level of precision 
you require. Essentially that means it will round your values to that 
precision before comparing them.

However coding 100 if/else statements like this, beyond being tedious, is 
very inefficient, every condition must be tested until the passing condition 
is found. There are a couple of alternatives that would perform much better. 
If you are using any Delphi version from D2009 on you could use a Dictionary 
object (in Generics.Collections unit). If not then this if/else ladder could 
at least be changed into a case statement. In either case since you are 
using values in a defined range and intervals, these could be promoted to 
integers to make the comparisons more efficient. E,g, if using case then:

var
    GNI: integer;
begin
    [...]
    GNI := Trunc(GN * 10); // 0.1 becomes 1, 9.9 becomes 99
    case GNI of
        1:  GammaLookup := 9.51351
        2:  GammaLookup := 4.59084
        [...]
        100: GammaLookup := 362880.0
        else
        begin
            MessageDlg( ....
        end;
    end;

If you can use the TDictionary class I would advise it, then you simply add 
the entries one time when program starts and the lookup becomes one line:

    GammaLookup := BetaDict[GNI];

The dictionary would be:

    BetaDict: TDictionary;
....
    BetaDict := TDictionary.Create;
    BetaDict.Add(1, 9.51351);
    BetaDict.Add(2, 4.59084);
    [...]

-- 
Wayne Niddery
"You know what they call alternative medicine that has been proven to work? 
Medicine." - Tim Minchin

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 23-Jan-2015, at 7:58 AM EST
From: Wayne Niddery
 
Re: Calls to Function not returning any values.  
News Group: embarcadero.public.delphi.language.delphi.general
On 23/01/2015 00:19, Just JJ wrote:
> On Thu, 22 Jan 2015 13:20:38 -0800, John Shyer wrote:

>
> It's mainly caused by float number rounding issue.
>
> In GammaLookup(), you're comparing GN variable with float constants. In
> Delphi, a float constant is an Extended type, and comparing two values with
> different float types can lead to incorrect result. Thus, if GN is 0.4, GN
> <> 0.4.
>
> I would suggest converting the value in GN to Extended then round it to one
> fractional digit (since you're working with and expecting one fractional
> digit value) *even* if it's looks like it only have one fractional digit
> already. e.g.:
>
> var XGN: Extended;
> begin
>    XGN:= Round(GN * 10) / 10;
>    If XGN < 1.0 then
>    .
>    .
>    else if XGN = 0.1 then ...
>    else if XGN = 0.2 then ...
>    .
>    .
>    else if XGN > 10.0 then
>    .
>    .
> end;
>

I would store each of your values (RHS of the 'thens') in a const array 
inside the function as:
const GL: array[1..100] of Double = (  );

Then reference this by Result:=GL[Round(GN*10)];
You would, of course, need to test for Round(GN*10)<1 and 
Round(GN*10)>100 prior to referencing the array.

Cheers,

Gerald.

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 23-Jan-2015, at 12:32 AM EST
From: Gerald Holdsworth
 
Re: Calls to Function not returning any values.  
News Group: embarcadero.public.delphi.language.delphi.general
On Thu, 22 Jan 2015 13:20:38 -0800, John Shyer wrote:
> Hello and Help:
> 
>      I have a table lookup function that is called 3 times by a procedure, and only the last call results in a return of a value.  I have tried everything I could think of to remedy the error, but I believe that I have made a basic coding error that I do not recognize and I cannot figure it out.
> 
> The function is declared at the end of the Type area, just before the Private declaration.  It is as follows: “    Function GammaLookup(GN : Double) : Double;   ”.
> 
> The actual function is a lengthy table, only the first and last parts are shown below:
> 
> Function TFormMainFormBetaDist01072015.GammaLookup(GN : Double) : Double;
> 
> begin
>    if GN < 0.10 then
>         begin
>            if MessageDlg('Data ERROR -- a or b is too small -- less than 0.1, application will be terminated', mtConfirmation, [mbYes, mbNo], 0, mbYes) = mrYes then close;
>         end
>    else if GN = 0.1 then GammaLookup := 9.51351
>    else if GN = 0.2 then GammaLookup := 4.59084
>    else if GN = 0.3 then GammaLookup := 2.99157
>    else if GN = 0.4 then GammaLookup := 2.21816
>    else if GN = 0.5 then GammaLookup := 1.77245
>    else if GN = 0.6 then GammaLookup := 1.48919
>    else if GN = 0.7 then GammaLookup := 1.29806
>    else if GN = 0.8 then GammaLookup := 1.16423
>    else if GN = 0.9 then GammaLookup := 1.06863
>    else if GN = 1.0 then GammaLookup := 1.00000
>    else if GN = 1.1 then GammaLookup := 0.951351
>                               |
>                               |
>                              ∇
>    else if GN = 9.4 then GammaLookup := 95809.5
>    else if GN = 9.5 then GammaLookup := 119292.0
>    else if GN = 9.6 then GammaLookup := 148696.0
>    else if GN = 9.7 then GammaLookup := 185551.0
>    else if GN = 9.8 then GammaLookup := 231792.0
>    else if GN = 9.9 then GammaLookup := 289868.0
>    else if GN = 10.0 then GammaLookup := 362880.0
>    else if GN > 10.0 then
>         begin
>           if MessageDlg('Data ERROR -- a or b is greater than 10.0, Exit now?', mtConfirmation, [mbYes, mbNo], 0, mbYes) = mrYes then close;
>         end ;
> end;
> 
[snip]
> 
> GammaAlpha, GAmmaBeta, GammaAlphaBeta are input from float edit boxes and all displayed on labels on the main form of the application, and the return values from the function of GammaA1, GammaB1 are displayed as 0.0000000 for both, but the return value for GammaAplusB1 is displayed with the proper value.
> 
> I have tried changing the number of calls to the function by // out the call lines for each and combinations of 2.  If I // out the calls for GammaB1 and GammaAplusB1, the proper value for GammaA1 is displayed, however, if I // out the calls for GammaA1 and GammaAplusB1, there is not any display (other than 0.000000) for GammaB1.  As mentioned above, the proper value for the sum of the two , GammaAplusB1 will display properly.
> 
> I have also tried substituting “result” for “GammaLookup” on the right side of the “then” in the else If statements.  That did not have any effect.
> 
> What am I doing wrong?  Any suggestions will be greatly appreciated.
> John Shyer

It's mainly caused by float number rounding issue.

In GammaLookup(), you're comparing GN variable with float constants. In
Delphi, a float constant is an Extended type, and comparing two values with
different float types can lead to incorrect result. Thus, if GN is 0.4, GN
<> 0.4.

I would suggest converting the value in GN to Extended then round it to one
fractional digit (since you're working with and expecting one fractional
digit value) *even* if it's looks like it only have one fractional digit
already. e.g.:

var XGN: Extended;
begin
  XGN:= Round(GN * 10) / 10;
  If XGN < 1.0 then
  .
  .
  else if XGN = 0.1 then ...
  else if XGN = 0.2 then ...
  .
  .
  else if XGN > 10.0 then
  .
  .
end;

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 22-Jan-2015, at 4:19 PM EST
From: Just JJ
 
Re: Calls to Function not returning any values.  
News Group: embarcadero.public.delphi.language.delphi.general
Paolo,

I had not thought of that.  I have been inputting values with just one decimal place, and in fact the one that went through was actually an double of the form x.0, with out any other decimal parts.  If that is the case, the function returned proper values with an input ending in .0 as the decimal part.  Now the only way I can see to achieve the proper lookup is to change all of the GN values to be the original ones * 10.0, then input Gn from "calculate" as GN * 10.0.  Is there an easier way to do this?

John

> {quote:title=Paolo Valle wrote:}{quote}
> maybe I cannot help you, but what is the expected result of your function if 
> the input value is for example 0.11 ?
> 
> "John Shyer" ha scritto nel messaggio news:710969@forums.embarcadero.com...
> 
> Hello and Help:
> 
>      I have a table lookup function that is called 3 times by a procedure, 
> and only the last call results in a return of a value.  I have tried 
> everything I could think of to remedy the error, but I believe that I have 
> made a basic coding error that I do not recognize and I cannot figure it 
> out.
> 
> The function is declared at the end of the Type area, just before the 
> Private declaration.  It is as follows: “    Function GammaLookup(GN : 
> Double) : Double;   ”.
> 
> The actual function is a lengthy table, only the first and last parts are 
> shown below:
> 
> Function TFormMainFormBetaDist01072015.GammaLookup(GN : Double) : Double;
> 
> begin
>    if GN < 0.10 then
>         begin
>            if MessageDlg('Data ERROR -- a or b is too small -- less than 
> 0.1, application will be terminated', mtConfirmation, [mbYes, mbNo], 0, 
> mbYes) = mrYes then close;
>         end
>    else if GN = 0.1 then GammaLookup := 9.51351
>    else if GN = 0.2 then GammaLookup := 4.59084
>    else if GN = 0.3 then GammaLookup := 2.99157
>    else if GN = 0.4 then GammaLookup := 2.21816
>    else if GN = 0.5 then GammaLookup := 1.77245
>    else if GN = 0.6 then GammaLookup := 1.48919
>    else if GN = 0.7 then GammaLookup := 1.29806
>    else if GN = 0.8 then GammaLookup := 1.16423
>    else if GN = 0.9 then GammaLookup := 1.06863
>    else if GN = 1.0 then GammaLookup := 1.00000
>    else if GN = 1.1 then GammaLookup := 0.951351
>                               |
>                               |
>                              ∇
>    else if GN = 9.4 then GammaLookup := 95809.5
>    else if GN = 9.5 then GammaLookup := 119292.0
>    else if GN = 9.6 then GammaLookup := 148696.0
>    else if GN = 9.7 then GammaLookup := 185551.0
>    else if GN = 9.8 then GammaLookup := 231792.0
>    else if GN = 9.9 then GammaLookup := 289868.0
>    else if GN = 10.0 then GammaLookup := 362880.0
>    else if GN > 10.0 then
>         begin
>           if MessageDlg('Data ERROR -- a or b is greater than 10.0, Exit 
> now?', mtConfirmation, [mbYes, mbNo], 0, mbYes) = mrYes then close;
>         end ;
> end;
> 
> 
> The Function is called from a Procedure called Calculate as follows:
> 
> procedure TFormMainFormBetaDist01072015.CalculateBTNClick(Sender: TObject);
>     //
> var
>    //
> begin
>     //
>               GammaAlpha       := FloatEdit5.value;
>               Label26.caption  := FloatToSTRF(GammaAlpha, ffNumber, 5, 2);
>               gammaA1          := GammaLookup(GammaAlpha);
>               Label21.Caption  := FloatToStrF(GammaA1, ffNumber, 10, 9);
>               //
>               GammaBeta        := FloatEdit6.value;
>               Label28.caption  := FloatToSTRF(GammaBeta, ffNumber, 5, 2);
>               gammaB1          := GammaLookup(GammaBeta);
>               Label23.Caption  := FloatToStrF(GammaB1, ffNumber, 10, 9);
>               //
>               GammaAlphaBeta   := GammaAlpha + GammaBeta;
>               Label30.Caption  := FloatToStrF(GammaAlphaBeta, ffNumber, 10, 
> 2);
>               gammaAplusB1     := GammaLookup(GammaAlphaBeta);
>               Label25.caption  := FloatToSTRF(GammaAplusB1, ffNumber, 10, 
> 9);
>               //
>               //
>                               |
>                               |
>                              ∇
> Other code that will utilize the values GammaA1, GammaB1, and GammaAplusB1.
> 
> End;
> 
> there is a data holding unit as follows:
> 
> “unit UnitDataHoldingBeta010172015;
> 
> interface
> 
> var
> //
>         Many, many variable definitions
>                               |
>                               |
>                              ∇
>     GammaAlpha, GAmmaBeta, GammaAlphaBeta, BetaFunction : double;
>     GammaA1, GammaB1, GammaAplusB1 : double;
>     //
>     //
>    //
> implementation
> 
> end.
> 
> 
> GammaAlpha, GAmmaBeta, GammaAlphaBeta are input from float edit boxes and 
> all displayed on labels on the main form of the application, and the return 
> values from the function of GammaA1, GammaB1 are displayed as 0.0000000 for 
> both, but the return value for GammaAplusB1 is displayed with the proper 
> value.
> 
> I have tried changing the number of calls to the function by // out the call 
> lines for each and combinations of 2.  If I // out the calls for GammaB1 and 
> GammaAplusB1, the proper value for GammaA1 is displayed, however, if I // 
> out the calls for GammaA1 and GammaAplusB1, there is not any display (other 
> than 0.000000) for GammaB1.  As mentioned above, the proper value for the 
> sum of the two , GammaAplusB1 will display properly.
> 
> I have also tried substituting “result” for “GammaLookup” on the right side 
> of the “then” in the else If statements.  That did not have any effect.
> 
> What am I doing wrong?  Any suggestions will be greatly appreciated.
> John Shyer

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 22-Jan-2015, at 2:10 PM EST
From: John Shyer
 
Re: Calls to Function not returning any values.  
News Group: embarcadero.public.delphi.language.delphi.general
maybe I cannot help you, but what is the expected result of your function if 
the input value is for example 0.11 ?

"John Shyer" ha scritto nel messaggio news:710969@forums.embarcadero.com...

Hello and Help:

     I have a table lookup function that is called 3 times by a procedure, 
and only the last call results in a return of a value.  I have tried 
everything I could think of to remedy the error, but I believe that I have 
made a basic coding error that I do not recognize and I cannot figure it 
out.

The function is declared at the end of the Type area, just before the 
Private declaration.  It is as follows: “    Function GammaLookup(GN : 
Double) : Double;   ”.

The actual function is a lengthy table, only the first and last parts are 
shown below:

Function TFormMainFormBetaDist01072015.GammaLookup(GN : Double) : Double;

begin
   if GN < 0.10 then
        begin
           if MessageDlg('Data ERROR -- a or b is too small -- less than 
0.1, application will be terminated', mtConfirmation, [mbYes, mbNo], 0, 
mbYes) = mrYes then close;
        end
   else if GN = 0.1 then GammaLookup := 9.51351
   else if GN = 0.2 then GammaLookup := 4.59084
   else if GN = 0.3 then GammaLookup := 2.99157
   else if GN = 0.4 then GammaLookup := 2.21816
   else if GN = 0.5 then GammaLookup := 1.77245
   else if GN = 0.6 then GammaLookup := 1.48919
   else if GN = 0.7 then GammaLookup := 1.29806
   else if GN = 0.8 then GammaLookup := 1.16423
   else if GN = 0.9 then GammaLookup := 1.06863
   else if GN = 1.0 then GammaLookup := 1.00000
   else if GN = 1.1 then GammaLookup := 0.951351
                              |
                              |
                             ∇
   else if GN = 9.4 then GammaLookup := 95809.5
   else if GN = 9.5 then GammaLookup := 119292.0
   else if GN = 9.6 then GammaLookup := 148696.0
   else if GN = 9.7 then GammaLookup := 185551.0
   else if GN = 9.8 then GammaLookup := 231792.0
   else if GN = 9.9 then GammaLookup := 289868.0
   else if GN = 10.0 then GammaLookup := 362880.0
   else if GN > 10.0 then
        begin
          if MessageDlg('Data ERROR -- a or b is greater than 10.0, Exit 
now?', mtConfirmation, [mbYes, mbNo], 0, mbYes) = mrYes then close;
        end ;
end;


The Function is called from a Procedure called Calculate as follows:

procedure TFormMainFormBetaDist01072015.CalculateBTNClick(Sender: TObject);
    //
var
   //
begin
    //
              GammaAlpha       := FloatEdit5.value;
              Label26.caption  := FloatToSTRF(GammaAlpha, ffNumber, 5, 2);
              gammaA1          := GammaLookup(GammaAlpha);
              Label21.Caption  := FloatToStrF(GammaA1, ffNumber, 10, 9);
              //
              GammaBeta        := FloatEdit6.value;
              Label28.caption  := FloatToSTRF(GammaBeta, ffNumber, 5, 2);
              gammaB1          := GammaLookup(GammaBeta);
              Label23.Caption  := FloatToStrF(GammaB1, ffNumber, 10, 9);
              //
              GammaAlphaBeta   := GammaAlpha + GammaBeta;
              Label30.Caption  := FloatToStrF(GammaAlphaBeta, ffNumber, 10, 
2);
              gammaAplusB1     := GammaLookup(GammaAlphaBeta);
              Label25.caption  := FloatToSTRF(GammaAplusB1, ffNumber, 10, 
9);
              //
              //
                              |
                              |
                             ∇
Other code that will utilize the values GammaA1, GammaB1, and GammaAplusB1.

End;

there is a data holding unit as follows:

“unit UnitDataHoldingBeta010172015;

interface

var
//
        Many, many variable definitions
                              |
                              |
                             ∇
    GammaAlpha, GAmmaBeta, GammaAlphaBeta, BetaFunction : double;
    GammaA1, GammaB1, GammaAplusB1 : double;
    //
    //
   //
implementation

end.


GammaAlpha, GAmmaBeta, GammaAlphaBeta are input from float edit boxes and 
all displayed on labels on the main form of the application, and the return 
values from the function of GammaA1, GammaB1 are displayed as 0.0000000 for 
both, but the return value for GammaAplusB1 is displayed with the proper 
value.

I have tried changing the number of calls to the function by // out the call 
lines for each and combinations of 2.  If I // out the calls for GammaB1 and 
GammaAplusB1, the proper value for GammaA1 is displayed, however, if I // 
out the calls for GammaA1 and GammaAplusB1, there is not any display (other 
than 0.000000) for GammaB1.  As mentioned above, the proper value for the 
sum of the two , GammaAplusB1 will display properly.

I have also tried substituting “result” for “GammaLookup” on the right side 
of the “then” in the else If statements.  That did not have any effect.

What am I doing wrong?  Any suggestions will be greatly appreciated.
John Shyer

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 22-Jan-2015, at 1:47 PM EST
From: Paolo Valle