Thread: Trouble with Decimals

  1. #1
    Registered User
    Join Date
    Sep 2007
    Location
    San Antonio, TX
    Posts
    3

    Question 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. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    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
    Last edited by tabstop; 09-11-2009 at 12:49 PM.

  3. #3
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Well, what is the type of ProjTDue1?

    And yes, rounding is the standard approach.

  4. #4
    The larch
    Join Date
    May 2006
    Posts
    3,573


    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';
    }
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  5. #5
    Registered User
    Join Date
    Sep 2007
    Location
    San Antonio, TX
    Posts
    3

    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. #6
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    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.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  7. #7
    Registered User
    Join Date
    Sep 2007
    Location
    San Antonio, TX
    Posts
    3

    Smile 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. #8
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by anon View Post


    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.
    Last edited by King Mir; 09-11-2009 at 01:24 PM.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  9. #9
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by ls1211 View Post
    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...
    Last edited by Sebastiani; 09-11-2009 at 01:32 PM.

  10. #10
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by Sebastiani View Post
    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.
    Last edited by King Mir; 09-11-2009 at 01:37 PM.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  11. #11
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    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 subscribe to a feed

Similar Threads

  1. Need help to show decimals
    By engstudent363 in forum C Programming
    Replies: 4
    Last Post: 02-19-2008, 04:13 PM
  2. Trouble with Decimals? =(
    By Junior89 in forum C++ Programming
    Replies: 5
    Last Post: 06-10-2007, 08:58 PM
  3. Replies: 6
    Last Post: 01-03-2007, 03:02 PM
  4. Help with Decimals
    By Deadlyaim in forum C++ Programming
    Replies: 8
    Last Post: 09-28-2006, 05:15 PM
  5. trouble scanning in... and link listing
    By panfilero in forum C Programming
    Replies: 14
    Last Post: 11-21-2005, 12:58 PM