[Coin-discuss] Problem with MPS export / MSVC

Matthew Saltzman mjs at ces.clemson.edu
Thu Mar 25 12:58:06 EST 2004


On Thu, 25 Mar 2004, Matthew Saltzman wrote:

> On Thu, 25 Mar 2004, Jörg Herbers wrote:
>
> > I encountered a problem when exporting an mps file via CoinMpsIO. I work on
> > Microsoft Visual Studio .NET 2003 which handles printf format specification
> > flags somewhat different from e.g. the gcc compiler. The problem is that
> > large "infinity" upper bounds are exported as "2.147484e+00", i.e. the
> > exponent is 0. CoinMpsIO::writeMps() takes the minimum over the given upper
> > bound and INT_MAX (2147483647). convertDouble() converts this to a string,
> > using format specification "%12.7g". The resulting string is cut after 12
> > characters according to the MPS specification for the BOUNDS section. But
> > while gcc converts INT_MAX into 2.147484e+09, MS VC7 (and equally MS VC6)
> > converts it into 2.147484e+009, and the final "9" at position 12 will be cut
> > afterwards. The Microsoft documentation says that the exponent will always
> > be typeset with three digits while gcc uses two digits for exponents <100. I
> > don’t know if the C++ standard defines a "correct" behaviour.
>
> printf() is a C function.  According to Harbison & Steele 4th ed., "The
> number of exponent digits is the same for all values and is the maximum
> needed to represent the range of the implementation's floating-point
> types."
>
> That would seem to indicate that gcc is in the wrong on this point.  On
> the other hand, it also means that field width 12 is not wide enough to
> hold DBL_MAX (1.797693e+308) to seven digits of precision anyway.  If the
> field width is forced to be 12 for MPS files, then the most we can
> guarantee is six digits of precision ("%12.6g" or just "%12g").

After about 30 seconds more reflection:

The maximum precision that you can guarantee to fit in a 12-character
field is five digits.  (I forgot the mantissa sign:  "%12.5g" yields
"-n.nnnne+ddd".)

If the value to the specified precision is too wide to fit in the field,
printf() *must* expand the field.  Truncating the field is *not* an
option.  If VC++ is doing the truncating, this is definitely a bug in
VC++.

If CoinMpsIO is doing the truncating, then it looks like the alternatives
are to drop back to five digits or to parse the value ourselves and allow
the precision to vary depending on whether the value is negative or has a
leading zero in the exponent.  It's not VC++-sepcific, though.  We need to
handle three-digit exponents correctly anyway.

>
> >
> > I have solved the problem in my COIN code, but I would clearly prefer a
> > general solution. Several ways are viable: On the one hand, the format
> > specifications could generally be changed to "%12.6g". On the other hand,
> > there could be a specific solution for the Microsoft compiler, e.g. by the
> > above reduction of significant digits or by a manipulation of the resulting
> > string, e.g. by something like
> >
> > #if defined(_MSC_VER)
> >     if ((outputValue[9] == '+') && (outputValue[10] == '0'))
> >       strcpy(&(outputValue[10]), &(outputValue[11]));
> > #endif
> >
> > I would be very glad if you could integrate a fix into the code.
> >
> > Thanks a lot,
> > Jörg
> >
> > _________________________________________________________________
> > Help STOP SPAM with the new MSN 8 and get 2 months FREE*
> > http://join.msn.com/?page=features/junkmail
> >
> > _______________________________________________
> > Coin-discuss mailing list
> > Coin-discuss at www-124.ibm.com
> > http://www-124.ibm.com/developerworks/oss/mailman/listinfo/coin-discuss
> >
>
>

-- 
		Matthew Saltzman

Clemson University Math Sciences
mjs AT clemson DOT edu
http://www.math.clemson.edu/~mjs



More information about the Coin-discuss mailing list