# Trouble with Decimals

This is a discussion on Trouble with Decimals within the C++ Programming forums, part of the General Programming Boards category; I was wondering if there was a way to format a number that already has decimals to not have the ...

1. ## Trouble with Decimals

I was wondering if there was a way to format a number that already has decimals to not have the decimals. However, I want the numbers behind the decimal point to still be there and I want no rounding. For instance, the number is 452.40. I want it display like this:

0000045240

I know how to add the zeros to the beginning to the number but I'm not sure if there is actually a way of removing the decimal from the number without having the number round. Anyone's help would be greatly appreciated as I have searched everywhere and have not found anything remotely close to what I want to do. My code looks like this:

sprintf(OString,"%010s\n", LPCTSTR(ProjTDue1));

ProjTDue1 is the variable in which I am trying to remove the decimal.

Thank you in advance for any help!

2. I think the problem is your belief in the existence of 452.40. If we assume that floats are stored in the machine in IEEE format (which, LPCTSTR makes me think Windows, and I'm pretty sure virtually every Windows machine is using IEEE), then what you think of as "452.40" is actually 1.11000100011001100110011 (binary) times 2^8, or 111000100.011001100110011 binary, which is close to 452.40 but not actually equal.

If, for instance, this is supposed to represent money, then using float/double in the first place was incorrect.

Edit: I suppose I should say I didn't do that myself; I got the numbers from http://babbage.cs.qc.edu/IEEE-754/Decimal.html

3. Well, what is the type of ProjTDue1?

And yes, rounding is the standard approach.

4. Code:
```#include <iostream>
#include <locale>
#include <iomanip>

class singing_numbers : public std::numpunct<char>
{
protected:
char do_decimal_point() const { return 7; }
};

int main() {
std::locale local(std::locale(""), new singing_numbers());
std::cout.imbue(local);
std::cout << std::setfill('0') << std::setw(11) << std::fixed << std::setprecision(2) << 452.40 << '\n';
}```

5. ## Type

ProjTDue1 is actually declared as a string because this program actually reads values in from an excel spreadsheet. Then I take the values from the spreadsheet and print them to a text pad formatted to the way he needs it. What it is is basically a tax statement program. When I was asked to do this I was not sure if there was a way to do this in C++. In VB6 the only way I could think of was to run through the number one digit at a time to find the decimal place and remove it. I was not sure if there was an easier way to do this in C++, plus they definitely want no rounding since this is dealing with property values and any rounding could be bad. Thanks!

6. Just multiply by 100.

Although it is possible to replace the radix point with a different character, there doesn't seem to be support for removing it completely.

7. ## Thank You

I feel really dumb now. I don't know why I didn't think about that. I guess I was just trying to make it more complicated than it actually was.

8. Originally Posted by anon

Code:
```#include <iostream>
#include <locale>
#include <iomanip>

class singing_numbers : public std::numpunct<char>
{
protected:
char do_decimal_point() const { return 7; }
};

int main() {
std::locale local(std::locale(""), new singing_numbers());
std::cout.imbue(local);
std::cout << std::setfill('0') << std::setw(11) << std::fixed
<< std::setprecision(2) << 452.40 << '\n';
}```
This will print the bell character instead of a radix point. It will look right, but will make a sound every time such a number is printed.

Unless you are writing to a file, in which case any editor will print some sort of font dependent character.

9. Originally Posted by ls1211
ProjTDue1 is actually declared as a string because this program actually reads values in from an excel spreadsheet. Then I take the values from the spreadsheet and print them to a text pad formatted to the way he needs it. What it is is basically a tax statement program. When I was asked to do this I was not sure if there was a way to do this in C++. In VB6 the only way I could think of was to run through the number one digit at a time to find the decimal place and remove it. I was not sure if there was an easier way to do this in C++, plus they definitely want no rounding since this is dealing with property values and any rounding could be bad. Thanks!
When you say "string" I assume you mean std::string, in which case the cast doesn't make sense (use string::data() and drop the cast). Or perhaps you meant char*? In that case, you still don't need the cast. Anyway, since you're (presumably) using C++, there's really no need for unsafe functions like XXXprintf anyway - stringstreams, iostreams, and the like are much safer and also much more flexible as well.

Ok, so assuming you *really* don't need to verify the data (eg: that it is in fact a float, will always have at least two digits after the decimal, etc) an easy way to do it is:

1) Place the data into an std::string
2) Get the position ('pos') of the decimal point with std::string::find
3) Pass 'pos' to std::string::erase (eg: my_string.erase( pos, 1 ))
4) Add 2 to 'pos'
5) Pass 'pos' to std::string::resize

EDIT: Come to think of it, you should add 2 to pos. I'm not at a compiler right now to verify that, but I'm pretty sure that's right...

10. Originally Posted by Sebastiani
When you say "string" I assume you mean std::string, in which case the cast doesn't make sense (use string::data() and drop the cast). Or perhaps you meant char*? In that case, you still don't need the cast. Anyway, since you're (presumably) using C++, there's really no need for unsafe functions like XXXprintf anyway - stringstreams, iostreams, and the like are much safer and also much more flexible as well.

Ok, so assuming you *really* don't need to verify the data (eg: that it is in fact a float, will always have at least two digits after the decimal, etc) an easy way to do it is:

1) Place the data into an std::string
2) Get the position ('pos') of the decimal point with std::string::find
3) Pass 'pos' to std::string::erase
4) Increment 'pos'
5) Pass 'pos' to std::string::resize
I think you're thinking of the remove algorithm. For string::erase, you don't need to resize the container after removal. Although I'm not sure why you would resize to pos+1 anyway.

I'd just use string::replace to remove the radix point if I were using this approach.

EDIT: if you're trimming everything passed the hundredths place, you would add 2. But if the number is already of that precision, then you don't need to trim anything.

11. Yes, I was assumming the number could have lot's of trailing digits - hence the resize. Otherwise, you're right, he could skip the resize (or just use replace).

Popular pages Recent additions