Hi Chris,
I got some strange conversion errors, when i’m convert a float to a string value (like "XYZ: " + (string)floatValue)). I append a small experiment file which (hopefully) reproduce the error.
(in C):
aFloat = 0.9;
for (cx = 1; cx < 5; cx++) {
aFloat += 0.15;
aString = “=> " + (string)aFloat + " <=”; // this line is mWorks syntax
}
the results for aFloat: 1.05, 1.2, 1.35, 1.5, 1.65
the results for aString: “=> 1.05 <=”, “=> 1.2 <=”, “=> 1.349999999 <=”, “=> 1.499999997 <=”, “=> 1.64999995 <=”
I try many things and check this loop with an older and the actual 0.5 version of mWorks…
Lieben Gruß aus Göttingen
Ralf
Attachment: convert.xml (2.89 KB)
Hi Ralf,
I see what you’re saying, although I do get slightly different strings than you:
1.05
1.2
1.349999999999999
1.4999999999999998
1.6499999999999997
However, this isn’t an error, but rather a reflection of the fact that the numbers you’re using (0.9 and 0.15) can’t be represented exactly as double-precision floating-point values. The Python tutorial has a nice explanation of this, which is also fully applicable to C/C++ and MWorks. I’ve attached a short Python script that shows the issue in action. Here’s what it produces on my machine:
$ python2.6 float2string.py
0.90 => 0.90000000000000002
0.15 => 0.14999999999999999
1.05 => 1.05
1.20 => 1.2
1.35 => 1.3499999999999999
1.50 => 1.4999999999999998
1.65 => 1.6499999999999997
As noted in the tutorial, Python 2.7 does a better job with printing inexact floats, and we could probably adopt its approach in MWorks. Unfortunately, it doesn’t help much in this case:
$ python2.7 float2string.py
0.90 => 0.9
0.15 => 0.15
1.05 => 1.05
1.20 => 1.2
1.35 => 1.3499999999999999
1.50 => 1.4999999999999998
1.65 => 1.6499999999999997
Another option would be to support printf-style precision modifiers (or something equivalent) in MWorks, although that might be more trouble than it’s worth.
Chris
Attachment: float2string.py (183 Bytes)
Hi Chris,
thanks for the fast answer. The only thing I can say is: omg … I forgot the floating point problem…
I think a little bit about the problem. We use strings to automate things like the output of staircases or the input for psychometric functions (multiple parameter). Fixing the problem with a printf-function sounds great, but I see the trouble too…
Maybe, we can put the printf for conversion on the feature wish list for 0.5 final?
Mit sonnigen Gruß
Ralf
Maybe, we can put the printf for conversion on the feature wish list for 0.5 final?
I’ll have to think about how a printf-style function would fit in with the existing expression parser/syntax, but it should be possible. We could also opt to use less-than-full precision when converting floats to strings, as including 16 decimal places is undoubtedly overkill.
Chris
Hi Ralf,
I’ve added a new function, format()
, to the expression parser, which does printf-style string formatting. Usage is as you’d expect:
format("%d * %.2f = %s", 2, 3.0, "six") -> "2 * 3.00 = six"
I’ve attached a new version of your example experiment that shows it in action.
The actual formatting is handled by boost::format
. For details on the format string syntax, see the boost::format docs.
This should be available in the nightly build shortly.
Cheers,
Chris