Interesting UV floating point issue

82 views
Skip to first unread message

James A

unread,
Dec 22, 2024, 1:40:15 PM12/22/24
to Pick and MultiValue Databases
We had an issue in production that was causing some processes to fail (because the value ends up being used in Java and throwing a rounding error); and it's taken my many hours to did through 5,000 lines of code to isolate the subtle interaction of a few values that caused the issue.

Code below: basically in some places the code uses '* 100' instead of 'iconv ... MR2'; which can result in an internal floating point number that's then put into strings with 14 digits of decimal numbers intact. (the code also used 'Precision 14' for legacy reasons: one of the fixes is just to use Precision 8 [the other fix is switch the code to 'iconv']).

The interesting part is that doing a 'matbuild' FROM a static array somehow changes the value in the static array!? That made this issue maddening since the code would skip the 'matbuild' for some cases which would then break; making it seem intermittent (and that code was separated by thousand of lines/separate programs).

-----------------------

  dim ARRAY.REC( 2 )

  precision 14  ;*  always '0' with 8
 
  mat ARRAY.REC = ''

  InternalValue    = 123739
  ExternalValue = 1237.39
 
  crt 'ExternalValue: ':ExternalValue
  crt 'InternalValue   : ':InternalValue
  crt
  crt 'Subtraction with * 100     : ':InternalValue - (ExternalValue * 100)
  crt 'Subtraction with iconv MD2 : ':InternalValue - iconv( ExternalValue, 'MD2')
 
  ARRAY.REC(1) = ExternalValue * 100
  crt 'Subtraction with Array     : ':InternalValue - ARRAY.REC(1)

  matbuild junk from ARRAY.REC  ;*  (matwrite also fixes it!)
 
  crt 'Subtraction after matbuild : ':InternalValue - ARRAY.REC(1)
  crt
stop


James A

unread,
Dec 22, 2024, 1:44:16 PM12/22/24
to Pick and MultiValue Databases

Forgot the output for those without UV handy (UV 11.3.5 on CentOS Linux)

ExternalValue: 1237.39
InternalValue   : 123739

Subtraction with * 100     : -0.00000000001455
Subtraction with iconv MD2 : 0
Subtraction with Array     : -0.00000000001455
Subtraction after matbuild : 0

Jim Idle

unread,
Dec 22, 2024, 2:36:05 PM12/22/24
to mvd...@googlegroups.com
UV handling of floating point and precision is essentially broken. To support this ‘take on it’ we had to do a lot of work in jBASE so we could port UV applications. 
Everything should be using scaled decimals and not precision in terms of floating point precision. IEEE floating point is inherently unstable when reforesting certain numbers. Divides by 3 and so on. You will get xxx.9999999 instead of xxx+1. All programmers should be aware of this, so you do well to bring it up here. 

Of course you should be using conversions anyway, as you point out. 

Jim

--
You received this message because you are subscribed to
the "Pick and MultiValue Databases" group.
To post, email to: mvd...@googlegroups.com
To unsubscribe, email to: mvdbms+un...@googlegroups.com
For more options, visit http://groups.google.com/group/mvdbms
---
You received this message because you are subscribed to the Google Groups "Pick and MultiValue Databases" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mvdbms+un...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/mvdbms/80dd6e0d-13bf-4963-bbea-f1a1185f849an%40googlegroups.com.

Wol

unread,
Dec 22, 2024, 4:34:07 PM12/22/24
to mvd...@googlegroups.com
On 22/12/2024 19:35, 'Jim Idle' via Pick and MultiValue Databases wrote:
> UV handling of floating point and precision is essentially broken. To
> support this ‘take on it’ we had to do a lot of work in jBASE so we
> could port UV applications.

iiui, back when we were on UV 9.6, I was (of course) interested in the
internals, and was left with the impression that UV was fairly
aggressive about caching numbers as IEEE. So basically UV very much does
stuff as computer floating point. Which was why max (and iirc default)
PRECISION was 14.

We'd moved from INFORMATION, which was all I'd used before that. And was
very much a "you get what you ask for" as regards precision (I think it
defaulted to 4dp). And when run on 50-series (ie it wasn't PI-Open) you
actually had special BCD microcode. So PI didn't do floating point, it
did BCD.

I don't know what other variants do, but given that everything in MV is
strings, it certainly seems as though BCD makes more sense than IEEE FP.

Cheers,
Wol

Jim Idle

unread,
Dec 23, 2024, 1:10:52 PM12/23/24
to mvd...@googlegroups.com
It’s closer to this: 


BCD is not used by any versions that I know of. Maybe PI did. 

--
You received this message because you are subscribed to
the "Pick and MultiValue Databases" group.
To post, email to: mvd...@googlegroups.com
To unsubscribe, email to: mvdbms+un...@googlegroups.com
For more options, visit http://groups.google.com/group/mvdbms
---
You received this message because you are subscribed to the Google Groups "Pick and MultiValue Databases" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mvdbms+un...@googlegroups.com.

Wols Lists

unread,
Dec 23, 2024, 1:33:10 PM12/23/24
to mvd...@googlegroups.com
On 23/12/2024 18:10, 'Jim Idle' via Pick and MultiValue Databases wrote:
> It’s closer to this:
>
> https://en.wikipedia.org/wiki/IEEE_854-1987 <https://en.wikipedia.org/
> wiki/IEEE_854-1987>
>
>
> BCD is not used by any versions that I know of. Maybe PI did.

A quick dig tells me that ieee_854 was first implemented in the HP75B,
which appears to date from 1984. I first met PI (version 5.4 iirc) in
1985. And I first met 50-series Pr1mes (a second hand 25/30) in 1982.

So PI is unlikely to have used 854 because it's quite a lot older.
Wikipedia tells me it was written in 1979 to run on 50-series. And it
certainly came with special microcode to enable some p-code instructions
to be optimised.

Cheers,
Wol
Reply all
Reply to author
Forward
0 new messages