Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>It appears there is no built-in string formatting trick which allows you to (1) print floats whose first significant digit appears after the 15th decimal place and (2) not in scientific notation. So that leaves manual string manipulation.</p> <p>Below I use the <code>decimal</code> module to extract the decimal digits from the float. The <code>float_to_decimal</code> function is used to convert the float to a <code>Decimal</code> object. The obvious way <code>decimal.Decimal(str(f))</code> is wrong because <code>str(f)</code> can lose significant digits.</p> <p><code>float_to_decimal</code> was lifted from the <a href="http://docs.python.org/library/decimal.html#decimal-faq" rel="nofollow noreferrer">decimal module's documentation</a>.</p> <p>Once the decimal digits are obtained as a tuple of ints, the code below does the obvious thing: chop off the desired number of sigificant digits, round up if necessary, join the digits together into a string, tack on a sign, place a decimal point and zeros to the left or right as appropriate. </p> <p>At the bottom you'll find a few cases I used to test the <code>f</code> function.</p> <pre><code>import decimal def float_to_decimal(f): # http://docs.python.org/library/decimal.html#decimal-faq "Convert a floating point number to a Decimal with no loss of information" n, d = f.as_integer_ratio() numerator, denominator = decimal.Decimal(n), decimal.Decimal(d) ctx = decimal.Context(prec=60) result = ctx.divide(numerator, denominator) while ctx.flags[decimal.Inexact]: ctx.flags[decimal.Inexact] = False ctx.prec *= 2 result = ctx.divide(numerator, denominator) return result def f(number, sigfig): # http://stackoverflow.com/questions/2663612/nicely-representing-a-floating-point-number-in-python/2663623#2663623 assert(sigfig&gt;0) try: d=decimal.Decimal(number) except TypeError: d=float_to_decimal(float(number)) sign,digits,exponent=d.as_tuple() if len(digits) &lt; sigfig: digits = list(digits) digits.extend([0] * (sigfig - len(digits))) shift=d.adjusted() result=int(''.join(map(str,digits[:sigfig]))) # Round the result if len(digits)&gt;sigfig and digits[sigfig]&gt;=5: result+=1 result=list(str(result)) # Rounding can change the length of result # If so, adjust shift shift+=len(result)-sigfig # reset len of result to sigfig result=result[:sigfig] if shift &gt;= sigfig-1: # Tack more zeros on the end result+=['0']*(shift-sigfig+1) elif 0&lt;=shift: # Place the decimal point in between digits result.insert(shift+1,'.') else: # Tack zeros on the front assert(shift&lt;0) result=['0.']+['0']*(-shift-1)+result if sign: result.insert(0,'-') return ''.join(result) if __name__=='__main__': tests=[ (0.1, 1, '0.1'), (0.0000000000368568, 2,'0.000000000037'), (0.00000000000000000000368568, 2,'0.0000000000000000000037'), (756867, 3, '757000'), (-756867, 3, '-757000'), (-756867, 1, '-800000'), (0.0999999999999,1,'0.1'), (0.00999999999999,1,'0.01'), (0.00999999999999,2,'0.010'), (0.0099,2,'0.0099'), (1.999999999999,1,'2'), (1.999999999999,2,'2.0'), (34500000000000000000000, 17, '34500000000000000000000'), ('34500000000000000000000', 17, '34500000000000000000000'), (756867, 7, '756867.0'), ] for number,sigfig,answer in tests: try: result=f(number,sigfig) assert(result==answer) print(result) except AssertionError: print('Error',number,sigfig,result,answer) </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload