Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

96 bits representing a decimal to string

37 views
Skip to first unread message

Christopher Pisz

unread,
Oct 14, 2014, 3:33:20 PM10/14/14
to
How would you go about converting a structure that is 96 bits plus a the
sign and an int for the scale into a string?

Its a fabulous Windows type and I can't seem to find anything on it.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms221061(v=vs.85).aspx

I could fairly easily do 32 bits or even 64, but I am not sure how to go
about 96 because anything I stuff it into previous to putting it in a
stringstream wouldn't be large enough and I'd think I would have to put
it into something before flipping the sign and putting in a decimal place.

I might see if I can just insert all the numbers into a stringstream and
then insert a sign into the front and a decimal into its place using
string random access and insert operators in the meanwhile. I wonder if
anyone has suggestions on this in the meanwhile.




Rick C. Hodgin

unread,
Oct 14, 2014, 3:46:27 PM10/14/14
to
If you can't find support anywhere else...

There's a well-proven library called MPFR. You could create an arbitrary
length integer, set it to 0, save it to memory, and then populate over
those 96 bits, and load it back in that way, and then use their MPFR
equivalent printf() functions.

There are various C++ wrapper classes for it. Google "MPFR C++ wrapper"
and you'll find some.

Best regards,
Rick C. Hodgin

Christopher Pisz

unread,
Oct 14, 2014, 3:47:55 PM10/14/14
to
Here is my first attempt. unfortunately, I don't even know how to
initialize this monstrosity. I am going to try and get some test data to
compare against and verify.

I realize this is a Windows type and I should (and am) asking on the
Windows forums, but just looking for the native C++ tips here, since
there might be a better solution than using stringstreams and string
operators.


//------------------------------------------------------------------------------
std::string DecimalToString(const DECIMAL & decimal)
{
std::ostringstream converter;

converter << decimal.Hi32;
converter << decimal.Lo64;

if( !decimal.sign )
{
converter.str().insert(converter.str().begin(), '+');
}
else
{
converter.str().insert(converter.str().begin(), '-');
}

converter.str().insert(converter.str().back() - (decimal.scale +
1), '.');

return converter.str();
}

Victor Bazarov

unread,
Oct 14, 2014, 4:14:08 PM10/14/14
to
From what I know about 'ostringstream', its 'str' member function
returns a temporary. So, even if you call 'insert' on that temporary in
the right place, it's not going to change the 'converter's own internal
string. I recommend you to manipulate a string, not the stream, in your
'DecimalToString' function. Something like

converter << ...
converter << ...

std::string output(converter.str());
if (...
output.insert(...
else
...

return output;
}

V
--
I do not respond to top-posted replies, please don't ask

Robert Wessel

unread,
Oct 14, 2014, 5:42:26 PM10/14/14
to
Assuming performance is not too critical, something like:

void cvtDECIMAL(DECIMAL &dec)
{
ULONG hi, mid, low, c;
ULONGLONG t;
int i;

hi = dec.Hi32;
mid = dec.Mid32;
low = dec.Lo32;

for (i=0; i<29; i++)
{
c = hi % 10;
hi /= 10;

t = c * ULONG_MAX; // I don't remember the exact macro name
t += mid;
c = t % 10;
mid = t / 10;

t = c * ULONG_MAX; // I don't remember the exact macro name
t += low;
c = t % 10;
low = t / 10;

output("0"+c);
}
}

gets you most of the way there, using basic long division. It happens
to output the digits in reverse, does not apply the scale factor, does
not suppress leading zeros, and doesn't output the sign, but those
should be easy to deal with.

Nobody

unread,
Oct 16, 2014, 9:51:48 PM10/16/14
to
On Tue, 14 Oct 2014 14:33:06 -0500, Christopher Pisz wrote:

> How would you go about converting a structure that is 96 bits plus a the
> sign and an int for the scale into a string?

This doesn't include the scale or sign, but it embodies the general
principle behind converting a multi-word integer to decimal:

#include <cstdint>
#include <iostream>
#include <string>

void print128(std::ostream& os, uint64_t hi, uint64_t lo)
{
static const uint64_t k_d = 0x1999999999999999ULL; // = 2^64 / 10
static const uint64_t k_r = 6; // = 2^64 % 10

std::string result;
while (hi > 0 || lo > 0) {
uint64_t hi_d = hi / 10;
uint64_t hi_r = hi % 10;
uint64_t lo_d = lo / 10;
uint64_t lo_r = lo % 10;
uint64_t d = (hi_r * k_r + lo_r) % 10;
result.push_back('0' + d);
hi = hi_d;
lo = (hi_r*k_d + lo_d) + (lo_r + hi_r*k_r) / 10;
}
for (auto it = result.crbegin(); it != result.crend(); ++it)
os << *it;
os << std::endl;
}


0 new messages