single/double precision - external dll

Use this forum to post Vensim related questions.
Post Reply
etam

single/double precision - external dll

Post by etam »

I create some external functions and wanted to test if the used tools are coherent in number precision.
I wrote a simple model and I got some strange result, which I can't explain.

The model should show something like this:
input: 1.00000000000000000000
input: 12.00000000000000000000
input: 123.00000000000000000000
input: 1234.00000000000000000000
...

The strange thing that both with single and double precision, the problems occur in the same place:
input: 12345678.00000000000000000000
input: 123456789.00000000000000000000
input: 1234567920.00000000000000000000
input: 12345679361.00000000000000000000

I would have though that for double precision it would happen later.

I've checked as much as I could, but haven't find any answer.
Any idea?

My model:
-------------------------------------------------------
val=val dly * 10 + MODULO(Time, 10) ~~|
val ext=PREC(val) ~~|
val dly=DELAY FIXED (val,1,0) ~~|

FINAL TIME = 20 ~~|
INITIAL TIME = 0 ~~|
SAVEPER = TIME STEP ~~|
TIME STEP = 1 ~~|
-------------------------------------------------------

PREC is really simple:
-------------------------------------------------------
CFUNCTION int VEFCC vensim_external(VV *val, int nval, int funcid) {
...
case PREC_FUNC: rval = PREC(val[0].val);
...
}

double PREC(double x) {
char tmp_str[1024];
sprintf(tmp_str, "input: %1.20f", x);
vs_error_message(NOT_ERROR, tmp_str);
return x;
} // double PREC(double x)
-------------------------------------------------------

I use the Vensim version 5.10c.
Administrator
Super Administrator
Posts: 4573
Joined: Wed Mar 05, 2003 3:10 am

Post by Administrator »

I cannot understand what the problem is here.

The line
sprintf(tmp_str, "input: %1.20f", x);

prints a number with 20 decimal places. So the results you have look ok.

What exactly is the problem?
etam

Post by etam »

It's a precision test, which means the float/double differences should have shown up.
The results should be:
---- for float (single precision) - that's OK
...
1234567
12345678
123456792
1234567936
...

---- for double (double precision) - that's NOT OK in the Vensim model
1234567
12345678
123456789
1234567890
12345678901
123456789012
1234567890123
12345678901234
123456789012345
1234567890123456
12345678901234568
123456789012345700
...
etam

Post by etam »

More clear:

I don't understand, why are the model results
...
input: 12345678.00000000000000000000
input: 123456789.00000000000000000000
input: 1234567920.00000000000000000000
input: 12345679361.00000000000000000000
...
instead of
...
input: 12345678.00000000000000000000
input: 123456789.00000000000000000000
input: 1234567890.00000000000000000000
input: 12345678901.00000000000000000000
...
using Vensim double precision.
tomfid
Administrator
Posts: 3806
Joined: Wed May 24, 2006 4:54 am

Post by tomfid »

As I recall, models can run internally at dp, but results in .vdf files are still stored single precision. That might explain the output you're seeing.
etam

Post by etam »

Yes, I know that.

But calling an external function has nothing to do with vdf files, am I right?
That should be internal.

Also definitions (see COMPREAL) suggest that there are significant differences between single and double precision.

However, there is no difference in the example. How come?
tomfid
Administrator
Posts: 3806
Joined: Wed May 24, 2006 4:54 am

Post by tomfid »

If your test is performing an ordinary simulation, the information is coming from a .vdf, and therefore subject to the limitation. I'm not sure if that's also true if you're extracting output from a live synthesim run, but my guess is that it is.

Is there a special reason that you need double precision?

Tom
tomfid
Administrator
Posts: 3806
Joined: Wed May 24, 2006 4:54 am

Post by tomfid »

Wait a sec ... I wasn't paying close enough attention ... I assumed you were using the .dll, but actually you're writing an external function - so, you're right: vdfs are not involved.
tomfid
Administrator
Posts: 3806
Joined: Wed May 24, 2006 4:54 am

Post by tomfid »

My guess is that the issue has something to do with compiler headers or definitions, but I'm not sure - Bob would have to weigh in on that.

Tom
etam

Post by etam »

Thanks, I really don't know what the problem is.
One more thing, the val[0].val in the VEFCC vensim_external is a double variable, for sure (checked with sizeof), so the reason must be deeper inside I guess.
bob@vensim.com
Senior Member
Posts: 1107
Joined: Wed Mar 12, 2003 2:46 pm

Post by bob@vensim.com »

If you enter something like 12345678912 into a model equation that will be truncated to a single precision number, as that is the way it is stored internally within the model. To get more precision going in you will need to use a .cin file. This will be read as a simulation sets up and will be retained in its full precision for computations.
etam

Post by etam »

Yes I know that, but if you have a look at my model (first post), it's not the case.

-------------------------------------------------------
val=val dly * 10 + MODULO(Time, 10) ~~|
val dly=DELAY FIXED (val,1,0) ~~|
val ext=PREC(val) ~~|
-------------------------------------------------------
etam

Post by etam »

Maybe it is truncated within DELAY FIXED?
etam

Post by etam »

OK, that's the reason. DELAY FIXED truncates double values to single.
I checked with a different model, and that works.
bob@vensim.com
Senior Member
Posts: 1107
Joined: Wed Mar 12, 2003 2:46 pm

Post by bob@vensim.com »

it is not DELAY FIXED - see the attached model and (in next message) .cin file - you should see difference go from -5 to 12.
Attachments
dbltest.mdl
(1.39 KiB) Downloaded 259 times
bob@vensim.com
Senior Member
Posts: 1107
Joined: Wed Mar 12, 2003 2:46 pm

Post by bob@vensim.com »

cin file
Attachments
dbltest.cin
(52 Bytes) Downloaded 263 times
etam

Post by etam »

You are right, DELAY FIXED does not truncate the values.

But I guess it looks them up from a storage (in case of data), which is truncated, and that's why the result.

Am I right?

First I thought for some reason that all time slots are in the memory, but to store and look them up is more logically.
bob@vensim.com
Senior Member
Posts: 1107
Joined: Wed Mar 12, 2003 2:46 pm

Post by bob@vensim.com »

Hi Etam,

I belatedly realized that my example was not correct, I need to delay the inputs, then take the difference. There results are different.

So you are right the DELAY... functions are truncating. That is a bug and will be fixed for the next release. It is also true that values brought in via GET XLS... were being truncated. That is by design, but will also be changed.

What will remain true is that stored values will be truncated.
georgemacin
Newbie
Posts: 1
Joined: Tue Jan 17, 2017 6:30 am
Vensim version: PLE+

Re: single/double precision - external dll

Post by georgemacin »

The decimal keyword denotes a 128-bit data type. Compared to floating-point types, the decimal type has a greater precision and a smaller range, which makes it suitable for financial and monetary calculations. Precision is the main difference where double is a double precision (64 bit) floating point data type and decimal is a 128-bit floating point data type.

Double - 64 bit (15-16 digits)

Decimal - 128 bit (28-29 significant digits)

So Decimals have much higher precision and are usually used within monetary (financial) applications that require a high degree of accuracy. But in performance wise Decimals are slower than double and float types. Double Types are probably the most normally used data type for real values, except handling money. In general, the double type is going to offer at least as great precision and definitely greater speed for arbitrary real numbers. More about...Double vs Decimal

George
Post Reply