Path: csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail From: eryk sun Newsgroups: comp.lang.python Subject: Re: Float Date: Sat, 30 Jul 2016 18:19:19 +0000 Lines: 64 Message-ID: References: <579b67b0$0$1614$c3e8da3$5496439d@news.astraweb.com> <367666cb-224f-4b16-88bb-cd1ada13a13b@googlegroups.com> <579c82a6$0$1619$c3e8da3$5496439d@news.astraweb.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 X-Trace: news.uni-berlin.de ZuxnlyT6/GlxqP7XWF5VgQx0MFLDSl5DssvHa1KkuxVA== Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.001 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'cpython': 0.05; 'float': 0.05; '754': 0.09; 'debugger': 0.09; 'decodes': 0.09; "object's": 0.09; 'underlying': 0.09; 'unsigned': 0.09; '1))': 0.16; '2016': 0.16; '3.0)': 0.16; 'attaching': 0.16; 'digits.': 0.16; 'exponent': 0.16; 'hexadecimal': 0.16; 'int64': 0.16; 'received:io': 0.16; 'received:psf.io': 0.16; 'route,': 0.16; 'uint64_t': 0.16; 'uniquely': 0.16; 'wrote:': 0.16; 'integer': 0.18; 'pointer': 0.18; '>>>': 0.20; 'windows': 0.20; 'implicit': 0.22; 'struct': 0.22; 'bit': 0.23; "python's": 0.23; 'represents': 0.23; 'sat,': 0.23; 'import': 0.24; 'header:In-Reply-To:1': 0.24; 'linux': 0.26; 'supported': 0.27; 'message-id:@mail.gmail.com': 0.27; '(such': 0.27; '3.0': 0.27; 'values': 0.28; 'decimal': 0.29; 'url:wikipedia': 0.29; 'url:wiki': 0.30; 'waste': 0.30; 'platforms.': 0.33; "skip:' 20": 0.34; 'received:google.com': 0.35; 'follows:': 0.35; 'skip:* 20': 0.35; 'url:org': 0.36; 'to:addr:python-list': 0.36; 'pm,': 0.36; 'subject:: ': 0.37; 'method': 0.37; 'format': 0.39; 'url:en': 0.39; 'rather': 0.39; 'to:addr:python.org': 0.40; 'field': 0.60; 'confirm': 0.62; '30,': 0.63; 'more': 0.63; 'you.': 0.64; 'jul': 0.72; 'article': 0.77; 'casting': 0.84; 'dennis': 0.91 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to; bh=kO8/gZ/J+ydUmLgjGmfJaXRZ3Y7ZpfjImjagr+4gWgQ=; b=YKtxImGWIPegRIo6oc+GKetfYlx2OZZyJ+3YfD8UUOy01qHPPD+bW48W9bpca/EBeb DxSraYV/RkCzeMajlxvsaQGJWxr0OKvddqWjAYcnBmb2qonKIeRKt93F+aYoad639jh+ J5jFC88+DWgr66r84IXJt72KrA3WRLijHrM2Oc+UjZcYlY5npqDLMu2xluh2tJyKCzDA U64DVgJrDnb61qaPii8R6Gg8xSqU+9Qv+l085DbJmCD6KNjM8/EeJB/hAJn1/yJuKc5x T+5oPGT++MQy4KFNRvnh3Dt42d5CrDxPJwO2UDm+L1uIha6Fk/6BJxSqJXOrEYCWhjsG W5Lg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to; bh=kO8/gZ/J+ydUmLgjGmfJaXRZ3Y7ZpfjImjagr+4gWgQ=; b=XJbwNa89lhyquJ1PwiuiM9CnPqtgHOmvx0pTE4DLDNMz+zPrk7dEXlX7f+NA1Etz0U EfeFyL+9NMhu1p3f7GnZYilBWDfqpWYAyWw3bcl5En+H3AbRu5Na0CRsoyuCrtGeNfyW b0EfwbcLP95PfJ9BczWjazvOiNxQi1X4Qy9LLXUB6iBL9iwCQsWUHucPixFa6QgpxztJ 8wZHWN8pX+gZC6mbAzdpnBlIAm1+ZgsHPQgtATVBS2rLVuBAdvpAHXyzzjkpAAbFPFNa eYTYmvWXz0zi68XyvjaoyJCsEg1IYwD16ZapBGU4tQl8Rav5Z9Kgr8KOlO3LXQwz0Xjv M7cA== X-Gm-Message-State: AEkoouuOoop36yktwzbvx5V+SbNi+0bFm5I5Kxr1Wn8A7/36uSHZRwGHFCgCL89vExqCrOQFNBQ/FtO6UqX7Eg== X-Received: by 10.36.90.79 with SMTP id v76mr48232778ita.16.1469902798813; Sat, 30 Jul 2016 11:19:58 -0700 (PDT) In-Reply-To: X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Mailman-Original-Message-ID: X-Mailman-Original-References: <579b67b0$0$1614$c3e8da3$5496439d@news.astraweb.com> <367666cb-224f-4b16-88bb-cd1ada13a13b@googlegroups.com> <579c82a6$0$1619$c3e8da3$5496439d@news.astraweb.com> Xref: csiph.com comp.lang.python:112097 On Sat, Jul 30, 2016 at 4:03 PM, Dennis Lee Bieber wrote: > And in a rather convoluted route, one can get to the underlying > representation... > >>>> import struct >>>> f = struct.pack(">f", 3.0) >>>> i = struct.pack(">i", 3) >>>> fi = struct.unpack(">i", f) >>>> ii = struct.unpack(">i", i) #really a waste of time >>>> "0x%8.8X 0x%8.8X" % (fi[0], ii[0]) > '0x40400000 0x00000003' A CPython float is a C double-precision float ('d'), which is an IEEE 754 binary64 on all of CPython's supported platforms. This format has a precision of 15 decimal digits (rounded down from 15.95). Uniquely representing a C double requires 17 decimal digits. See the following Wikipedia article for more information: https://en.wikipedia.org/wiki/Double-precision_floating-point_format The underlying representation of 3.0 is as follows: >>> n = 3.0 >>> hex(struct.unpack('Q', struct.pack('d', n))[0]) '0x4008000000000000' You can confirm this by attaching a native debugger (such as gdb on Linux or cdb on Windows) and pointer casting the float object's ob_fval field as a uint64_t integer: Linux (python3-dbg): >>> id(n) 140737353618480 (gdb) p/x *(uint64_t *)&((PyFloatObject *)140737353618480)->ob_fval $1 = 0x4008000000000000 Windows (python_d.exe): >>> id(n) 2398135104848 0:000> ?? *(ULONG64 *)&((PyFloatObject *)2398135104848)->ob_fval unsigned int64 0x40080000`00000000 We can break this down as follows: sign = 0x400 >> 11 = 0 exponent = (0x400 & (1 << 11 - 1)) - 1023 = 1 significand = 1 + 0x8000000000000 / 2 ** 52 = 1.5 n = (-1) ** sign * significand * 2 ** exponent = 3.0 Python's float type has a hex() method that represents the value in hexadecimal as follows: >>> n.hex() '0x1.8000000000000p+1' This format shows the implicit integer bit of the normalized significand and decodes the sign and exponent values for you.