473,583 Members | 3,413 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Fixed precision floating point and locale facets

Hello,

I'm writing a fixed-precision floating point class, based on the ideas
in the example fixed_pt class in the "Practical C++ Programming" book
by Steve Oualline (O' Reilly). This uses a long int to store the
value, and the precision (number of decimal points) is variable (it's
a templated class):

template <size_t _decimal_places = 4>
class FixedFloat {
private:
/// The integer value.
long int m_value;
[...]
};

The value is set from a string (FixedFloat<2> ff = "12.43";), or via
overloaded istream/ostream extraction and insertion operators (<< and
) which are templated friend functions (implicit conversion to/from

double is not allowed due to precision loss.). The conversion between
long int and string forms is done in the latter functions.

To output a number, I was manually splitting up the number into whole
and fractional parts and processing them separately, using '.' as the
decimal point symbol. However, I've just discovered the existence of
std::locale::nu meric and std::locale::mo netary locale facets, and the
num_put() and num_get() methods. Ideally, I'd like to use these
functions for the the conversions (FixedFloat -> std::string).
However, their support for the standard numeric types (int, long,
float, double) is hard-coded into the class. I can't risk conversion
to a supported type such as double, due to loss of precision (0.60
would becomes 0.59 on my i686-pc-linux-gnu arch), and they will be
used to process financial data!

Is it possible to extend these to support my FixedFloat class?

Is it reasonable to derive from std::num_put in this case? I had a
look into the GNU libstdc++ headers to see if it was possible, but
they were hideously complex, and I'm not keen on using the internals
such as num_put<>::do_p ut and __convert_from_ v(), since these are
presumably non-portable.

Lastly, are there any standard classes that do this sort of thing?
Many thanks!
Roger

--
Roger Leigh

Printing on GNU/Linux? http://gimp-print.sourceforge.net/
GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.
Jul 19 '05 #1
4 7831
"Roger Leigh" <${******@inval id.whinlatter.u klinux.net.inva lid> wrote in message
news:87******** ****@wrynose.wh inlatter.uklinu x.net...
To output a number, I was manually splitting up the number into whole
and fractional parts and processing them separately, using '.' as the
decimal point symbol. However, I've just discovered the existence of
std::locale::nu meric and std::locale::mo netary locale facets, and the
num_put() and num_get() methods. Ideally, I'd like to use these
functions for the the conversions (FixedFloat -> std::string).
However, their support for the standard numeric types (int, long,
float, double) is hard-coded into the class. I can't risk conversion
to a supported type such as double, due to loss of precision (0.60
would becomes 0.59 on my i686-pc-linux-gnu arch), and they will be
used to process financial data!

Is it possible to extend these to support my FixedFloat class?
It's possible, but probably not a rewarding exercise.
Is it reasonable to derive from std::num_put in this case? I had a
look into the GNU libstdc++ headers to see if it was possible, but
they were hideously complex, and I'm not keen on using the internals
such as num_put<>::do_p ut and __convert_from_ v(), since these are
presumably non-portable.
The do_put part is portable, the other isn't. But you're right to
observe that they're hideously complex.
Lastly, are there any standard classes that do this sort of thing?


You can pervert money_put and moneypunct to output a digit sequence
stored in a string, with a specified number of decimal places, commas
between thousands groups, etc.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Jul 19 '05 #2
"P.J. Plauger" <pj*@dinkumware .com> writes:
"Roger Leigh" <${******@inval id.whinlatter.u klinux.net.inva lid> wrote in message
news:87******** ****@wrynose.wh inlatter.uklinu x.net...
To output a number, I was manually splitting up the number into whole
and fractional parts and processing them separately, using '.' as the
decimal point symbol. However, I've just discovered the existence of
std::locale::nu meric and std::locale::mo netary locale facets, and the
num_put() and num_get() methods. Ideally, I'd like to use these
functions for the the conversions (FixedFloat -> std::string).
However, their support for the standard numeric types (int, long,
float, double) is hard-coded into the class. I can't risk conversion
to a supported type such as double, due to loss of precision (0.60
would becomes 0.59 on my i686-pc-linux-gnu arch), and they will be
used to process financial data!

Is it possible to extend these to support my FixedFloat class?
It's possible, but probably not a rewarding exercise.


If I'm correct here, I would have to add my own custom locale facet(s)
to allow this, but I'd need to do this manually for each locale I want
to use, which would be a pain.

[do_put() and __convert_from_ v()] The do_put part is portable, the other isn't. But you're right to
observe that they're hideously complex.


OK.
Lastly, are there any standard classes that do this sort of thing?


You can pervert money_put and moneypunct to output a digit sequence
stored in a string, with a specified number of decimal places, commas
between thousands groups, etc.


This looks like what I'll do. I'll derive a "Money" class from
FixedFloat and do that in there, overriding the standard ostream<< and
istream>> operators.

I've attached a copy of the working class, and a small driver program
to show it in action (sorry it's so long). I have a few questions
about this:

1. Is the header file OK style-wise? Is there anything wrong that I
should not be doing?

2. I've noticed that the modulus (operator%) member and friend
functions can be out by a small factor e.g. 0.0001 in a 4
d.p. precision class. With fixed-point arithmetic, should I be
doing anything to correct this? Is it actually incorrect? For
some reason, I couldn't get the "real" % operator to work, so had
to resort to the hack that actually gets used (subtracting the
result of division and subsequent multiplication from the original
value).

3. Looking at the compiled binary, the FixedFloat symbols have weak,
rather than vague linkage. I thought that /all/ templated class
methods and functions would be vague. This is with GCC 3.3.2, GNU
ld 2.14.90.0.6 and binutils 2.14.90.0.6-5 on i686-pc-linux-gnu
using ELF binary format (this is probably OT).

4. In the stream output and extraction friend classes, is the use of
locales correct? I've not used locales (in C++) before, and I've
done this using the Josuttis Standard Library book.
Many thanks for your time,
Roger
----begin main.cc----
#include <iostream>

#include "fixedfloat .h"

int main()
{
std::locale::gl obal(std::local e(""));
std::cout.imbue (std::locale()) ;

FixedFloat<4> f1("4.1246");
FixedFloat<4> f2("2.3443");

std::cout << f1 << std::endl;
std::cout << f2 << std::endl;

FixedFloat<4> n(f1);
FixedFloat<4> o;
o = f2;

std::cout << n << std::endl;
std::cout << o << std::endl;

std::cout << "Signedness \n";
std::cout << +f1 << std::endl;
std::cout << -f1 << std::endl;

std::cout << "Binary arithmetic\n";
std::cout << f1 << "-" << f2 << "=" << f1-f2 << "\n";
std::cout << f1 << "+" << f2 << "=" << f1+f2 << "\n";
std::cout << f1 << "*" << f2 << "=" << f1*f2 << "\n";
std::cout << f1 << "/" << f2 << "=" << f1/f2 << "\n";
std::cout << f1 << "%" << f2 << "=" << f1%f2 << "\n";
std::cout << -f1 << "/" << f2 << "=" << (-f1)/f2 << "\n";
std::cout << -f1 << "%" << f2 << "=" << (-f1)%f2 << "\n";

std::cout << "Logic\n";
std::cout << f1 << "==" << f1 << "=" << (f1==f1) << "\n";
std::cout << f1 << "==" << f2 << "=" << (f1==f2) << "\n";
std::cout << f1 << "!=" << f1 << "=" << (f1!=f1) << "\n";
std::cout << f1 << "!=" << f2 << "=" << (f1!=f2) << "\n";

std::cout << "Unary arithmetic\n";
FixedFloat<4> f3 = f1;
f3 += FixedFloat<4>(" 2.3430");
std::cout << f1 << "+=2.3430" << "=" << f3 << "\n";

f3 = f1;
f3 -= FixedFloat<4>(" 2.3430");
std::cout << f1 << "-=2.3430" << "=" << f3 << "\n";

f3 = f1;
f3 *= FixedFloat<4>(" 2.3430");
std::cout << f1 << "*=2.3430" << "=" << f3 << "\n";

f3 = f1;
f3 /= FixedFloat<4>(" 2.3430");
std::cout << f1 << "/=2.3430" << "=" << f3 << "\n";

f3 = f1;
f3 %= FixedFloat<4>(" 2.3430");
std::cout << f1 << "%=2.3430" << "=" << f3 << "\n";

f3 = f1;
++f3;
std::cout << "++" << f1 << "=" << f3 << "\n";

f3 = f1;
std::cout << f1 << "++" << "=" << f3++ << " (before)\n";
std::cout << f1 << "++" << "=" << f3 << " (after)\n";

f3 = f1;
--f3;
std::cout << "--" << f1 << "=" << f3 << "\n";

f3 = f1;
std::cout << f1 << "--" << "=" << f3-- << " (before)\n";
std::cout << f1 << "--" << "=" << f3 << " (after)\n";

return 1;
}
----end main.cc----

----begin fixedfloat.h----
// fixed floating point class -*- C++ -*-
// $Id: template.cc,v 1.1 2003/09/14 21:56:55 roger Exp $
//
// Copyright (C) 2003 Roger Leigh.
//
// Authors: Roger Leigh <ro***@whinlatt er.uklinux.net>

#include <iomanip>
#include <istream>
#include <locale>
#include <ostream>
#include <sstream>

/**
* A class to represent fixed floating point numbers with high
* accuracy.
* The float and double data types to not offer enough accuracy when
* dealing with some types of data, for example currency values, since
* they cannot garuantee that a particular value is representable in
* their floating-point binary format. This class will garuantee
* accuracy, with the restriction that there is a fixed number of
* decimal places after the decimal point. Internally, the value is
* held as a long integer.
*
* Conversion to and from the double data type is not implicit--this
* must be done using the methods provided. However, conversion to
* and from std::string is possible.
*/
template <size_t _decimal_places = 2>
class FixedFloat {
public:
/// The type used internally to hold fixed floating point values.
typedef long int value_type;

private:
/// The integer value.
value_type m_value;
/// The correction factor.
value_type m_correction;

/**
* Compute the correction factor.
* The correction value is used to correct multiplication and
* division of fixed point numbers.
*/
void compute_correct ion()
{
m_correction = 1;
for (int i = 0; i < _decimal_places ; ++i)
m_correction *= 10;
}

/**
* The constructor.
* The initial value is set to the value provided.
* @param value the initial value.
*/
FixedFloat(valu e_type value):
m_value(value)
{
compute_correct ion();
}

public:
/**
* The constructor.
* The initial value is set to 0.
*/
FixedFloat():
m_value(0)
{
compute_correct ion();
}

/**
* The constructor.
* The initial value is set to the value provided. If there are too
* many numbers after the decimal place, they will be rounded to the
* nearest representable value (0 to 4 are rounded down, 5 to 9 are
* rounded up.
* @param value the initial value.
*/
FixedFloat(cons t std::string& value)
{
compute_correct ion();

std::istringstr eam input(value);
input >> *this;
}

/**
* The copy constructor.
*/
FixedFloat(cons t FixedFloat& original):
m_value(origina l.m_value),
m_correction(or iginal.m_correc tion)
{}

/// The destructor.
~FixedFloat()
{}
FixedFloat& operator = (const FixedFloat& rhs)
{
m_value = rhs.m_value;
return *this;
}

FixedFloat& operator += (const FixedFloat& rhs)
{
m_value += rhs.m_value;
return *this;
}

FixedFloat& operator -= (const FixedFloat& rhs)
{
m_value -= rhs.m_value;
return *this;
}

FixedFloat& operator *= (const FixedFloat& rhs)
{
m_value *= rhs.m_value;
m_value /= m_correction;
return *this;
}

FixedFloat& operator /= (const FixedFloat& rhs)
{
m_value *= m_correction;
m_value /= rhs.m_value;
return *this;
}

FixedFloat& operator %= (const FixedFloat& rhs)
{
*this = (*this - ((*this / rhs) * rhs));
return *this;
}

FixedFloat& operator ++ ()
{
m_value += m_correction;
return *this;
}

FixedFloat operator ++ (int)
{
FixedFloat ret(*this);
m_value += m_correction;
return ret;
}

FixedFloat& operator -- ()
{
m_value -= m_correction;
return *this;
}

FixedFloat operator -- (int)
{
FixedFloat ret(*this);
m_value -= m_correction;
return ret;
}

friend FixedFloat<_dec imal_places> operator +<> (const FixedFloat<_dec imal_places>& lhs,
const FixedFloat<_dec imal_places>& rhs);

friend FixedFloat<_dec imal_places> operator -<> (const FixedFloat<_dec imal_places>& lhs,
const FixedFloat<_dec imal_places>& rhs);

friend FixedFloat<_dec imal_places> operator *<> (const FixedFloat<_dec imal_places>& lhs,
const FixedFloat<_dec imal_places>& rhs);

friend FixedFloat<_dec imal_places> operator /<> (const FixedFloat<_dec imal_places>& lhs,
const FixedFloat<_dec imal_places>& rhs);

friend FixedFloat<_dec imal_places> operator %<> (const FixedFloat<_dec imal_places>& lhs,
const FixedFloat<_dec imal_places>& rhs);

friend bool operator ==<> (const FixedFloat<_dec imal_places>& lhs,
const FixedFloat<_dec imal_places>& rhs);

friend bool operator !=<> (const FixedFloat<_dec imal_places>& lhs,
const FixedFloat<_dec imal_places>& rhs);

friend FixedFloat<_dec imal_places> operator -<> (const FixedFloat<_dec imal_places>& rhs);

friend FixedFloat<_dec imal_places> operator +<> (const FixedFloat<_dec imal_places>& rhs);

friend std::ostream& operator <<<> (std::ostream& output_stream,
const FixedFloat<_dec imal_places>& rhs);

friend std::istream& operator >><> (std::istream& input_stream,
FixedFloat<_dec imal_places>& rhs);

}; // class FixedFloat<>
// Friend functions.

template <size_t _decimal_places >
inline FixedFloat<_dec imal_places> operator + (const FixedFloat<_dec imal_places>& lhs,
const FixedFloat<_dec imal_places>& rhs)
{
return FixedFloat<_dec imal_places>(lh s.m_value + rhs.m_value);
}

template <size_t _decimal_places >
inline FixedFloat<_dec imal_places> operator - (const FixedFloat<_dec imal_places>& lhs,
const FixedFloat<_dec imal_places>& rhs)
{
return FixedFloat<_dec imal_places>(lh s.m_value - rhs.m_value);
}

template <size_t _decimal_places >
inline FixedFloat<_dec imal_places> operator * (const FixedFloat<_dec imal_places>& lhs,
const FixedFloat<_dec imal_places>& rhs)
{
return FixedFloat<_dec imal_places>((l hs.m_value * rhs.m_value) / lhs.m_correctio n);
}

template <size_t _decimal_places >
inline FixedFloat<_dec imal_places> operator / (const FixedFloat<_dec imal_places>& lhs,
const FixedFloat<_dec imal_places>& rhs)
{
return FixedFloat<_dec imal_places>((l hs.m_value * lhs.m_correctio n) / rhs.m_value);
}

template <size_t _decimal_places >
inline FixedFloat<_dec imal_places> operator % (const FixedFloat<_dec imal_places>& lhs,
const FixedFloat<_dec imal_places>& rhs)
{
return FixedFloat<_dec imal_places>(lh s - ((lhs / rhs) * rhs));
}

template <size_t _decimal_places >
inline bool operator == (const FixedFloat<_dec imal_places>& lhs,
const FixedFloat<_dec imal_places>& rhs)
{
return lhs.m_value == rhs.m_value;
}

template <size_t _decimal_places >
inline bool operator != (const FixedFloat<_dec imal_places>& lhs,
const FixedFloat<_dec imal_places>& rhs)
{
return lhs.m_value != rhs.m_value;
}

template <size_t _decimal_places >
inline FixedFloat<_dec imal_places> operator - (const FixedFloat<_dec imal_places>& rhs)
{
return FixedFloat<_dec imal_places>(-rhs.m_value);
}

template <size_t _decimal_places >
inline FixedFloat<_dec imal_places> operator + (const FixedFloat<_dec imal_places>& rhs)
{
return FixedFloat<_dec imal_places>(rh s.m_value);
}

template <size_t _decimal_places >
inline std::ostream& operator << (std::ostream& output_stream,
const FixedFloat<_dec imal_places>& rhs)
{
bool negative = false;
if (rhs.m_value < 0)
negative = true;

typename FixedFloat<_dec imal_places>::v alue_type whole_part
= rhs.m_value / rhs.m_correctio n;
typename FixedFloat<_dec imal_places>::v alue_type fractional_part
= rhs.m_value - (whole_part * rhs.m_correctio n);

if (whole_part < 0) // turn into a positive number
whole_part = -whole_part;
if (fractional_par t < 0) // turn into a positive number
fractional_part = -fractional_part ;

std::ostringstr eam s;
s.copyfmt(outpu t_stream);
s.width(0);

if (negative == true)
s << '-'; // output sign, if needed
s << whole_part; // output the whole part
if (_decimal_place s > 0) // output the fractional part, including decimal point
{
std::ostringstr eam fractional_stri ng;
fractional_stri ng.imbue(std::l ocale::classic( )); // "plain" numbers
fractional_stri ng << fractional_part ;

s << std::use_facet< std::numpunct<c har> >(s.getloc()).d ecimal_point()
<< std::setw(_deci mal_places) << std::setfill('0 ')
<< fractional_stri ng.str();
}
output_stream << s.str();

return output_stream;
}

template <size_t _decimal_places >
inline std::istream& operator >> (std::istream& input_stream,
FixedFloat<_dec imal_places>& rhs)
{
bool negative = false;
typename FixedFloat<_dec imal_places>::v alue_type whole_part = 0;
char decimal_point;
typename FixedFloat<_dec imal_places>::v alue_type fractional_part = 0;

std::istream::s entry stream_sentry(i nput_stream, true);

if (stream_sentry)
{
// Get the whole part of the number
if (input_stream.b ad())
return input_stream;

// Check signedness (would be lost if value is < 1, since -0 == 0)
if (input_stream.p eek() == '+')
negative = false;
else if (input_stream.p eek() == '-')
negative = true;

input_stream >> whole_part;
whole_part *= rhs.m_correctio n;
if (whole_part < 0) // turn into a positive number
whole_part = -whole_part;
if (_decimal_place s > 0)
{
// Get the decimal point.
if (input_stream.b ad())
return input_stream;

input_stream >> decimal_point;
// Check that the decimal point was the correct type for this locale
if (decimal_point != std::use_facet< std::numpunct<c har> >(input_stream. getloc()).decim al_point())
{
rhs.m_value = 0;
input_stream.se tstate(std::ios ::failbit);
}

// Get the fractional part of the number
fractional_part = 0;
for (size_t i = _decimal_places ; i > 0; --i)
{
if (input_stream.b ad())
return input_stream;

char decimal_char = '0';
input_stream >> decimal_char;
if (decimal_char < '0' || decimal_char > '9')
{
rhs.m_value = 0;
input_stream.se tstate(std::ios ::failbit);
return input_stream;
}
size_t decimal_number = decimal_char - '0';

size_t multiply_factor = 1;
for (int j = 1; j < i; ++j)
multiply_factor *= 10;

fractional_part += (decimal_number * multiply_factor );
}
}
if (negative == false)
rhs.m_value = whole_part + fractional_part ;
else
rhs.m_value = - (whole_part + fractional_part );
}
else
input_stream.se tstate(std::ios ::failbit);

return input_stream;
}
----end fixedfloat.h----

--
Roger Leigh

Printing on GNU/Linux? http://gimp-print.sourceforge.net/
GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.
Jul 19 '05 #3
"Roger Leigh" <${******@inval id.whinlatter.u klinux.net.inva lid> wrote in
message news:87******** ****@wrynose.wh inlatter.uklinu x.net...
You can pervert money_put and moneypunct to output a digit sequence
stored in a string, with a specified number of decimal places, commas
between thousands groups, etc.
This looks like what I'll do. I'll derive a "Money" class from
FixedFloat and do that in there, overriding the standard ostream<< and
istream>> operators.

I've attached a copy of the working class, and a small driver program
to show it in action (sorry it's so long). I have a few questions
about this:

1. Is the header file OK style-wise? Is there anything wrong that I
should not be doing?


Sorry, I don't have time to critique what you've done in detail.
Instead I supply below a sample use of money_put and moneypunct
I published in The C/C++ Users Journal (April 1998), for comparative
anatomy studies.
2. I've noticed that the modulus (operator%) member and friend
functions can be out by a small factor e.g. 0.0001 in a 4
d.p. precision class. With fixed-point arithmetic, should I be
doing anything to correct this? Is it actually incorrect? For
some reason, I couldn't get the "real" % operator to work, so had
to resort to the hack that actually gets used (subtracting the
result of division and subsequent multiplication from the original
value).
Not such a hack, since it's built on the basic definition. It's very
hard to avoid 1 or even 2 ulp errors with this sort of math. That's
why people are reconsidering decimal floating point these days.
3. Looking at the compiled binary, the FixedFloat symbols have weak,
rather than vague linkage. I thought that /all/ templated class
methods and functions would be vague. This is with GCC 3.3.2, GNU
ld 2.14.90.0.6 and binutils 2.14.90.0.6-5 on i686-pc-linux-gnu
using ELF binary format (this is probably OT).
I don't know anything about these forms of linkage. But I think
"vague linkage" is a wonderfully surreal term, FWIW.
4. In the stream output and extraction friend classes, is the use of
locales correct? I've not used locales (in C++) before, and I've
done this using the Josuttis Standard Library book.


If it works... The example below uses our magic locale macros to
deal with VC++ V6.0 compiler limitations.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
--------------

#include <iomanip>
#include <iostream>
#include <locale>
using namespace std;

// MONETARY TYPES
typedef long double MoneyVal;

class Money {
public:
Money(MoneyVal v)
: value(v) {}
operator MoneyVal() const
{return (value); }
private:
MoneyVal value;
};

// Money INSERTER
template<class _E, class _Tr> inline
basic_ostream<_ E, _Tr>& operator<<(
basic_ostream<_ E, _Tr>& _O, Money _Y)
{typedef ostreambuf_iter ator<_E, _Tr> _Iter;
typedef money_put<_E, _Iter> _Mput;

ios_base::iosta te _St = ios_base::goodb it;
const typename basic_ostream<_ E, _Tr>::sentry _Ok(_O);
if (_Ok)
{try
{const _Mput& _Fac =
_USEFAC(_O.getl oc(), _Mput);
if (_Fac.put(_Iter (_O.rdbuf()),
(_O.flags() & ios_base::showp os) != 0,
_O, _O.fill(), _Y).failed())
_St |= ios_base::badbi t; }
catch (...)
{_O.setstate(io s_base::badbit, true); }}
_O.setstate(_St );
return (_O); }

// moneypunct FOR USA LOCALE
money_base::pat tern mon_fmt = {
money_base::sym bol, money_base::spa ce,
money_base::sig n, money_base::val ue};

class Mymoneypunct
: public moneypunct<char , false> {
protected:
virtual char do_decimal_poin t() const
{return ('.'); }
virtual char do_thousands_se p() const
{return (','); }
virtual string do_grouping() const
{return (string("\3")); }
virtual string do_curr_symbol( ) const
{return (string("$")); }
virtual string do_positive_sig n() const
{return (string("")); }
virtual string do_negative_sig n() const
{return (string("-")); }
virtual int do_frac_digits( ) const
{return (2); }
virtual pattern do_pos_format() const
{return (mon_fmt); }
virtual pattern do_neg_format() const
{return (mon_fmt); }
};

int main()
{locale loc = _ADDFAC(locale: :classic(), new Mymoneypunct);
cout.imbue(loc) ;

cout << showbase << setw(20) << internal << setfill('*')
<< Money(123456789 .0) << endl;
return (0); }
Jul 19 '05 #4
"P.J. Plauger" <pj*@dinkumware .com> writes:
"Roger Leigh" <${******@inval id.whinlatter.u klinux.net.inva lid> wrote in
message news:87******** ****@wrynose.wh inlatter.uklinu x.net...
2. I've noticed that the modulus (operator%) member and friend
functions can be out by a small factor e.g. 0.0001 in a 4
d.p. precision class. With fixed-point arithmetic, should I be
doing anything to correct this? Is it actually incorrect? For
some reason, I couldn't get the "real" % operator to work, so had
to resort to the hack that actually gets used (subtracting the
result of division and subsequent multiplication from the original
value).


Not such a hack, since it's built on the basic definition. It's very
hard to avoid 1 or even 2 ulp errors with this sort of math. That's
why people are reconsidering decimal floating point these days.


I noticed your post in the thread about this in comp.lang.c.mod erated.
This looks quite exciting, and I look forward to using this in the
future, when it's implemented. Are there any C++ classes implementing
this yet?

I've got hold of the specs from the IBM Hursley site, and also some
docs about BCD arithmetic. If it's not too hairy, I might be able to
knock out a C++ class for this myself, but I'm not a mathematician and
worry about the subtleties I might get wrong when dealing with
financial stuff.

For the time being, I've been looking for other classes and libraries
out there. GNU MP (libgmp) looks like a decent choice, since it can
do arbitrary-precision computation, and it has a C++ binding. I
wouldn't have to worry about overflow or underflow if I used this.
However, the values still have to be stored in a fixed-precision
backend database (PostgreSQL numeric type), so having a
fixed-precision class to directly represent the database types would
be highly advantageous.
3. Looking at the compiled binary, the FixedFloat symbols have weak,
rather than vague linkage. I thought that /all/ templated class
methods and functions would be vague. This is with GCC 3.3.2, GNU
ld 2.14.90.0.6 and binutils 2.14.90.0.6-5 on i686-pc-linux-gnu
using ELF binary format (this is probably OT).


I don't know anything about these forms of linkage. But I think
"vague linkage" is a wonderfully surreal term, FWIW.


:-)

With weak linkage, if the same symbol is present in multiple
translation units, only one will be resolved by the runtime linker.
In contrast, vague linkage means that additional copies are thrown
away by the linker at link time, e.g. multiple template instantiations
emitted for every translation unit (I believe this is called COMDAT on
some platforms). I expected the latter behaviour, but didn't get it
with my own templates (although I see it for all the Standard Library
ones, such as basic_ofstream< > et. al.). I'll have to investigate
this one further.
4. In the stream output and extraction friend classes, is the use of
locales correct? I've not used locales (in C++) before, and I've
done this using the Josuttis Standard Library book.


If it works... The example below uses our magic locale macros to
deal with VC++ V6.0 compiler limitations.


Thanks, that was quite informative. I'll be using GCC and GNU
libstdc++5 on all our target platforms, including Windows, so I won't
have to deal with VC++, at least initially. It would merit further
investigation if it provided a POSIX/SUSv3 layer like Cygwin or MinGW.
I require the Gtkmm and PostgreSQL client libraries for my current
project, though.
--
Roger Leigh

Printing on GNU/Linux? http://gimp-print.sourceforge.net/
GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.
Jul 19 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
1997
by: Cagdas Ozgenc | last post by:
Greetings. I am confused about C++ standard library locale stuff. It seems as if the implementations of locales are not part of the library, but only some guideline classes are there. What is the standard conformant way of formatting and parsing locale specific date, time, strings with various character encoding, etc. Thanks
7
3864
by: klaus hoffmann | last post by:
Is it possible to convert 2 characters from a stringstream to an integer without using an intermediate a 2-bytes string ? The following fragment doesn't work #include <iostream> #include <fstream> #include <sstream> #include <iomanip> #include <string> using namespace std;
9
4177
by: pout | last post by:
What are the purposes of fixed-point? When should it be used? I read: #define Int2Fixed(x) (((long)(short)x) << 16) and the fixed-point in 16.16 format. Does the 16 in the MACRO refer to integer or decimal part? For example, if in 8.24, should the macro be: #define Int2Fixed(x) (((long)(short)x) << 24)?
3
23733
by: Madan | last post by:
Hi all, I had problem regarding float/double arithmetic only with + and - operations, which gives inaccurate precisions. I would like to know how the arithmetic operations are internally handled by C# or they are hardware (processor) dependent. Basic addition operation errors, for ex: 3.6 - 2.4 = 1.19999999999 or 1.20000000003 There are the...
4
5814
by: riya1012 | last post by:
hello guys, I need some help from you. I am doing a DSP project and for that I need to do some C coding for the conversion of sample data which is in floating point representation to fixed point representation. the sample data is in floating point like 0.224128 2.299965 0.448350 -1.779926
1
1955
by: Joseph Turian | last post by:
Hi, How can I change the default floating point precision for the duration of execution? i.e. that *every* ostream I subsequently create will have this precision? Thanks Joseph
137
6620
by: mathieu.dutour | last post by:
Dear all, I want to do multiprecision floating point, i.e. I want to go beyond single precision, double precision and have quadruple precision, octuple precision and the like, and possibly with high speed. What would be the possible alternatives? Thanks for any help
0
2551
by: Charles Coldwell | last post by:
James Kanze <james.kanze@gmail.comwrites: True, with some additional considerations. The commonly used IEEE 754 floating point formats are single precision: 32 bits including 1 sign bit, 23 significand bits (with an implicit leading 1, for 24 total), and 8 exponent bits double precision: 64 bits including 1 sign bit, 52 significand...
2
1883
by: Rob Clewley | last post by:
Dear Pythonistas, How many times have we seen posts recently along the lines of "why is it that 0.1 appears as 0.10000000000000001 in python?" that lead to posters being sent to the definition of the IEEE 754 standard and the decimal.py module? I am teaching an introductory numerical analysis class this fall, and I realized that the best...
0
8176
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
1
7931
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
8191
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
6578
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5699
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
5370
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3816
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
1
1426
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
1154
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.