single/double precision - external dll
single/double precision - external dll
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.
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.
-
- Super Administrator
- Posts: 4573
- Joined: Wed Mar 05, 2003 3:10 am
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
...
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
...
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.
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.
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.
/*
Advice to posters (it really helps us to help you)
http://www.ventanasystems.co.uk/forum/v ... f=2&t=4391
Blog: http://blog.metasd.com
Model library: http://models.metasd.com
Bookmarks: http://delicious.com/tomfid/SystemDynamics
*/
Advice to posters (it really helps us to help you)
http://www.ventanasystems.co.uk/forum/v ... f=2&t=4391
Blog: http://blog.metasd.com
Model library: http://models.metasd.com
Bookmarks: http://delicious.com/tomfid/SystemDynamics
*/
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
Is there a special reason that you need double precision?
Tom
/*
Advice to posters (it really helps us to help you)
http://www.ventanasystems.co.uk/forum/v ... f=2&t=4391
Blog: http://blog.metasd.com
Model library: http://models.metasd.com
Bookmarks: http://delicious.com/tomfid/SystemDynamics
*/
Advice to posters (it really helps us to help you)
http://www.ventanasystems.co.uk/forum/v ... f=2&t=4391
Blog: http://blog.metasd.com
Model library: http://models.metasd.com
Bookmarks: http://delicious.com/tomfid/SystemDynamics
*/
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.
/*
Advice to posters (it really helps us to help you)
http://www.ventanasystems.co.uk/forum/v ... f=2&t=4391
Blog: http://blog.metasd.com
Model library: http://models.metasd.com
Bookmarks: http://delicious.com/tomfid/SystemDynamics
*/
Advice to posters (it really helps us to help you)
http://www.ventanasystems.co.uk/forum/v ... f=2&t=4391
Blog: http://blog.metasd.com
Model library: http://models.metasd.com
Bookmarks: http://delicious.com/tomfid/SystemDynamics
*/
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
Tom
/*
Advice to posters (it really helps us to help you)
http://www.ventanasystems.co.uk/forum/v ... f=2&t=4391
Blog: http://blog.metasd.com
Model library: http://models.metasd.com
Bookmarks: http://delicious.com/tomfid/SystemDynamics
*/
Advice to posters (it really helps us to help you)
http://www.ventanasystems.co.uk/forum/v ... f=2&t=4391
Blog: http://blog.metasd.com
Model library: http://models.metasd.com
Bookmarks: http://delicious.com/tomfid/SystemDynamics
*/
-
- Senior Member
- Posts: 1107
- Joined: Wed Mar 12, 2003 2:46 pm
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.
-
- Senior Member
- Posts: 1107
- Joined: Wed Mar 12, 2003 2:46 pm
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 260 times
-
- Senior Member
- Posts: 1107
- Joined: Wed Mar 12, 2003 2:46 pm
-
- Senior Member
- Posts: 1107
- Joined: Wed Mar 12, 2003 2:46 pm
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.
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.
-
- Newbie
- Posts: 1
- Joined: Tue Jan 17, 2017 6:30 am
- Vensim version: PLE+
Re: single/double precision - external dll
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
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