Recent

Author Topic: float field validation error  (Read 2032 times)

Packs

  • Sr. Member
  • ****
  • Posts: 498
float field validation error
« on: January 04, 2024, 08:23:48 am »
Code: Pascal  [Select][+][-]
  1. procedure Tdm_statement.pr_update_overall_cgpa_grade();
  2. var
  3.   Fcgpa: double = 0.00;
  4.   Fmultiple: double = 0.00;
  5.   FMinsgpa: double = 0.00;
  6.   FMaxsgpa: double = 0.00;
  7.   lCondition : boolean = false ;
  8. begin
  9.   if (buf_sem_main.RecordCount <= 0) then
  10.   begin
  11.     ShowMessage('Record count :');
  12.     Exit;
  13.   end;
  14.  
  15.   buf_marks.First;
  16.  
  17.   buf_sem_main.First;
  18.   while not buf_sem_main.EOF do
  19.   begin
  20.     if buf_sem_main.FieldByName('aadhaar').AsLargeInt = 868819501724 then
  21.     begin
  22.       ShowMessage('Yes');
  23.     end;
  24.  
  25.     if buf_marks.Locate('Aadhaar', buf_sem_main.FieldByName(
  26.       'aadhaar').AsLargeInt, []) then
  27.     begin
  28.       if buf_sem_main.FieldByName('total_multiple').AsFloat > 0 then
  29.       begin
  30.  
  31.         Fcgpa := 0;
  32.         Fmultiple := 0;
  33.  
  34.         Fmultiple := buf_sem_main.FieldByName('total_multiple').AsFloat;
  35.         Fcgpa := (Fmultiple / Overallcreditpoints);
  36.         Fcgpa := Math.RoundTo(Fcgpa, -3);
  37.  
  38.  
  39.         buf_slab.First;
  40.         while not buf_slab.EOF do
  41.         begin
  42.           FMinsgpa := 0;
  43.           FMaxsgpa := 0;
  44.           FMinsgpa := buf_slab.FieldByName('min_gpa').AsFloat;
  45.           FMaxsgpa := buf_slab.FieldByName('max_gpa').AsFloat;
  46.  
  47.  
  48.           lCondition := ((Fcgpa >= FMinsgpa) and (Fcgpa <= FMaxsgpa)) ;
  49.           if lCondition then
  50.           begin
  51.             buf_marks.Edit;
  52.             buf_marks.FieldByName('sem_comma').AsString :=
  53.               buf_sem_main.FieldByName('commadata').AsString;
  54.  
  55.             //buf_marks.FieldByName('overall_cgpa').AsString := 'NA';
  56.             //buf_marks.FieldByName('overall_grade').AsString := 'NA';
  57.  
  58.             buf_marks.FieldByName('overall_cgpa').AsString := Format('%.2f', [Fcgpa]);
  59.             buf_marks.FieldByName('overall_grade').AsString :=
  60.               buf_slab.FieldByName('grade').AsString;
  61.             buf_marks.Post;
  62.  
  63.             Break;
  64.           end;
  65.  
  66.           buf_slab.Next;
  67.         end;
  68.  
  69.       end;
  70.       //buf_marks.Post;
  71.     end;
  72.  
  73.     buf_sem_main.Next;
  74.   end;
  75.  
  76. end;
  77.  
  78.  

in this above code what was the mistake.

when I am geeting value for following variables 

Fcgpa = 8.99
FMinsgpa = 8
FMaxsgpa = 8.99

my condition is not get staified .( lCondition := ((Fcgpa >= FMinsgpa) and (Fcgpa <= FMaxsgpa))  )



Zvoni

  • Hero Member
  • *****
  • Posts: 3442
Re: float field validation error
« Reply #1 on: January 04, 2024, 08:30:06 am »
when I am geeting value for following variables 

Fcgpa = 8.99
FMinsgpa = 8
FMaxsgpa = 8.99

my condition is not get staified .( lCondition := ((Fcgpa >= FMinsgpa) and (Fcgpa <= FMaxsgpa))  )
Then check the Value of FMaxsgpa.
If your condition is not satisfied, that means that FMaxsgpa<Fcgpa.

At a guess: Rounding error.
Maybe try to use an Epsilon-Threshold
« Last Edit: January 04, 2024, 09:36:28 am by Zvoni »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Packs

  • Sr. Member
  • ****
  • Posts: 498
Re: float field validation error
« Reply #2 on: January 04, 2024, 08:40:14 am »
i Have check the watch window and share the value

Packs

  • Sr. Member
  • ****
  • Posts: 498
Re: float field validation error
« Reply #3 on: January 04, 2024, 09:01:55 am »
is there any method to find exact value of the float vairable

Thaddy

  • Hero Member
  • *****
  • Posts: 19488
  • Glad to be alive.
Re: float field validation error
« Reply #4 on: January 04, 2024, 09:16:07 am »
is there any method to find exact value of the float vairable
No, because that is not always possible for float comparisons like you describe. But FreePascal has a function SameValue (in math), where you can define an acceptible margin to compare two float values that corrects for the imprecise nature of floating point values.
Code: Pascal  [Select][+][-]
  1. program test;
  2. {$mode objfpc}
  3. uses math;
  4. var
  5.   x:single = 10.0;
  6.   y:single = 3.0;
  7.   Epsilon:Single  = 0.000000001;
  8. begin
  9.    writeln(SameValue((x/y) * 3, x)); // should be false
  10.    writeln(SameValue((x/y)*3, x,Epsilon); // Should be true
  11.    Readln;
  12. end.
Untested.
« Last Edit: January 04, 2024, 12:06:37 pm by Thaddy »
Any "programmer" that knows only one programming language is not a programmer

Zvoni

  • Hero Member
  • *****
  • Posts: 3442
Re: float field validation error
« Reply #5 on: January 04, 2024, 09:23:32 am »
Maybe add a "rounding" in Line 45 like you did in Line 36
Code: Pascal  [Select][+][-]
  1. FMaxsgpa := Math.RoundTo(buf_slab.FieldByName('max_gpa').AsFloat, -3);
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

dseligo

  • Hero Member
  • *****
  • Posts: 1686
Re: float field validation error
« Reply #6 on: January 04, 2024, 09:29:55 am »
As Thaddy told you, use SameValue.

But there is an alternative. Depends on precision you need and calculations you do, you could also use 'currency' type.

Currency is fixed to 4 decimal places, but you can compare directly values.
There is equivalent support in FPC for currency as for other float types. You have: StrToCurr, FormatCurr, FieldByName('some DB field').AsCurrency, and so on.

Thaddy

  • Hero Member
  • *****
  • Posts: 19488
  • Glad to be alive.
Re: float field validation error
« Reply #7 on: January 04, 2024, 09:53:18 am »
Note that in my example the smallest theoretical epsilon is actually 10.0 -((10/3)* 3)
which uses the error between the result of the calculation and the value to compare against. That is usually just the loss of one bit "precision" that can be expressed in a float value. Actually it is proof that comparisons may not be so precise when comparing float values.
Note that for my purposes I tend to prefer two bits "precision" lost.
Float value comparisons must be considered approximations
« Last Edit: January 04, 2024, 10:07:55 am by Thaddy »
Any "programmer" that knows only one programming language is not a programmer

Paolo

  • Hero Member
  • *****
  • Posts: 753
Re: float field validation error
« Reply #8 on: January 04, 2024, 04:19:36 pm »
Quote
Actually it is proof that comparisons may not be so precise when comparing float values

I don't think that is something wrong in the comparison, the comparison said the truth: the two numbers are different.

what something can create confusion is also the "default" float value shown in the "debug wathces", for example

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. var
  3.   a, b, c, d : double;
  4. begin
  5.   a:=0.1;
  6.   b:=0.2;
  7.   c:=0.3;
  8.   d:=a+b;
  9.   if (c = d) then
  10.     beep;
  11. end;
  12.  

this code will never do "beep", but the comparison said the truth, infact (see picture 1) the binary repesentation of C and D confirms they are different, but if you look at the "default" value it says something false, both are 0.3  %)(picture-2).
I understand that it can be annoying to see similar numbers in watches, and they can be much-much longer: (eg 64-bit double, if I am not wrong)
C=+0.299999999999999988897769753748434595763683319091796875
D=+0.3000000000000000444089209850062616169452667236328125
So as main advice look always at the binary content of "float" variable, do not rely on other representation for float variable and even on what the watches say when “Default” is selected.

Quote
is there any method to find exact value of the float variable

If you mean decimal representation: no, that I know of. You have to write code for this purpose (see the real value of C and D above).
If you want see the values during coding look at the Memory Dump representation in the watches as said above.

Paolo

  • Hero Member
  • *****
  • Posts: 753
Re: float field validation error
« Reply #9 on: January 04, 2024, 04:51:32 pm »
sorry, the  pictures :-[

Packs

  • Sr. Member
  • ****
  • Posts: 498
Re: float field validation error
« Reply #10 on: January 04, 2024, 06:39:14 pm »
Thanks zvoni.

It is working. I have used round for min and Max variable.

Thaddy

  • Hero Member
  • *****
  • Posts: 19488
  • Glad to be alive.
Re: float field validation error
« Reply #11 on: January 05, 2024, 02:43:10 pm »
A bitwise comparison will also reveal that they are different. That can be done with a simple hardcast.
Any "programmer" that knows only one programming language is not a programmer

Packs

  • Sr. Member
  • ****
  • Posts: 498
Re: float field validation error
« Reply #12 on: January 09, 2024, 07:11:16 pm »
Please elaborate in detail.

Thaddy

  • Hero Member
  • *****
  • Posts: 19488
  • Glad to be alive.
Re: float field validation error
« Reply #13 on: January 09, 2024, 08:31:30 pm »
What I mean is simply to compare the bit patterns, easy:
Code: Pascal  [Select][+][-]
  1. program expfrac;
  2. uses sysutils;
  3. var a,b:single;
  4. begin
  5.   a:= 33 * 100/33;
  6.   b:= 100.0;
  7.   writeln('bit pattern of the mantissa''s')
  8.   writeln(a.mantissa.tobinstring);
  9.   writeln('comparison of the bit patterns of exp and frac');
  10.   writeln ((a.frac = b.frac) and  (a.exp = b.exp));
  11. end.
In some cases it may be enough to just compare the mantissa directly, because of the insignificant bit.
All three used functions are a bitwise representation of the values.
See the documentation for typehelpers in sysutils.
« Last Edit: January 09, 2024, 08:33:15 pm by Thaddy »
Any "programmer" that knows only one programming language is not a programmer

 

TinyPortal © 2005-2018