Results 1 to 11 of 11

Thread: QStrings and Floats, Current Precision?

  1. #1
    Join Date
    Jun 2012
    Posts
    98
    Thanks
    11
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default QStrings and Floats, Current Precision?

    So I'm down to my last little bug in a keypad I built; getting the precision to not be...exorbitant. I've checked through the docs and haven't found any methods that detect the number of significant digits. I'm getting ready to write a substantial bit of code (at least by compared to the task at hand) and adding potentially needless state to an object to deal with keeping track. I can do this, but I'm just curious beforehand if there's any sort of detect precision functionality in Qt.

    Note: I know it will figure it out itself when it converts to scientific notation (or at least it'll figure it out good enough.) My algorithm to deal with it basically entails chopping off the E(blah) part, dealing with the current decimal if needed (moving or deleting it) and appending (or prepending) zeros to my QString so it reads the way I want it to (I.E. so it reads just like the 'f' argument would, but with a precision dependent on the input.) This may not work; as I'm assuming Qt doesn't use scientific notation with some set number of decimals, but uses it like actual scientific notation.

    Thanks!

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QStrings and Floats, Current Precision?

    Qt has nothing to do with this. You are using floating point numbers as defined by the language (C++) and all rules that apply to that language, apply to your Qt program. "Notations" are just what they are called -- ways to enter and display numbers. They have nothing to do with how the number is really kept in memory. As the name suggests, you are dealing with "floating point" numbers (i.e. the precision is not statically defined but rather dependent on the value itself). Maybe what you want is "fixed point" arithmetics. Unfortunately C/C++ don't have such a data type built in so you have to either roll out your own or use a library that provides such a data type.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QStrings and Floats, Current Precision?

    @OP
    Maybe I don't understand correctly but if what you are concerned about is displaying float number with a fixed trailing numbers after the point, have a look at QString::arg() overloads.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  4. #4
    Join Date
    Jun 2012
    Posts
    98
    Thanks
    11
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QStrings and Floats, Current Precision?

    I thank you, but I think I've been unclear. I understand I'm dealing with floats (or similarly doubles). I'm trying to display a *dynamic* number of significant digits

    -Qt defines significant digits as digits after the decimal (just to make sure we're on the same page.)
    -Qt QStrings default to showing 5 significant digits if using the 'f' argument
    -QStrings (seem) to default to showing 3 significant digits if using the 'e'/'E' arguments

    What I'm trying to do is when the user enters a number: 1.1, that when they scale it E5, it will say 110000, not 110000.0 (or .00, .000, .0000, .00000, etc..) and that when they scale it down E2 it will say (0).011. Qt would in these two cases offer me the options (unless I'm missing something) the ability to display it as 110000.00000 or 1.100E+5 (or similar) and .01100 or 1.100E-2 (or similar.)

    Again, I get that it's underlying C++, but C++ doesn't have a default functionality and uses "setprecision(X)" (also not helpful.) I'm just double-checking that there's no *dynamic* significant digit feature (I.E. show only the relevant digits.)

    I will note that C++ defaults to this, but QStrings interpret the float directly. I.E. in C++ if you have x = 1.1 and y = 3.55 :
    cout << x << " " << y; will display
    1.1 3.55.

    I'm guessing thinking about it that Qt has some local setprecision method that's been set already. Hmm...

    EDIT: I bet I could just use floating point and chop off trailing '0's if there's a decimal point.


    EDIT: What I did:
    (this is called whenever something wants to update the display with a floating point rather than the usual input)

    Qt Code:
    1. void EnterYourSuperCoolQStringFunctionNameHere(QString input)
    2. {
    3. //remove trailing zeros or a trailing decimal if we have a decimal point
    4. while(input.contains('.')){
    5. //if it ends with a zero or decimal, remove it
    6. if(input.endsWith('0') || input.endsWith('.'))
    7. input.chop(1);
    8. else
    9. break;
    10. }
    11. //input is now acceptable.
    12. this->setText(input);
    13. }
    To copy to clipboard, switch view to plain text mode 

    Again, if this is repeated functionality it'd be good to know. Otherwise, w00t. Tested with scalars, appended input, etc.., it all works now.
    Last edited by tescrin; 12th July 2012 at 16:38.

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QStrings and Floats, Current Precision?

    QString::arg() has variants allowing you to specify the number of digits displayed. But it doesn't change the fact that 1.1 divided by E5 and then multiplied back by E5 might not give you 1.1 again. It might be 1.1 but it might be 1.100001 or something like that. You can't dynamically determine precision because the number is kept as binary and not decimal. Of course you can chop off zeroes but then you can get bad results. You have to employ rounding for that.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  6. #6
    Join Date
    Jun 2012
    Posts
    98
    Thanks
    11
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QStrings and Floats, Current Precision?

    This is less about getting exact numbers. This was a replication of something akin to a calculator. The display should only display what the user has entered or a reasonable approximation of it (i.e. if they multiply by 2*2, they don't need 4.00000)

    The problem with the Qt args is the same as me chopping off zeros if you want to be technical. Whenever you setprecision you're implicitly rounding. Just because QStrings will do this automatically does not afford you some kind of extra.. er... correctness. Further, setting the precision is not precise! Just because you default to pretending you multiplied by 1.000000 doesn't mean you did. If it were any sort of science class you'd be incorrect to assume such precision.

    That said, were it in a program for anything but displaying; I wouldn't be too worried about chopping trailing zeros (at least.. I don't think I would?) But for displaying all of the "user-entered significant digits" without displaying excess, as you'd expect from a calculator or something that functions like one, you are more worried about what's pleasing to the user.

    Further, the excess posses problems. Something that functions similar to a calculator appends digits when you press them. This means that if a user wants to press the button and there's a bunch of decimals it either:
    -appends to the end of these decimals meaning that the user must first clear the box and then enter their number(s)
    -appends it before the decimal, in which case it's unintuitive. After all, all calcs just append to the end!

    Hence my solution. It seems reasonable that default C++ functionality or that some removal-of-useless-digits function would exist in the QString, but oddly enough it does not. Given that the *default* in C++ is to just show what's actually there I wanted to ask if Qt would do the same.

    Surely the *default* C++ functionality isn't an unreasonable request.


    EDIT: That brings me to an odd idea: hooking up the output stream (the C++ cout variable) to a QLabel or QTextEdit to display what I want; just as an experiment.
    Last edited by tescrin; 12th July 2012 at 17:49.

  7. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QStrings and Floats, Current Precision?

    I don't see how Qt or C++ would have to guess what you as the user consider "useless". My point of view is that if you want a decimal calculator, you use decimal (aka fixed point) math.You can calculate everything using integers and keep the precision as a separate value and then just put the decimal point in the right place when showing the result.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  8. #8
    Join Date
    Jun 2012
    Posts
    98
    Thanks
    11
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QStrings and Floats, Current Precision?

    I think I can see what you're saying. I did something akin to that elsewhere in the program (or rather a program that uses this keypad dialog.) Still, how many calculators have you used that preserve the actual number of digits? IIRC even my TI-83+ and TI-92 may not have done that (it's hard to remember having not used them for a year or two.)

    But I think you still misunderstand. C++ *already* does that. Similar to what I said before if you do:
    Qt Code:
    1. float x=10.0000, y=3.0010;
    2. cout<<x*y;
    To copy to clipboard, switch view to plain text mode 

    the output will be 30.01, not 30.010 (or 30.0100), which true precision would say the result *is*. This is *default functionality* is what I'm saying; and I'm surprised that Qt went out of it's way to "improve" upon functionality without also allowing you to print it the way it would normally.

    What I'm calling "useless digits" are the same digits the default truncation C++ gets rid of, however accurate it would be in real world scientific application. Note also, that your calculator would be incorrect if given two values like the above (if I understand you correctly):

    Qt Code:
    1. float x=10, y=3.0010;
    2. cout<<x*y;
    To copy to clipboard, switch view to plain text mode 
    This would output under your code (assuming I understand you) 30.010 (or 30.0100), which is incorrect. We can only know that it is 30. Further more, if a user is using your calculator which value do they expect? They expect that you didn't get rid of their .01 for the sake of precision correctness. They'd expect it to be the "incorrect" or "unprecise" value because they're presumably either smart enough to truncate the amount they were not supposed to use, or don't care to.

    I argue that in *any* user realm, the user expects the calculator to give it all of it's information and they don't want several trailing zeros. Again, in acadamia or research you'd likely go figure out the precision yourself and rather have the calculator just calculate.


    Disclaimer: I hate to turn this into a topic about the philosophy of keypad precision :S. Technically my question is answered and a solution is posted.


    EDIT: It's worth noting that I understand C++ isn't technically truncating digits; that instead it's never saving them in the floating point format because there's no need to. It doesn't change my point at all.
    Last edited by tescrin; 12th July 2012 at 18:56.

  9. #9
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QStrings and Floats, Current Precision?

    Quote Originally Posted by tescrin View Post
    the output will be 30.01, not 30.010 (or 30.0100),
    Sure it will but not because of C++ but rather because the binary representation of all these is the same. Your computer simply doesn't differentiate between them. But if you write a decimal number that doesn't have a binary representation then you won't get what you entered but rather what the actual binary representation closest to what you entered is. That's how floating point works. The precision of the number is not determined by any calls to setprecision() (whatever that is) but by the value itself. Some values (like 0.1) do not have a binary representation. What cout does is (probably) that it rounds the binary value to a human-readable decimal representation. QTextStream does the same thing.

    Qt Code:
    1. #include <QtCore>
    2. #include <iostream>
    3.  
    4. int main() {
    5. QTextStream str(&s);
    6. str << 0.000001;
    7. qDebug() << s;
    8. std::cout << 0.000001 << std::endl;
    9. return 0;
    10. }
    To copy to clipboard, switch view to plain text mode 

    "1e-06"
    1e-06

    (both will show "0.01" for 0.01)


    This all doesn't change the fact that when using floating point, you're risking not showing the actual value that is used for calculation. I would never risk using such calculator for serious calculations, to be honest...
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  10. #10
    Join Date
    Jun 2012
    Posts
    98
    Thanks
    11
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QStrings and Floats, Current Precision?

    Ha! I didn't realize you meant to not use floating point at all. For sure.

    As it is, this is a simple keypad for user input (it doesn't even do calculations, sort of...) That said, yeah, I can agree with that. Binary representation has it's practical limits.

    EDIT: You've never used "setprecision()"? Its a standard C++ cout uh.. right-hand variable. I.E. setprecision(X) limits all cout functionality to read to X decimal places similar to QString::number(<NUM>,'f',X) regardless of the number.

    Also, you keep talking as if I didn't make it clear that I understand how floating point is represented. I even displayed so in an example (and mentioned why.) It's worth noting that Cout isn't really doing anything to the value other than allowing the floating point to be interpreted; just as you said there's no distinction for extra zeros. [You're setting floating point bits and then leaving the exponent. There's no real way to set extra zeros in binary without always setting all of them.]

    The main issue in this discussion has been that we're viewing the word "Precision" differently. I'm using as the Qt term (and apparently C++ term) meaning "number of decimal places to use" and you seem to be remarking on the actual precision of the value.
    Last edited by tescrin; 12th July 2012 at 20:21.

  11. #11
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QStrings and Floats, Current Precision?

    Quote Originally Posted by tescrin View Post
    As it is, this is a simple keypad for user input (it doesn't even do calculations, sort of...)
    Then why do you keep it as a numeric value instead of keeping it as text in the first place?

    EDIT: You've never used "setprecision()"? Its a standard C++ cout uh.. right-hand variable.
    Then it is std::ostream::setprecision() or something like that. And no, I have never used it, at least not that I remember using it. There is QTextStream::setRealNumberPrecision() if you want it.

    It's worth noting that Cout isn't really doing anything to the value other than allowing the floating point to be interpreted
    It is the one interpreting it so yeah... I'd say it does something to the value.

    just as you said there's no distinction for extra zeros.
    That's different. That's done by the compiler (or actually by the parser).

    [You're setting floating point bits and then leaving the exponent. There's no real way to set extra zeros in binary without always setting all of them.]
    To be honest there are no zeroes there at all. There are (usually) two binary values --- mantissa and exponent. And they are both of fixed width that can contain a lot of zeroes at the end.

    The main issue in this discussion has been that we're viewing the word "Precision" differently. I'm using as the Qt term (and apparently C++ term) meaning "number of decimal places to use" and you seem to be remarking on the actual precision of the value.
    No, we are interpreting this word the same way. I'm just saying you either have fixed precision or not. There is no "magically-determine-precision-for-me" precision. I'm sure there are lots and lots of decimal values that "cout" (meaning std::ostream) will show in a different way than what you input in your source code file (ignoring any trailing zeroes that do not change the actual value) or in some text field. The more fine grained values you use the higher probability of such behaviour. "cout" can guess that when you give it 0.100000001 then you probably mean 0.1 but at some point you might want to show 0.100000001 and it will instead display 0.1. It's all about heuristics and those are by definition not always correct.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. Replies: 4
    Last Post: 4th November 2014, 22:53
  2. Replies: 10
    Last Post: 9th February 2012, 05:31
  3. Replies: 2
    Last Post: 17th May 2011, 10:47
  4. QPainter::drawPixmap with floats ?
    By christophe.daudin in forum Qt Programming
    Replies: 8
    Last Post: 20th October 2009, 10:19
  5. Current Time with microsecond precision on windows
    By Dwarf007 in forum General Programming
    Replies: 16
    Last Post: 5th April 2006, 11:42

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.