Precision Change - Float to String

Discussion in 'C++' started by Bryan R. Meyer, May 21, 2004.

  1. I am a relatively new C++ programmer and am attempting to write a
    function that takes a number of type float and adds commas to it in
    the appropriate places. In order to manipulate the number to add the
    commas, I convert it to a string (specifically a char[] rather than an
    actual string object) using the
    gcvt function as shown below.

    char amt[50];
    gcvt(amount,50,amt);

    The problem I run into is a change in the precision. If amount is of
    type float and has a value of 264588.44 then the code above results in
    the string amt being "264588.4375". Note the change in the decimal
    portion of the number; I don't want this. I want the original number
    in the string. People have suggested using sprintf(). However,
    sprintf() won't help me since I don't know the number of decimal
    places in advance of the conversion.

    Is there any way around this? Keep in mind that I don't know how many
    decimal places I will need.

    Thanks,
    Bryan
     
    Bryan R. Meyer, May 21, 2004
    #1
    1. Advertising

  2. "Bryan R. Meyer" <> wrote...
    > I am a relatively new C++ programmer and am attempting to write a
    > function that takes a number of type float and adds commas to it in
    > the appropriate places. In order to manipulate the number to add the
    > commas, I convert it to a string (specifically a char[] rather than an
    > actual string object) using the
    > gcvt function as shown below.
    >
    > char amt[50];
    > gcvt(amount,50,amt);
    >
    > The problem I run into is a change in the precision. If amount is of
    > type float and has a value of 264588.44 then the code above results in
    > the string amt being "264588.4375". Note the change in the decimal
    > portion of the number; I don't want this.


    How do you know that it "has a value of 264588.44" unless you convert
    it to a string (which you have) and read the result? And if such
    conversion does not give you what you think it should give you, what
    reason do you have to doubt it?

    > I want the original number
    > in the string.


    What is "the original number"? How did it come into being? Why do
    consider it "the original"? Is that a constant you wrote in the C++
    source file? Do you know that many numbers cannot be represented
    precisely in a double or a float? Take 0.1 for example. It cannot
    be represented in a limited amount of binary digits. So, the real
    number is not what you think it is, but it's kinda close. And when
    time comes to convert it back into characters, some part of the
    number is lost, in your case 0.0025. That's rounding and truncation
    happening in memory when you store a double (or float) value in some
    limited number of bits.

    > People have suggested using sprintf(). However,
    > sprintf() won't help me since I don't know the number of decimal
    > places in advance of the conversion.
    >
    > Is there any way around this? Keep in mind that I don't know how many
    > decimal places I will need.


    If you don't know how many you'll need, how do you know that what you're
    getting is wrong?

    V
     
    Victor Bazarov, May 21, 2004
    #2
    1. Advertising

  3. "Victor Bazarov" <> wrote in message news:<omgrc.89178$xw3.5049169@attbi_s04>...

    > What is "the original number"? How did it come into being? Why do
    > consider it "the original"? Is that a constant you wrote in the C++
    > source file? Do you know that many numbers cannot be represented
    > precisely in a double or a float?


    I am very well aware that floating-point numbers cannot be represented
    exactly. Simply for testing purposes, my "original number" is a
    constant in my program. I wanted to convert the number 264588.44 from
    a floating-point number to a string. I attempted to use the gcvt
    function to do this and it returned a string with the vaue
    "264588.4375". This is unacceptable in the context of my program.

    My intention is to write a function that takes a parameter of type
    float and adds commas to the number in the appropriate places. This
    is achieved by first converting the float to a string. It does not
    suit me that after conversion to a string that I will be adding commas
    to a number that was different than the original passed into the
    function. I was merely trying to determine if there was some sort of
    workaround for this. I do not know all of the limitations of C++.

    > If you don't know how many you'll need, how do you know that what you're
    > getting is wrong?


    The example I gave was just a constant. If I have a variable num of
    type float with the value 35453.3466 then I don't want to add the
    commas to a number that is different, say 35453.34656576. This holds
    true for any floating-point number that may be passed into the
    function.

    I am just a newbie in C++. I do not know every single thing the
    language can and cannot do for me. I was simply trying to get some
    insight into a problem I was having and wanted some input.

    Thanks,
    Bryan
     
    Bryan R. Meyer, May 22, 2004
    #3
  4. Bryan R. Meyer

    Rolf Magnus Guest

    Bryan R. Meyer wrote:

    > "Victor Bazarov" <> wrote in message
    > news:<omgrc.89178$xw3.5049169@attbi_s04>...
    >
    >> What is "the original number"? How did it come into being? Why do
    >> consider it "the original"? Is that a constant you wrote in the C++
    >> source file? Do you know that many numbers cannot be represented
    >> precisely in a double or a float?

    >
    > I am very well aware that floating-point numbers cannot be represented
    > exactly. Simply for testing purposes, my "original number" is a
    > constant in my program. I wanted to convert the number 264588.44 from
    > a floating-point number to a string. I attempted to use the gcvt
    > function to do this and it returned a string with the vaue
    > "264588.4375". This is unacceptable in the context of my program.


    Maybe 264588.44 is one of those numbers that cannot be exactly
    represented in a double.

    > My intention is to write a function that takes a parameter of type
    > float


    A float or a double? Note that the precision of float is typically very
    limited. On most systems, that precision is less than the 8 digits that
    are required for 264588.44. There is most often no good reason to
    prefer float over double anyway.

    > and adds commas to the number in the appropriate places. This
    > is achieved by first converting the float to a string. It does not
    > suit me that after conversion to a string that I will be adding commas
    > to a number that was different than the original passed into the
    > function. I was merely trying to determine if there was some sort of
    > workaround for this. I do not know all of the limitations of C++.


    This is not a limitation of C++. It's rather a limitation of the way
    floating point values are stored in computers. You claim to have
    understood that, but it doesn't seem you really have. Anyway, you could
    round the value to some number of digits, but I don't know how you
    could do that if you don't know how many digits to round to.

    >> If you don't know how many you'll need, how do you know that what
    >> you're getting is wrong?

    >
    > The example I gave was just a constant. If I have a variable num of
    > type float with the value 35453.3466 then I don't want to add the
    > commas to a number that is different, say 35453.34656576. This holds
    > true for any floating-point number that may be passed into the
    > function.


    Well, you can't just expect precision to come back magically after it
    was reduced.
     
    Rolf Magnus, May 22, 2004
    #4
  5. Bryan R. Meyer

    Julie Guest

    "Bryan R. Meyer" wrote:
    >
    > I am a relatively new C++ programmer and am attempting to write a
    > function that takes a number of type float and adds commas to it in
    > the appropriate places. In order to manipulate the number to add the
    > commas, I convert it to a string (specifically a char[] rather than an
    > actual string object) using the
    > gcvt function as shown below.
    >
    > char amt[50];
    > gcvt(amount,50,amt);
    >
    > The problem I run into is a change in the precision. If amount is of
    > type float and has a value of 264588.44 then the code above results in
    > the string amt being "264588.4375". Note the change in the decimal
    > portion of the number; I don't want this. I want the original number
    > in the string. People have suggested using sprintf(). However,
    > sprintf() won't help me since I don't know the number of decimal
    > places in advance of the conversion.
    >
    > Is there any way around this? Keep in mind that I don't know how many
    > decimal places I will need.


    Short answer: no, there isn't a way around it as you describe using floating
    point.

    Long answer (and then some): go read the VB sub-thread.

    Possible solution: move away from a floating point number and use (or create) a
    fixed-point number. Once you have a fixed-point number, you won't have to
    worry about loss/change of precision inherent w/ floating point, and then you
    can convert to string and manipulate as you deem necessary.
     
    Julie, May 22, 2004
    #5
  6. Bryan R. Meyer wrote:

    > I am a relatively new C++ programmer and am attempting to write a
    > function that takes a number of type float and adds commas to it
    > in the appropriate places. In order to manipulate the number
    > to add the commas, I convert it to a string
    > (specifically a char[] rather than an actual string object)
    > using the gcvt function as shown below.
    >
    > char amt[50];
    > gcvt(amount, 50, amt);
    >
    > The problem I run into is a change in the precision.
    > If amount is of type float and has a value of 264588.44
    > then the code above results in the string amt being "264588.4375".


    But you requested 50 digits and you only got 10.
    What does that tell you?

    > Note the change in the decimal portion of the number;


    You probably meant the fractional part.

    > I don't want this.
    > I want the original number in the string.


    I don't think so.
    I think you want the original number in amount.

    > People have suggested using sprintf().
    > However, sprintf() won't help me since I don't know
    > the number of decimal places in advance of the conversion.
    >
    > Is there any way around this? Keep in mind that
    > I don't know how many decimal places I will need.


    > cat main.cc

    #include <iostream>
    #include <stdlib.h>

    int
    main(int argc, char* argv[]) {
    const
    double amount = 264588.437543210987654321;
    const
    size_t ndigit = 50;
    char amt[ndigit];
    std::cout << gcvt(amount, ndigit, amt)
    << " = gcvt(amount, ndigit, amt)" << std::endl;
    std::cout << gcvt(amount, 8, amt)
    << " = gcvt(amount, 8, amt)" << std::endl;
    return 0;
    }

    > g++ -Wall -ansi -pedantic -o main main.cc
    > ./main

    264588.43754321098 = gcvt(amount, ndigit, amt)
    264588.44 = gcvt(amount, 8, amt)

    It works just fine for me.
     
    E. Robert Tisdale, May 22, 2004
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Thinkit
    Replies:
    2
    Views:
    306
    Thinkit
    Nov 28, 2003
  2. bd
    Replies:
    0
    Views:
    651
  3. Replies:
    3
    Views:
    362
    Roger Miller
    Aug 11, 2007
  4. Carsten Fuchs
    Replies:
    45
    Views:
    1,607
    James Kanze
    Oct 8, 2009
  5. Anton81

    Float precision and float equality

    Anton81, Dec 5, 2009, in forum: Python
    Replies:
    26
    Views:
    1,155
Loading...

Share This Page