Recent

Author Topic: val return code  (Read 4080 times)

ALLIGATOR

  • Sr. Member
  • ****
  • Posts: 469
  • FPC git[main] Lazarus git[main] 💪🐯💪
Re: val return code
« Reply #15 on: July 10, 2026, 08:58:24 pm »
but what about the claim
Quote
No, Val does not use exceptions...

But Val doesn't even use exceptions)

The exception occurs outside the Val function

Paolo

  • Hero Member
  • *****
  • Posts: 771
Re: val return code
« Reply #16 on: July 10, 2026, 09:05:08 pm »
Take care that since Delphi 12.x (I don't remember wich) the floating points behave like IEE754 without exceptions. All flag are masked by default.
..and it is a very bad decision.

LeP

  • Guest
Re: val return code
« Reply #17 on: July 10, 2026, 09:47:37 pm »
Take care that since Delphi 12.x (I don't remember wich) the floating points behave like IEE754 without exceptions. All flag are masked by default.
..and it is a very bad decision.

Why ? that breaks old code and this is true ... but everything should work as it does now, and had for a long time.
And you can always use unmasked exception in the code to come back.

Now you can write math operations without worry about exception.
I think it's a good thing, not weird

Paolo

  • Hero Member
  • *****
  • Posts: 771
Re: val return code
« Reply #18 on: July 10, 2026, 09:58:17 pm »
Quote
Now you can write math operations without worry about exception.

So, it is better having a wrong computation result and going on with it silently in the code ?

Maybe everyone has its preferences.


LeP

  • Guest
Re: val return code
« Reply #19 on: July 10, 2026, 10:13:51 pm »
Quote
Now you can write math operations without worry about exception.
So, it is better having a wrong computation result and going on with it silently in the code ?
Maybe everyone has its preferences.

You don't have wrong computational.
Before that you had to check every single operation or put a try along a gruop of math.
Now you have simply the results that IEE754 said. And you can check when you want ... ie for INF, NAN, etc ... if that's the case.

If one want to check every single operation with a try, you can do.

It's like the exception on the normal code: do you want to have a result (status) when you call a function or better to have an exception ?

There is time for exceptions and time for results, but for sure now one can choose.

Before that the maths operations didn't work well in all cases, now they work ... or should work.

Paolo

  • Hero Member
  • *****
  • Posts: 771
Re: val return code
« Reply #20 on: July 10, 2026, 10:40:09 pm »
Quote
You don't have wrong computational.
I am not god yet! Something can go wrong...
Quote
Now you have simply the results that IEE754 said
Yes, and for example NaN can happily go around...

Quote
There is time for exceptions and time for results
Fully agreed

My point is, unless I misunderstanding something, I prefer separate computational logic with "try.." instead having mixed it with check controls. And more important intercept exception as soon as possible.

Paolo

  • Hero Member
  • *****
  • Posts: 771
Re: val return code
« Reply #21 on: July 10, 2026, 10:42:56 pm »
Try is used to sorround large block of computational task not single operation, where it cannot have sense.

Thaddy

  • Hero Member
  • *****
  • Posts: 19625
  • Glad to be alive.
Re: val return code
« Reply #22 on: July 10, 2026, 10:43:45 pm »
Take care that since Delphi 12.x (I don't remember wich) the floating points behave like IEE754 without exceptions. All flag are masked by default.
..and it is a very bad decision.
No, because their main platform also works that way. Not only their compiler. Also the msvc compilers.
Practice vs theory. Happens all the time.
And the mask can be set to whatever you want. Even on per routine basis.
It is also documented:
https://www.freepascal.org/docs-html/rtl/math/setexceptionmask.html

So what's the fuzz all about?
« Last Edit: July 10, 2026, 10:48:13 pm by Thaddy »
Any "programmer" that knows only one programming language is not a programmer

Paolo

  • Hero Member
  • *****
  • Posts: 771
Re: val return code
« Reply #23 on: July 10, 2026, 10:58:32 pm »
Quote
So what's the fuzz all about?
Nothing... just to discuss about that..  :D

avk

  • Hero Member
  • *****
  • Posts: 837
Re: val return code
« Reply #24 on: July 12, 2026, 11:42:21 am »
...
But Val doesn't even use exceptions)

The exception occurs outside the Val function

How did you come to this conclusion?

BTW, another example:
Code: Pascal  [Select][+][-]
  1. ...
  2. begin
  3.   WriteLn('FPC-', {$i %FPCVersion}, ' ', {$i %FPCTargetCPU}, '-', {$i %FPCTargetOs});
  4.   s := '-42e308';
  5.   DoTest(s);
  6.   WriteLn;
  7.   s := '-42e30800';
  8.   DoTest(s);
  9. end.    
  10.  
>>>
Code: [Select]
FPC-3.3.1 i386-Win32
Input: -42e308
EOverflow on call Val()
Code: 0
Output bits: 01618BB00040CCE6
Conversion failure

Input: -42e30800
Conversion success
Output bits: FFF0000000000000
Output:                     -Inf

ALLIGATOR

  • Sr. Member
  • ****
  • Posts: 469
  • FPC git[main] Lazarus git[main] 💪🐯💪
Re: val return code
« Reply #25 on: July 12, 2026, 12:32:39 pm »
How did you come to this conclusion?
I just debugged it step by step in the debugger

ALLIGATOR

  • Sr. Member
  • ****
  • Posts: 469
  • FPC git[main] Lazarus git[main] 💪🐯💪
Re: val return code
« Reply #26 on: July 12, 2026, 12:38:40 pm »
How did you come to this conclusion?

Another option is to modify the function like this:

https://editor.mergely.com/t51aQd5F

Code: Pascal  [Select][+][-]
  1. function TryStrToDouble(const s: string; out d: Double): Boolean;
  2. var
  3.   q: QWord absolute d;
  4.   c: Integer;
  5.   f80: Extended;
  6. begin
  7.   WriteLn('Input: ', s);
  8.   Result := False;
  9.   try
  10.     Val(s, f80, c);
  11.     d := f80;
  12.     d := f80; // UPD! twice
  13.     Result := c = 0;
  14.   except
  15.     on e: Exception do begin
  16.       WriteLn(e.ClassName, ' on call Val()');
  17.       WriteLn('Code: ', c);
  18.       WriteLn('Output bits: ', q.ToHexString(16));
  19.     end;
  20.   end;
  21. end;
  22.  

« Last Edit: July 12, 2026, 12:51:32 pm by ALLIGATOR »

avk

  • Hero Member
  • *****
  • Posts: 837
Re: val return code
« Reply #27 on: July 12, 2026, 01:04:05 pm »
...
I just debugged it step by step in the debugger

Val() is a pseudo-procedure that the compiler expands into some code depending on the type of the input parameters, and fpc_val_real_shortstr is just a part of it, returning the result as a float80 on the top of the FPU stack. This result still needs to be extracted, converted to float64, and written to the address passed in the second parameter.
So, Val() is this entire code:
Code: ASM  [Select][+][-]
  1. ...
  2. ; [14] Val(s, d, c);
  3.                 lea     edx,dword ptr [ebp-16]
  4.                 mov     eax,dword ptr [ebp-4]
  5.                 call    fpc_val_real_shortstr
  6.                 fstp    qword ptr [ebp-24]
  7.                 fld     qword ptr [ebp-24]
  8.                 mov     eax,dword ptr [ebp-8]
  9.                 fstp    qword ptr [eax]
  10.  

ALLIGATOR

  • Sr. Member
  • ****
  • Posts: 469
  • FPC git[main] Lazarus git[main] 💪🐯💪
Re: val return code
« Reply #28 on: July 12, 2026, 01:40:21 pm »
Val() is a pseudo-procedure that the compiler expands into some code depending on the type of the input parameters, and fpc_val_real_shortstr is just a part of it, returning the result as a float80 on the top of the FPU stack. This result still needs to be extracted, converted to float64, and written to the address passed in the second parameter.
I agree

So, Val() is this entire code:
Code: ASM  [Select][+][-]
  1. ...
  2. ; [14] Val(s, d, c);
  3.                 lea     edx,dword ptr [ebp-16]
  4.                 mov     eax,dword ptr [ebp-4]
  5.                 call    fpc_val_real_shortstr
  6.                 fstp    qword ptr [ebp-24]
  7.                 fld     qword ptr [ebp-24]
  8.                 mov     eax,dword ptr [ebp-8]
  9.                 fstp    qword ptr [eax]
I disagree)

That's because the function returns a ValReal type. And at this stage, everything is fine

In other words, if you accept the result as a ValReal, everything will be fine

But if you accept the result as a Double - that means you've essentially performed two operations implicitly: calling Val and an implicit type conversion

Code: Pascal  [Select][+][-]
  1. Function fpc_Val_Real_ShortStr(const s : shortstring; out Code : ValSInt): ValReal;

Again, it turns out that the exception handling function itself does not generate exceptions (at least in this case)

By the way, it’s probably worth categorizing exceptions by source type here as well: hardware-related and software-generated

 

TinyPortal © 2005-2018