On Wed, Apr 12, 2017 at 3:40 AM, boB Stepp <robertvst...@gmail.com> wrote: > > I have to say I am surprised by this as well as the OP. I knew that > str() in general makes a nice printable representation
The single-argument str() constructor calls the object's __str__ method (or __repr__ if __str__ isn't defined). In Python 3, float.__str__ and float.__repr__ behave the same. They use as many digits as is required to round trip back to the float value exactly. That's up to 17 digits. >>> str(1.2345678901234567) '1.2345678901234567' >>> str(1.) '1.0' In Python 2, float.__str__ uses up to 12 digits: >>> str(1.2345678901234567) '1.23456789012' > realize that using str() on an arbitrarily typed in "float-like" value > would convert the typed in value to a normal float's max precision. For a literal floating-point value in source code, the compiler (component of the interpreter) first parses a NUMBER node: >>> e = parser.expr('3.14159265358979323846264338327950288419716939') >>> p = parser.st2list(e) >>> while p[0] != token.NUMBER: ... p = p[1] ... >>> p [2, '3.14159265358979323846264338327950288419716939'] Next it transforms this concrete syntax tree into a abstract syntax tree: >>> a = ast.parse('3.14159265358979323846264338327950288419716939', ... mode='eval') >>> ast.dump(a) 'Expression(body=Num(n=3.141592653589793))' >>> a.body.n 3.141592653589793 >>> type(a.body.n) <class 'float'> You see above that the AST transforms the NUMBER node into a Num node that references a float object. The value of the float is the closest possible approximation of the source code literal as a double-precision binary float. If the compiler instead used Decimal objects, then it could retain all of the literal's precision. Double-precision binary floats are fast and efficient by virtue of hardware support, but that's not a compelling reason in Python. Maybe some future version of Python will switch to using Decimals for floating-point literals. The final step is to compile this AST into bytecode and create a code object. The float value is referenced in the code object's co_consts attribute: >>> c = compile(a, '', 'eval') >>> c.co_consts (3.141592653589793,) The code in this case is simple; just load and return the constant value: >>> dis.dis(c) 1 0 LOAD_CONST 0 (3.141592653589793) 3 RETURN_VALUE >>> eval(c) 3.141592653589793 _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor