[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

On 27 February 2014 15:42, Mark H. Harris <harrismh777 at gmail.com> wrote: > On Thursday, February 27, 2014 8:42:55 AM UTC-6, Oscar Benjamin wrote: > >> >> Some points: > > Thanks so much... you have clarified some things I was struggling with... > >> 1) Why have you committed the code as a .tar.gz file? > > um, to save space... well, I know its tiny, but its just a habit I have... 5kb instead of 25kb... It made it awkward for me to see the code you were referring to. In a separate thread you asked about how to share code samples. These days it's common practice to host code somewhere it can be viewed from a browser. This means that I can do things like link to a line in Chris' code: https://github.com/Rosuav/ExceptExpr/blob/master/examples.py#L169 There are many other reasons (as mentioned by Chris) why committing a binary archive instead of just the plain old files is a generally bad idea with standard version control systems. A relevant one is that every change you make to your code, even if you only change 2 lines will require an additional 5kb of space to store the new .tar.gz file alongside the old rather than 200 bytes or whatever it is to store the diff of the code files. >> 2) This function is not such a good idea: >> >> def D(numform): >> return Decimal(str(numform)) > > The reason for this is not for strings, but for float literals. All of my functions may take a float literal and things still work, because the D(float) function converts the float literal to a string, which is then passed to the Decimal constructor. so... this works sqrt(0.1) or, sqrt(2.01) Without the D() function float literals may not be passed to the Decimal because it really cannot handle them... 0.1 and others cause it a fit... is there another way to do what I'm looking for here..? I think you're misunderstanding what's going on: >>> from decimal import Decimal as D >>> D(0.1) Decimal('0.1000000000000000055511151231257827021181583404541015625') There is no binary floating point value that is exactly equal to the mathematical number 0.1. So when you write 0.1 in Python the number is rounded to the nearest binary floating point number. When you create a Decimal from a float it will create a Decimal with the *exact* same value that the float had. That's exactly what you're seeing above. When you print a float normally it pretends to have the value 0.1 but that's really a lie: >>> 0.1 # There is no float with the true value 0.1!!!!! 0.1 >>> 0.1 == D('0.1') False When you convert a float to a string it does not show the exact value of the float but rather a rounded, shortened decimal form. By converting float->str->Decimal you are introducing unnecessary rounding. The Decimal constructor deliberately never rounds its inputs and every float can be represented as a Decimal with a finite number of digits. So Decimal(float) is exact but your D function is not. It is precisely the fact that binary floating point cannot represent seemingly simple non-integer decimal numbers like 0.1 that leads to the creation of the decimal module. But why would anyone pass a float into one of your dmath functions since they're surely much slower than the math module? The main reason that I can imagine is that they would like a really accurate result in which case rounding all floats on input is unacceptable. > This has confused me, because when I look into the module help text I don't see roun() all I see is > __round__(...) how do I know when the round() method exists vs. __round__(...) ?? The round builtin function calls __round__ on any object. Dunder methods are not supposed to be called directly. Oscar

- Prev by Date:
**Tuples and immutability** - Next by Date:
**Tuples and immutability** - Previous by thread:
**extend methods of decimal module** - Next by thread:
**extend methods of decimal module** - Index(es):