On Apr 14, 2013, at 6:30 PM, Algis Kabaila <[email protected]> wrote:
> Just to add a little fuel to this fire: > > First, by hand try to convert the "exact" 0.1 then 0.01 decimal to their > binary equivalent. Send to this list the binary value. Is it exact? > > Second, who would care about 1 cent in $10 000 ? people who are stealing money :) Its been some years, but taking the roundings has actually been done. It has always amused me when people insist on using float for "dollars" rather than tracking cents exactly. > > Al. > > On Sunday 14 April 2013 16:04:15 Tim Doty wrote: > > On Apr 14, 2013, at 3:35 PM, Zak <[email protected]> wrote: > > > My original email was correct, let me provide proof and explain > > > further. > > > > > > Let me address a few specific points: > > > > > > Tim Doty wrote: > > > > For the PySide what is really happening is not a rounding > > > > error/precision as suggested, but printing an integer with floating > > > > point notation. When the floating point is converted to an integer > > > > it is rounded. To satisfy yourself that this is in fact happening > > > > change the number to be printed (e.g., 9999999.5 vs 9999999.4). > > > > > > This is incorrect, what is happening is a rounding error. The number > > > is being rounded to fit in a 32 bit piece of memory. The > > > counter-example above is misleading because it uses bad values. Try > > > the values 1.4 and 1.6 instead. These values are used in the attached > > > Python script. > > As I said, I don't know the PySide internals. I referred to the > > published documentation which implies that floats are being coerced > > into integers due to lack of a float overload. Apparently the docs are > > wrong… go figure. > > > > Interestingly, if you drop the millions (e.g., 999999.62) you can see > > the rounding in action. I'm not going to dredge through a wall of text > > looking for a point in the preceding post, but -- as it so happens -- > > the example I give above outputs correctly making it seem as if there > > is inconsistent precision. But it is an accident. 999999.65 also prints > > as 999999.62 while 999999.66 prints as 999999.69 > > > > So it is just an artifact of 32-bit precision float representations. > > Now, why it is being constrained to a 32-bit float on a 64-bit > > architecture is a different conversation and, while I recognize there > > would be disagreement, I call that a bug on its face and the fact that > > the sibling implementation uses 64-bit precision underscores the point. > > > > Tim Doty > > > > > The number is not at any point represented as an integer (data > > > structure), it is always a floating point. Even if the number's value > > > is a whole number, it is represented as a floating point. For > > > instance, Python interprets '1.0' as a floating point literal. A > > > mathematician would say 1.0 is an integer, but computer science uses > > > different terminology. In computer science, in the language Python, > > > '1' is an integer and '1.0' is a floating point, and they are equal > > > in numerical value. They are represented differently in memory.> > > > Alexey Vihorev wrote: > > > > Two considerations: > > > > 1. No rounding should take place in this case - the decimal > > > > precision of the input and output is exactly the same. > > > > 2. In PyQt it *does* work correctly, so fundamental lows of computer > > > > science are certainly not the reason. > > > > > > In response to 1: That is just your opinion. You do not want rounding > > > to take place. The designers of Python and Qt had a different > > > opinion. To make things faster, they decided to round numbers so that > > > they can fit in either 32 or 64 bits of memory. If you want to use > > > larger chunks of memory and keep higher precision, then you should > > > use the Python standard library 'decimal', as I said before. Using > > > decimal.Decimal objects, you can set the precision yourself. Because > > > you are not using this library, Python, PySide, and PyQt are making a > > > decision about how to round the number. PySide chose 32 bits, PyQt > > > chose 64 bits. The Python language itself chose 64 bits, so PySide > > > and PyQt cannot possibly choose higher precision, the extra bits have > > > already been thrown away. > > > > > > In response to 2: You are using incorrect logic. As you can see from > > > my example, PyQt also suffers rounding errors, they just occur around > > > 15 to 17 digits. You didn't use that many digits so you didn't see > > > the rounding error. > > > > > > Zak Fallows > > > > > > # File: num_print.py > > > > > > from PyQt4.QtCore import QLocale as PyQtLocale > > > from PySide.QtCore import QLocale as PySideLocale > > > > > > def pb(num): > > > """pb stands for Print Both""" > > > > > > print "Original: " + num > > > flt = eval(num) > > > print " PyQt: ", > > > print PyQtLocale().toString(flt, 'f', 6) > > > print " PySide: ", > > > print PySideLocale().toString(flt, 'f', 6) > > > print '' > > > > > > test_list = [ > > > > > > '1.4', > > > '1.6', > > > '1000.4', > > > '1000.6', > > > '10**6 + .4', > > > '10**6 + .6', > > > '10**7 + .4', > > > '10**7 + .6', > > > '10**8 + .4', > > > '10**8 + .6', > > > '10**9 + .4', > > > '10**9 + .6', > > > '10**14 + .4', > > > '10**14 + .6', > > > '10**15 + .4', > > > '10**15 + .6', > > > '10**16 + .4', > > > '10**16 + .6', > > > '10**17 + .4', > > > '10**17 + .6', > > > > > > ] > > > > > > for num in test_list: > > > pb(num) > > > > > > """ > > > > > > #======================== How to Check Version Numbers > > > ========================#> > > > PyQt: > > > PyQt4.QtCore.PYQT_VERSION_STR > > > > > > PySide: > > > PySide.__version__ > > > > > > #=============================== Sample Output > > > ================================# > > > > > > Here is some sample output from running the program: > > > > > > #---------------------------------- Mac OS X > > > ----------------------------------# > > > > > > Mac OS X 10.8.3 > > > Python 2.7.3, 64-bit, from Python.org > > > PySide 1.1.1, 64-bit > > > PyQt 4.9.4, 64-bit > > > > > > >>> import num_print > > > > > > Original: 1.4 > > > > > > PyQt: 1.400000 > > > PySide: 1.400000 > > > > > > Original: 1.6 > > > > > > PyQt: 1.600000 > > > PySide: 1.600000 > > > > > > Original: 1000.4 > > > > > > PyQt: 1,000.400000 > > > PySide: 1,000.400024 > > > > > > Original: 1000.6 > > > > > > PyQt: 1,000.600000 > > > PySide: 1,000.599976 > > > > > > Original: 10**6 + .4 > > > > > > PyQt: 1,000,000.400000 > > > PySide: 1,000,000.375000 > > > > > > Original: 10**6 + .6 > > > > > > PyQt: 1,000,000.600000 > > > PySide: 1,000,000.625000 > > > > > > Original: 10**7 + .4 > > > > > > PyQt: 10,000,000.400000 > > > PySide: 10,000,000.000000 > > > > > > Original: 10**7 + .6 > > > > > > PyQt: 10,000,000.600000 > > > PySide: 10,000,001.000000 > > > > > > Original: 10**8 + .4 > > > > > > PyQt: 100,000,000.400000 > > > PySide: 100,000,000.000000 > > > > > > Original: 10**8 + .6 > > > > > > PyQt: 100,000,000.600000 > > > PySide: 100,000,000.000000 > > > > > > Original: 10**9 + .4 > > > > > > PyQt: 1,000,000,000.400000 > > > PySide: 1,000,000,000.000000 > > > > > > Original: 10**9 + .6 > > > > > > PyQt: 1,000,000,000.600000 > > > PySide: 1,000,000,000.000000 > > > > > > Original: 10**14 + .4 > > > > > > PyQt: 100,000,000,000,000.406250 > > > PySide: 100,000,000,376,832.000000 > > > > > > Original: 10**14 + .6 > > > > > > PyQt: 100,000,000,000,000.593750 > > > PySide: 100,000,000,376,832.000000 > > > > > > Original: 10**15 + .4 > > > > > > PyQt: 1,000,000,000,000,000.375000 > > > PySide: 999,999,986,991,104.000000 > > > > > > Original: 10**15 + .6 > > > > > > PyQt: 1,000,000,000,000,000.625000 > > > PySide: 999,999,986,991,104.000000 > > > > > > Original: 10**16 + .4 > > > > > > PyQt: 10,000,000,000,000,000.000000 > > > PySide: 10,000,000,272,564,224.000000 > > > > > > Original: 10**16 + .6 > > > > > > PyQt: 10,000,000,000,000,000.000000 > > > PySide: 10,000,000,272,564,224.000000 > > > > > > Original: 10**17 + .4 > > > > > > PyQt: 100,000,000,000,000,000.000000 > > > PySide: 99,999,998,430,674,944.000000 > > > > > > Original: 10**17 + .6 > > > > > > PyQt: 100,000,000,000,000,000.000000 > > > PySide: 99,999,998,430,674,944.000000 > > > > > > #--------------------------------- Windows 7 > > > ----------------------------------# > > > > > > Windows 7, 64-bit > > > Python 2.7.3, 32-bit, from Python.org > > > PySide 1.1.1, 32-bit > > > PyQt 4.10, 32-bit > > > > > > >>> import num_print > > > > > > Original: 1.4 > > > > > > PyQt: 1.400000 > > > PySide: 1.400000 > > > > > > Original: 1.6 > > > > > > PyQt: 1.600000 > > > PySide: 1.600000 > > > > > > Original: 1000.4 > > > > > > PyQt: 1,000.400000 > > > PySide: 1,000.400024 > > > > > > Original: 1000.6 > > > > > > PyQt: 1,000.600000 > > > PySide: 1,000.599976 > > > > > > Original: 10**6 + .4 > > > > > > PyQt: 1,000,000.400000 > > > PySide: 1,000,000.375000 > > > > > > Original: 10**6 + .6 > > > > > > PyQt: 1,000,000.600000 > > > PySide: 1,000,000.625000 > > > > > > Original: 10**7 + .4 > > > > > > PyQt: 10,000,000.400000 > > > PySide: 10,000,000.000000 > > > > > > Original: 10**7 + .6 > > > > > > PyQt: 10,000,000.600000 > > > PySide: 10,000,001.000000 > > > > > > Original: 10**8 + .4 > > > > > > PyQt: 100,000,000.400000 > > > PySide: 100,000,000.000000 > > > > > > Original: 10**8 + .6 > > > > > > PyQt: 100,000,000.600000 > > > PySide: 100,000,000.000000 > > > > > > Original: 10**9 + .4 > > > > > > PyQt: 1,000,000,000.400000 > > > PySide: 1,000,000,000.000000 > > > > > > Original: 10**9 + .6 > > > > > > PyQt: 1,000,000,000.600000 > > > PySide: 1,000,000,000.000000 > > > > > > Original: 10**14 + .4 > > > > > > PyQt: 100,000,000,000,000.406250 > > > PySide: 100,000,000,376,832.000000 > > > > > > Original: 10**14 + .6 > > > > > > PyQt: 100,000,000,000,000.593750 > > > PySide: 100,000,000,376,832.000000 > > > > > > Original: 10**15 + .4 > > > > > > PyQt: 1,000,000,000,000,000.375000 > > > PySide: 999,999,986,991,104.000000 > > > > > > Original: 10**15 + .6 > > > > > > PyQt: 1,000,000,000,000,000.625000 > > > PySide: 999,999,986,991,104.000000 > > > > > > Original: 10**16 + .4 > > > > > > PyQt: 10,000,000,000,000,000.000000 > > > PySide: 10,000,000,272,564,224.000000 > > > > > > Original: 10**16 + .6 > > > > > > PyQt: 10,000,000,000,000,000.000000 > > > PySide: 10,000,000,272,564,224.000000 > > > > > > Original: 10**17 + .4 > > > > > > PyQt: 100,000,000,000,000,000.000000 > > > PySide: 99,999,998,430,674,944.000000 > > > > > > Original: 10**17 + .6 > > > > > > PyQt: 100,000,000,000,000,000.000000 > > > PySide: 99,999,998,430,674,944.000000 > > > > > > """ > > > > > > <num_print.py> > > > > _______________________________________________ > > PySide mailing list > > [email protected] > > http://lists.qt-project.org/mailman/listinfo/pysidea _______________________________________________ PySide mailing list [email protected] http://lists.qt-project.org/mailman/listinfo/pyside
