Recent

Author Topic: ABS truncates a Variant float ?  (Read 8299 times)

Thaddy

  • Hero Member
  • *****
  • Posts: 14201
  • Probably until I exterminate Putin.
Re: ABS truncates a Variant float ?
« Reply #30 on: February 25, 2018, 06:05:33 pm »
Concentrate on integer vs floats.

Function ABS(V:Variant):Variant; Overload; inline;
Begin
  result := v;
  If VarIsNumeric(V) Then
    if V< 0 Then result := -v;
end;   [/code] :D

This will also allow code like this to compile:
Code: Pascal  [Select][+][-]
  1. var
  2.   S : String;
  3.  
  4. begin
  5.   S:='My very nice string';
  6.   S:=Abs(S);
  7. end;
  8.  

That would be bad.

Bart
That's why you need to initialize result to varnull as per my example here http://forum.lazarus.freepascal.org/index.php/topic,40223.msg277657.html#msg277657 .
That gets handled correctly because it throws a descriptive runtime error in all cases.

In general the bug is described only half-way and it should be fixed. And it can be fixed. Nothing to do with rt vs ct.
« Last Edit: February 25, 2018, 06:14:23 pm by Thaddy »
Specialize a type, not a var.

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: ABS truncates a Variant float ?
« Reply #31 on: February 25, 2018, 06:22:09 pm »
Point is that Abs() currently throws a compile time error on that code, and it stops doing that when you introduce the variant overload.

Bart

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: ABS truncates a Variant float ?
« Reply #32 on: February 25, 2018, 06:32:42 pm »
Code: Pascal  [Select][+][-]
  1. Function ABS(V:Variant):Variant; Overload;   //Current FPC 3.0.4 has Double Type bug.
  2. Begin                                               //Must override;
  3.   If (VarIsNumeric(V)) Then
  4.   if V< 0 Then result := -V else Result := V
  5.   else
  6.    Raise EVariantBadVarTypeError.Create('Contains no Integer or Float for Variant');
  7. end;                                                                                  

This is what I am using now!..
it works.
The only true wisdom is knowing you know nothing

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: ABS truncates a Variant float ?
« Reply #33 on: February 25, 2018, 09:08:32 pm »
This will also allow code like this to compile:

That would be bad.

Indeed that would be very bad.

Silly workaround ?:
Code: Pascal  [Select][+][-]
  1. Function ABS(var V:Variant):Variant;
  2.  

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: ABS truncates a Variant float ?
« Reply #34 on: February 25, 2018, 09:45:31 pm »
Your correct, I see the problem.. although for me it wasn't a big deal  but the use of the
VAR instead will make things faster to pass a reference to it.
Code: Pascal  [Select][+][-]
  1. Function ABS(Var V:Variant):Variant; //Current FPC 3.0.4 has Double Type bug.
  2. Begin                                        ;
  3.   If (VarIsNumeric(V)) Then
  4.   if V< 0 Then result := -V else Result := V
  5.   else
  6.    Raise EVariantBadVarTypeError.Create('Contains no Integer or Float for Variant');
  7. end;                                                                                    

Thanks.. Maybe this should be put in the variants unit, its only needed when you use the variant unit in the first place.
The only true wisdom is knowing you know nothing

ASerge

  • Hero Member
  • *****
  • Posts: 2222
Re: ABS truncates a Variant float ?
« Reply #35 on: February 26, 2018, 02:25:26 am »
Code: Pascal  [Select][+][-]
  1. Function ABS(Var V:Variant):Variant; //Current FPC 3.0.4 has Double Type bug.
  2. Begin                                        ;
  3.   If (VarIsNumeric(V)) Then
  4.   if V< 0 Then result := -V else Result := V
  5.   else
  6.    Raise EVariantBadVarTypeError.Create('Contains no Integer or Float for Variant');
  7. end;
var not allow call as Abs(Variant(-5)). And what about Abs(Variant('-5'))?
I suggest the following version
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$APPTYPE CONSOLE}
  3. {$MODE OBJFPC}
  4.  
  5. uses SysUtils, Variants;
  6.  
  7. function Abs(const V: Variant): Variant;
  8. begin
  9.   Result := V;
  10.   //if Result < 0 then
  11.   //generate code:
  12.   //V2: Variant;
  13.   //V2 := ShortInt(0);
  14.   //if V < V2 then
  15.   if Extended(Result) < 0 then
  16.     Result := -Result;
  17. end;
  18.  
  19. var
  20.   i: Integer;
  21.   Arr: Variant;
  22. begin
  23.   Arr := VarArrayOf([-35.2, 35.2, -35, -2e-20, '-5.2', 'bad abs value', -$FF, '-$FF']);
  24.   for i := VarArrayLowBound(Arr, 1) to VarArrayHighBound(Arr, 1) do
  25.   try
  26.     Write('Abs(', Arr[i], ')=');
  27.     Writeln(Abs(Arr[i]));
  28.   except
  29.     on E: Exception do
  30.       Writeln('error: ', E.Message);
  31.   end;
  32.   Readln;
  33. end.

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: ABS truncates a Variant float ?
« Reply #36 on: February 26, 2018, 02:43:37 am »
var not allow call as Abs(Variant(-5)). And what about Abs(Variant('-5'))?
Correct. Never seen anyone do that though....

Quote
I suggest the following version
The (or at least my) aim was to prevent:
Code: Pascal  [Select][+][-]
  1.   WriteLn(Abs('hello world'));
  2.  
from compiling.

Bart already expressed that it would be more welcome to have a compile time generated error (and not a runtime generated error).

I don't believe we are able to solve it this way and instead requires some changes in compiler.

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: ABS truncates a Variant float ?
« Reply #37 on: February 26, 2018, 03:59:07 am »
With the above changes I made, it fails compile here when I do this

ABS('Hello World');

Compile Project, Target: project1.exe: Exit code 1, Errors: 1, Hints: 1
project1.lpr(27,20) Error: Variable identifier expected
project1.lpr(17,10) Hint: Found declaration: ABS(var Variant):Variant;

So how is this a problem?
 What I am finding is some strange happenings with the name scoping..
 System.abs is the same as Abs for other than Variant types but,
 
 System.Abs allows a constant while ABS does not and it calling the same one.
oh well


« Last Edit: February 26, 2018, 04:07:08 am by jamie »
The only true wisdom is knowing you know nothing

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: ABS truncates a Variant float ?
« Reply #38 on: February 26, 2018, 04:10:22 am »
With the above changes I made, it fails compile here when I do this

ABS('Hello World');

Compile Project, Target: project1.exe: Exit code 1, Errors: 1, Hints: 1
project1.lpr(27,20) Error: Variable identifier expected
project1.lpr(17,10) Hint: Found declaration: ABS(var Variant):Variant;

So how is this a problem?
 What I am finding is some strange happenings with the name scoping..
 System.abs is the same as Abs for other than Variant types but,
 
 System.Abs allows a constant while ABS does not and it calling the same one.
oh well
does it compile for
Code: Pascal  [Select][+][-]
  1.   abs(variant(35.45))
  2.  
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: ABS truncates a Variant float ?
« Reply #39 on: February 26, 2018, 04:16:34 am »
Ok, the OVERLOAD is needed on the prototype
 compiler is getting confused when doing the System.ABS(-5) and ABS(-5), that works now for
non Variant types

 I can live wth needing to pass a living variant to the ABS functions, the others still work old
way..

 A comment here:
 
 Variants are more of a runtime type and can change so is having it caught at runtime just for the
Variant types is such a bad idea?
« Last Edit: February 26, 2018, 04:22:36 am by jamie »
The only true wisdom is knowing you know nothing

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: ABS truncates a Variant float ?
« Reply #40 on: February 26, 2018, 03:35:58 pm »
Well, if you are going to code
Code: Pascal  [Select][+][-]
  1.   V := Abs(Variant(1.23));
Then you might as well leave out the Variant cast.

Bart

 

TinyPortal © 2005-2018